tools-deps

imre 2026-05-20T10:41:22.451599Z

Why is :override-deps restricted to only work inside an alias? We had an idea to use it for CVE fixes, and to resolve clashes described in https://clojure.atlassian.net/browse/TDEPS-132, but for those we'd need it at the top level because we want those overrides to apply to the normal dependencies of the project

imre 2026-05-21T13:58:44.843589Z

Here is one more case where a global override might come in useful:

{A {:version 1}
 B {:version 2}}

imre 2026-05-21T14:00:24.340239Z

Both A and B depend on C, which we don't care about, however, A needs version 3 of C specifically, while B uses version 4 of same, but works with version 3.

imre 2026-05-21T14:01:45.342559Z

I want to fix {C {:version 3}} - if I can do it in an overrides section, that communicates better that it's only there to override something

imre 2026-05-21T14:01:57.163229Z

I guess TDEPS-282 could work here too

imre 2026-05-21T14:02:13.600719Z

might need to repeat it a few times though if there are more deps like B

imre 2026-05-21T14:03:15.076919Z

Apologies for the lots of text, I'm just coming across these cases due to the nature of work I'm doing now 😅

seancorfield 2026-05-20T12:25:56.034389Z

Because top-level deps take precedence already?

Alex Miller (Clojure team) 2026-05-20T12:28:58.523359Z

I don't understand what you're suggesting

imre 2026-05-20T13:58:26.231999Z

Here is an example for the CVE case:

{:deps
 {info.sunng/ring-jetty9-adapter {; has CVEs in transitive deps for example in org.eclipse.jetty.http2/http2-server
                                  :mvn/version "0.14.3"}}

 :override-deps
 {; it would be nice to be able to fix the CVE above like this
  ; we don't have a direct need for the below, we just saw that it comes in
  ; transitively and we want to make sure that the version used is the safe one,
  ; so it feels a bit off to add an exclusion and a direct dependency in :deps
  org.eclipse.jetty.http2/http2-server {:mvn/version "9.4.58.v20250814"}}}

Alex Miller (Clojure team) 2026-05-20T14:03:53.690159Z

right now, your best practice here is to use :exclusions and add the dep after

{:deps
 {info.sunng/ring-jetty9-adapter {; has CVEs in transitive deps for example in org.eclipse.jetty.http2/http2-server
                                  :mvn/version "0.14.3" :exclusions [org.eclipse.jetty.http2/http2-server]}


  ; it would be nice to be able to fix the CVE above like this
  ; we don't have a direct need for the below, we just saw that it comes in
  ; transitively and we want to make sure that the version used is the safe one,
  ; so it feels a bit off to add an exclusion and a direct dependency in :deps
  org.eclipse.jetty.http2/http2-server {:mvn/version "9.4.58.v20250814"}}}

Alex Miller (Clojure team) 2026-05-20T14:04:33.835719Z

but I understand the request now

Alex Miller (Clojure team) 2026-05-20T14:05:44.425809Z

or maybe you only need the exclusions if you're not using that transitive dep at all

imre 2026-05-20T14:08:20.941329Z

This is the method we currently use. I might not use that transitive dep but my direct dep might need it, I prefer not having to worry about that. Also, some other direct dependency might also bring it in, if not today, maybe the next time I bump its version, so a blanket override-deps might help there.

imre 2026-05-20T14:14:25.576929Z

These exclusions/pinnings will have to be revised from time to time anyway, but being able to use a top-level override-deps would let you not have to worry about where something comes from and also communicating "I don't really need this dep, it's just here to make sure it's this version, if it is pulled in anyway"

imre 2026-05-20T14:15:48.932259Z

And here is an example for the TDEPS-132 case:

{:deps
 {; these 2 come from a monorepo and both have a local/root
  ; dependency on juxt.edge/edge.system so without an exclusion
  ; or direct dependency on juxt.edge/edge.system,
  ; clojure -Spath will fail
  ; Error building classpath. No known ancestor relationship between local versions for juxt.edge/edge.system

  juxt.edge/lib.app
  {:deps/root "lib/edge.app"
   :git/url   ""
   :sha       "bd3ea7e774920bf544e45040da6d17f5993387a3"}

  juxt.edge/lib.app.dev
  {:deps/root "lib/edge.app.dev"
   :git/url   ""
   :sha       "bd3ea7e774920bf544e45040da6d17f5993387a3"}}

 ; it would be nice to resolve the above clash using the below, since
 ; we don't directly need the dependency below, just helping tools.deps resolve a clash
 :override-deps
 {juxt.edge/edge.system
  {:deps/root "lib/edge.system"
   :git/url   ""
   :sha       "bd3ea7e774920bf544e45040da6d17f5993387a3"}}

 ; it can also be fixed by going
 ; clojure -A:fix -Spath, but that requires an alias
 :aliases
 {:fix
  {:override-deps
   {juxt.edge/edge.system
    {:deps/root "lib/edge.system"
     :git/url   ""
     :sha       "bd3ea7e774920bf544e45040da6d17f5993387a3"}}}}}

imre 2026-05-20T14:19:05.943379Z

Do you think this is worth an ask.clojure? Or is top-level override-deps completely off the table?

seancorfield 2026-05-20T14:20:49.026629Z

So the only benefit of :override-deps at the top-level would be that it doesn't pull the dep in -- unless some transient dep needs it?

imre 2026-05-20T14:21:35.878899Z

and that you don't have to muck around with exclusions if your goal isn't specifically to exclude something

imre 2026-05-20T14:21:58.351009Z

both of these cases are currently solveable using direct :deps and/or :exclusions

imre 2026-05-20T14:22:45.317899Z

or aliased override-deps, but those don't carry over to projects depending on the project where you set these up, and in my case I'd need that for this to be really useful

Alex Miller (Clojure team) 2026-05-20T14:57:28.818129Z

I think the important thing is to stick to the use case and not to these particular solution ideas (which are probably not where it would end up). One use case that I've seen before (and I think is in the issue tracker somewhere) is to always exclude a particular library, a "global exclusion"

Alex Miller (Clojure team) 2026-05-20T14:58:49.091409Z

the other use case here (which I have certainly experienced myself re CVEs) is a scoped override - in the context of this dependency subtree, provide an override

Alex Miller (Clojure team) 2026-05-20T14:59:27.205009Z

global override already exists - you just specify the library at the top level

imre 2026-05-20T15:01:59.308599Z

what doesn't exist though is the ability to globally override but only if it's in the dep tree (don't add, but if something else pulls it in, override)

👍 1
Alex Miller (Clojure team) 2026-05-20T15:10:01.954939Z

why would you be specifying it at all if nothing bring it in?

Alex Miller (Clojure team) 2026-05-20T15:10:21.599649Z

I logged https://clojure.atlassian.net/browse/TDEPS-281 (global exclusions) and https://clojure.atlassian.net/browse/TDEPS-282 (scoped overrides)

Alex Miller (Clojure team) 2026-05-20T15:11:33.418319Z

but this is basically global defaults (which is the same space as dependency management in lein/ maven)

imre 2026-05-20T21:09:43.746989Z

> why would you be specifying it at all if nothing bring it in? Not a bad question. I'm thinking of a case where an override gets added, is then kind of forgotten about, and stays in, despite changes in the "business" deps of the system meaning it wouldn't otherwise be part of the dep tree anymore. Using your example from TDEPS-282, say, today we have

{A {:version 1 :excludes [B]}
 B {:version 2}}
then maybe in 2028 A gets replaced with C:
{C {:version 1}
 B {:version 2}}
but B is no longer a transitive dep of C, but B is still part of the dep tree because the direct dependency. TDEPS-282 does suggest a much nicer way of dealing with this, thank you for adding those tickets! TDEPS-281 would finally provide a way to globally ignore stuff like clojurescript (which some libs tend to pull in staticly) in pure clojure projects

imre 2026-05-20T21:13:17.554419Z

What do you think about the case I brought for TDEPS-132, when multiple direct deps pull in versions of the same transitive dep that tdeps cannot decide between? This could again be handled using exclusion/adding a direct dep/TDEPS-282 scoped override, but they all feel a bit clunky.

Alex Miller (Clojure team) 2026-05-20T22:08:00.126479Z

TDEPS-281 - I added that to the jira, it's a good example

Alex Miller (Clojure team) 2026-05-20T22:11:28.068009Z

TDEPS-132 - I don't have time to re-gain the context on this, so not sure but I think the first suggestion in that ticket is a non-starter, the second is I think generally the right direction to have "local" deps that still retain the context of being in a git repo that gives you version comparison capability

imre 2026-05-20T22:32:01.346709Z

thank you for these Alex

Alex Miller (Clojure team) 2026-05-20T22:33:00.878139Z

I don't know if that's a "new" dep type - it's kind of a hybrid of local and git

Alex Miller (Clojure team) 2026-05-20T22:33:33.021049Z

I think there's at least one other ticket related to this, or maybe I'm thinking of this one