Fork me on GitHub
#tools-deps
<
2022-09-20
>
cfleming01:09:22

I’m having a problem with the Cursive build, due to the fact that I’m using a fork of Clojure. I’m using :classpath-overrides like this:

{:deps      {com.cursive-ide/clojure {:mvn/version "1.10.4"}}
 :aliases   {:no-clojure {:classpath-overrides {org.clojure/clojure ""}}}
 :mvn/repos {"" {:url "my-repo-url"}}}
What I’m finding since the base Clojure version has moved on from the version of my fork is that I’m getting incorrect versions of spec. My Clojure version depends on the spec versions from Clojure 1.10.3, but the versions from 1.11.1 are different. What seems to happen is that deps returns the latest spec version (corresponding to 1.11.1), but the classpath-overrrides is processed later, leaving the spec versions without a valid parent in the deps tree. I can’t even add the right spec versions explicitly to my :deps, since they’re still filtered out earlier in the process than the classpath-overrides is run. Is there any useful workaround to this problem?

hiredman01:09:49

I may be misunderstanding, but I don't believe any dependency information is conveyed when using classpath overrides

hiredman01:09:49

very literally "replace the path this dep would have used with this other path" no search for or usage of dependency information found there

cfleming01:09:26

Right, it looks like not. The problem is that that means there’s no way to remove a dep and its dependencies, and there’s no way I can see to manually force the dependencies I want since they’re overridden earlier in the process.

hiredman01:09:36

A local dep might be what you want, since that includes dependency information

cfleming01:09:07

A local dep for the fork, you mean? I don’t think the problem is the dependency information from the fork (since my fork correctly specifies the dependencies it needs), it’s that that info is discarded early in the process.

hiredman01:09:03

Because you are bringing the fork in using the classpath override, the dependency information from the fork (what version of spec it wants) isn't considered

cfleming01:09:59

No. I bring the fork in as a normal dep, with dependencies as usual. What I’m doing with the classpath override is trying to get rid of the mainline version of Clojure so it doesn’t conflict with the fork.

hiredman01:09:20

Ah, yeah, you need a top level exclusion, I forget if that is a thing

cfleming01:09:59

I don’t think it is, unfortunately.

cfleming01:09:01

I can’t even manually add :exclusions to all my deps coords, since Clojure comes in from the system deps file.

hiredman01:09:07

If you are publishing to your own repo, you could squat org.clojure/clojure and use a special version

cfleming01:09:34

Sadly: > tools.deps guarantees that the “central” and “clojars” repositories will be checked first, in that order, for Maven libraries. The lookup order of other repositories is undefined.

hiredman01:09:13

I guess I don't know mavens algorithm exactly there, if you specify a version that doesn't exist in central, but does in your repo, it won't check your repo because it checks central first?

cfleming01:09:40

I’m not sure, in that case. I guess it probably would, I’d just have to use a version numbering scheme that didn’t ever conflict with Clojure.

cfleming01:09:00

And versions which are always seen by Maven as higher than public versions.

hiredman02:09:45

I believe the version algorithm tools.deps uses isn't just a straight comparison, but also considers where it is specified, and if i am remembering that correctly, then what you directly specify in your deps.edn should always win

cfleming02:09:54

It starts to sound like relying a lot on implementation details, though. I’ll see what’s involved in just updating my fork, which might be the easiest solution.

cfleming02:09:44

Indeed, updating my fork was the easiest thing to do. But it would be good to have a not-horrible workaround for this.

ambrosebs15:10:09

@U0567Q30W try adding this to the :no-clojure alias:

:deps {org.clojure/clojure {:mvn/version "1.11.1" :exclusions [org.clojure/spec.alpha]}}

pez06:09:23

We're running into a strange problem where a dependency on com.datomic/datomic-free messes up the cider/piggieback dependency. The repository is public, here: https://github.com/skydread1/flybot.sg/tree/42-simple-clojure-backend There's an alias dev-server that brings in datomic-free:

:dev-server
  {:extra-paths ["src/clj"]
   :extra-deps {com.datomic/datomic-free {:mvn/version "0.9.5697"}}}
If I specify that alias on the clojure command line, together with the injection of piggieback and using piggieback nrepl middleware, I get the error that the namespace cider.piggieback is not found:
$ clojure -Sdeps '{:deps {nrepl/nrepl {:mvn/version,"1.0.0"},cider/cider-nrepl {:mvn/version,"0.28.5"},cider/piggieback {:mvn/version,"0.5.3"}}}' -M:dev-server -m nrepl.cmdline --middleware "[cider.nrepl/cider-middleware cider.piggieback/wrap-cljs-repl]"
Execution error at nrepl.cmdline/require-and-resolve (cmdline.clj:221).
No namespace: cider.piggieback found

Full report at:
/var/folders/t5/gqxhj8pd6p9_tnvy6sbtmy480000gn/T/clojure-13582953176357101871.edn
Whereas if I don't use that alias, the nREPL server starts without complaints:
$ clojure -Sdeps '{:deps {nrepl/nrepl {:mvn/version,"1.0.0"},cider/cider-nrepl {:mvn/version,"0.28.5"},cider/piggieback {:mvn/version,"0.5.3"}}}' -M -m nrepl.cmdline --middleware "[cider.nrepl/cider-middleware cider.piggieback/wrap-cljs-repl]"
nREPL server started on port 49890 on host localhost - 
What could we further do to investigate/fix this issue? Anyone has an idea?

thheller06:09:03

what does the Full report say? should contain the cause exception

pez07:09:34

Thanks. forgot to include the full report:

{:clojure.main/message
 "Execution error at nrepl.cmdline/require-and-resolve (cmdline.clj:221).\nNo namespace: cider.piggieback found\n",
 :clojure.main/triage
 {:clojure.error/class java.lang.Exception,
  :clojure.error/line 221,
  :clojure.error/cause "No namespace: cider.piggieback found",
  :clojure.error/symbol nrepl.cmdline/require-and-resolve,
  :clojure.error/source "cmdline.clj",
  :clojure.error/phase :execution},
 :clojure.main/trace
 {:via
  [{:type java.lang.Exception,
    :message "No namespace: cider.piggieback found",
    :at [clojure.core$the_ns invokeStatic "core.clj" 4163]}],
  :trace
  [[clojure.core$the_ns invokeStatic "core.clj" 4163]
   [clojure.core$ns_resolve invokeStatic "core.clj" 4370]
   [clojure.core$ns_resolve invokeStatic "core.clj" 4360]
   [clojure.core$ns_resolve invoke "core.clj" 4360]
   [nrepl.cmdline$require_and_resolve invokeStatic "cmdline.clj" 221]
   [nrepl.cmdline$require_and_resolve invoke "cmdline.clj" 211]
   [nrepl.cmdline$fn__2105 invokeStatic "cmdline.clj" 225]
   [nrepl.cmdline$fn__2105 invoke "cmdline.clj" 225]
   [clojure.core$map$fn__5931$fn__5932 invoke "core.clj" 2759]
   [clojure.core$map$fn__5931$fn__5932 invoke "core.clj" 2759]
   [clojure.lang.PersistentVector reduce "PersistentVector.java" 343]
   [clojure.core$transduce invokeStatic "core.clj" 6946]
   [clojure.core$into invokeStatic "core.clj" 6962]
   [clojure.core$into invoke "core.clj" 6950]
   [nrepl.cmdline$__GT_mw_list invokeStatic "cmdline.clj" 252]
   [nrepl.cmdline$__GT_mw_list invoke "cmdline.clj" 250]
   [nrepl.cmdline$build_handler invokeStatic "cmdline.clj" 261]
   [nrepl.cmdline$build_handler invoke "cmdline.clj" 254]
   [nrepl.cmdline$options__GT_handler invokeStatic "cmdline.clj" 330]
   [nrepl.cmdline$options__GT_handler invoke "cmdline.clj" 321]
   [nrepl.cmdline$server_opts invokeStatic "cmdline.clj" 380]
   [nrepl.cmdline$server_opts invoke "cmdline.clj" 367]
   [nrepl.cmdline$dispatch_commands invokeStatic "cmdline.clj" 480]
   [nrepl.cmdline$dispatch_commands invoke "cmdline.clj" 473]
   [nrepl.cmdline$_main invokeStatic "cmdline.clj" 496]
   [nrepl.cmdline$_main doInvoke "cmdline.clj" 491]
   [clojure.lang.RestFn applyTo "RestFn.java" 137]
   [clojure.lang.Var applyTo "Var.java" 705]
   [clojure.core$apply invokeStatic "core.clj" 667]
   [clojure.main$main_opt invokeStatic "main.clj" 514]
   [clojure.main$main_opt invoke "main.clj" 510]
   [clojure.main$main invokeStatic "main.clj" 664]
   [clojure.main$main doInvoke "main.clj" 616]
   [clojure.lang.RestFn applyTo "RestFn.java" 137]
   [clojure.lang.Var applyTo "Var.java" 705]
   [clojure.main main "main.java" 40]],
  :cause "No namespace: cider.piggieback found"}}

thheller07:09:57

hmm not sure but should it maybe be -A:dev-server -M in the command line? not sure if -M maybe drops -Sdeps or so if used with alias?

pez07:09:07

Doesn't seem to be the issue. I get the same result. Also, it is the datomic-dependency that makes the difference. If I replace it with some other dependency in the alias, piggieback is found and the REPL starts.

thheller07:09:14

my guess would be on a dependency conflict. I'm guessing that the presence of piggieback causes clojurescript to be added and loaded as well

thheller07:09:31

and clojurescript (or rather the closure-compiler) can fail to load with a conflicting guava dependency on the classpath

thheller07:09:38

which in turn comes from datomic

thheller07:09:14

dunno where that actual exception ends up though. it usually throws a proper exception making this easier to debug

thheller07:09:09

try adding this dep as well [com.google.guava/guava "31.0.1-jre"] via the alias or -Sdeps

thheller07:09:33

confirms that its the dependency conflict if it works 😉

🙌 1
pez07:09:18

Confirmed then. 😃 Because works! Thank you! Check here, @loic ^ That's your workaround.

👍 1
Loic07:09:55

Thank you!