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
Here is one more case where a global override might come in useful:
{A {:version 1}
B {:version 2}}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.
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
I guess TDEPS-282 could work here too
might need to repeat it a few times though if there are more deps like B
Apologies for the lots of text, I'm just coming across these cases due to the nature of work I'm doing now 😅
Because top-level deps take precedence already?
I don't understand what you're suggesting
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"}}}
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"}}}but I understand the request now
or maybe you only need the exclusions if you're not using that transitive dep at all
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.
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"
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"}}}}} Do you think this is worth an ask.clojure? Or is top-level override-deps completely off the table?
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?
and that you don't have to muck around with exclusions if your goal isn't specifically to exclude something
both of these cases are currently solveable using direct :deps and/or :exclusions
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
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"
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
global override already exists - you just specify the library at the top level
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)
why would you be specifying it at all if nothing bring it in?
I logged https://clojure.atlassian.net/browse/TDEPS-281 (global exclusions) and https://clojure.atlassian.net/browse/TDEPS-282 (scoped overrides)
but this is basically global defaults (which is the same space as dependency management in lein/ maven)
> 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 projectsWhat 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.
TDEPS-281 - I added that to the jira, it's a good example
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
thank you for these Alex
I don't know if that's a "new" dep type - it's kind of a hybrid of local and git
I think there's at least one other ticket related to this, or maybe I'm thinking of this one