tools-deps 2026-07-13

i just noticed that :main-opts are converted to strings, so i can pass in symbols and they will be converted to strings. is this intentional?

:repl {:extra-deps {nrepl/nrepl {:mvn/version "1.7.0"}
                    cider/cider-nrepl {:mvn/version "0.62.0"}}
       :main-opts [-m nrepl.cmdline
                   --interactive
                   --middleware ["cider.nrepl/cider-middleware"]]}

👀 1
Alex Miller (Clojure team) 2026-07-13T19:19:04.305399Z

I think you should probably not rely on that

😢 1

It's because writing the various options etc into the cached files implicitly converts everything to strings: https://github.com/clojure/tools.deps/blob/master/src/main/clojure/clojure/tools/deps/script/make_classpath2.clj#L129-L157 Very much a low-level implementation detail...

👀 1

(`:main-opts` specifically is handled on line 156)

So, they end up in plain text files in .cpcache and then they're read in by the shell script (I think?) as strings...

thanks for researching that, i poked around but couldn't find the exact implementation

Alex Miller (Clojure team) 2026-07-13T19:34:48.064979Z

yes, they're read back via bash read

I vaguely remembered that each invocation "compiles" everything to a set of .cpcache text files, so subsequent invocations with the same set of aliases/options don't need to compute & fetch dependencies and the clojure script can just read the .cpcache text files to construct the appropriate command-line to run. I hadn't dug into that bit of code much before, and it hadn't occurred to me that a side effect was that "everything" in deps.edn would become strings / plain text for the actual invocation!

Alex Miller (Clojure team) 2026-07-13T19:50:49.347949Z

this aspect specifically affects main opts and jvm opts (exec stuff really goes through the basis), but you should not expect all of the same things to happen in the future