Fork me on GitHub

hi all is there a way to ask tools-deps to download all deps but ignore any main options (basically I want just to cached deps)

- clojure -Sdeps '{:mvn/local-repo ".m2"}' -A:test:prod:frontend -P
doesnt work


That's the thing with main opts, I think the clojure CLI should now ignore them with -A but because of historical behavior, it doesn't yet.


as a workaround i can create empty alias w/o any -m and put it last thing


Perhaps -P could be made to accept aliases as well


this worked for me

clojure -Sdeps '{:mvn/local-repo ".m2"}' -A:test:prod:frontend -Spath > /dev/null


note that -Spath (clj-opt) needs to go before -Aaliases


although this works, it's not guaranteed to work, since the docs recommend otherwise


why does

clojure -Sdeps '{:mvn/local-repo ".m2"}' -M:dev:test
download deps every run?


Error building classpath. Could not transfer artifact org.glassfish.jaxb:txw2:jar: from/to central (): status code: 416, reason phrase: Range Not Satisfiable (416)
maven misbehaving?


seems working on CI with older verion of tools-deps seems like a bug?


:version ""


found the solution


just deleteing m2

Joshua Suskalo17:09:00

Is there any way to run a tool installed with the -Ttools tool but with the current classpath available? Like if I have a tool installed, can I run it with -X even if it isn't in the current project?

Alex Miller (Clojure team)17:09:45

no, tools definitionally don't run with the project classpath

Alex Miller (Clojure team)17:09:55

you can install that dep as an alias and use -X with it though

Alex Miller (Clojure team)17:09:16

if you want to see the lib/coord for an installed tool, you can do that with:

clj -Ttools show :tool tools

Alex Miller (Clojure team)17:09:30

(replace the last tools with whatever)

Joshua Suskalo17:09:49

Alright. What I'm thinking about doing (haven't committed to it yet, still exploring how complex an undertaking it will be) is making a tool which can format code in the same way that cider does, but without needing to connect a repl to your entire project. This is fine to not have the classpath loaded for your project, but an extension that I want for it is to be able to run it inside the classpath for a different operation that instead of formatting the code, it will load the namespaces from your project, explore all the public vars for your namespaces and all the dependencies, record the :style/indent metadata, and write a config file that specifies the indent config for every var that customizes it.

Joshua Suskalo17:09:42

Unfortunately what that means is that I'll either have to have users add this extra alias to their project or their user deps.edn, neither of which is desirable compared to being able to install the tool and then run it with -X, although I can see the reason why it is the way it is.


@suskeyhose A tool can read the project deps.edn and find the user's code.

Joshua Suskalo17:09:58

Yes, that's what I'll be doing for the formatter tool, but for the configuration generator I need to load both the code and the dependencies.


If you want it to be able to read code that exists under an alias, your tool would need to accept a list of aliases and use those when computing the basis.


The tool still does not need to be part of the deps.edn for that. Use tools.deps.alpha as a library to calculate the basis.


That's how depstar and many other tools work: they use t.d.a to compute the basis.

Joshua Suskalo17:09:05

Yes, the easiest way however to do this will be to require the namespaces, inspect them with ns-map, for all vars inspect the metadata, and build up a list that way. It would be preferable to not have to use tools.deps.alpha to procure all the deps, use the basis to find the location of the code, have to deal with source vs jar dependencies, parse/load the code, find metadata, etc.

Joshua Suskalo17:09:23

I suppose I may be able to mess with classloaders if I wanted to in order to load the dependencies at runtime using lambdaisland/classpath, but even that isn't exactly desirable if I can avoid it.


Or just use the add-lib3 branch of t.d.a and add dependencies that way 🙂

Joshua Suskalo17:09:59

I thought there were issues with that branch not working correctly. Has it been fixed, or was I misinformed?


I use it all the time. Not aware of problems. But you would still need to do some classloader stuff to add paths since add-libs doesn't handle that (although I guess you could add :local/root "." to get the current project?)


(that wouldn't help with :test deps though -- you'd still need classloader stuff for that)

Joshua Suskalo17:09:04

Yeah, loading the current paths can be alleviated by just using the clojure file-seq and load too.

Joshua Suskalo17:09:20

Which that's what I'd want to do anyway because otherwise there's a chance I don't load all the namespaces which are needed.


You'd have to figure out the right order to load files in based on their ns deps since you'd need to load from the "bottom" up.

Joshua Suskalo17:09:32

I suppose yeah, but there's already graph libraries and I could just parse the ns decls

Joshua Suskalo17:09:36

tools.analyzer provides me with almost everything I need for that


Clj-kondo can also provide you with that including for CLJS sources


Potentially it could also just give you that metadata for every var

Joshua Suskalo17:09:26

Oooh, if clj-kondo analysis can give me metadata for everything, then I might want to use that. The only problem I might have is for vars defined with macros.


if you just create a dummy file, stick all the ns's in a require in there, and load it, it will all load correctly


no need to build your own dependency graph to load things correctly

Joshua Suskalo18:09:06

That's true. clj-kondo would provide the added benefit of not being restricted to jvm clojure though, which is nice.


I said the same thing when the compile task in had an issue with code loading order, and looks like it got rewritten to build a dependency graph


you could even do the same thing without the temp file with something like

(fn [namespace-names] (binding [*compile-files* true] (run! require namespace-names)))


(for compiling)


the issue is just clojure.core/compile calls load-one, which doesn't do any checks to see if a ns has already been loaded, so if you do things in the wrong order you get multiple compiles, if you manually set *compile-files* and use require, it will check before loading