Welcome! Please see the About page for a little more info on how this works.

+1 vote
in Clojure CLI by
edited by

While setting up a monorepo using tools.deps I have noticed that clojure -X:deps prep was not handling the case of nested :local/root dependency. Here is a minimal example that should help understand the issue.

I have a top-level deps.edn serving as a development basis depending two modules.

{:deps {monopero/module-a {:local/root "modules/a"}
        monopero/module-b {:local/root "modules/b"}}}

Here is module/a/deps.edn which is a module without dependency

{:paths ["src"]}

And here is module/b/deps.edn which defines a prep only dependency on module A

{:paths ["target/resources"]
 :deps/prep-lib {:alias :resources
                 :fn monorepo.b.core/generate
                 :ensure "target/resources"}
 :aliases {:resources {:paths ["src"]
                       :deps {monopero/module-a {:local/root "../a"}}}}}

From the top-level development basis I would expect to be able to run clojure -X:deps prep to trigger the preparation of module B. However when doing so I encounter the following error

~/src/scratch/recur-prep $ clojure -X:deps prep
Prepping monopero/module-b in /home/mthl/src/scratch/recur-prep/modules/b
Execution error (ExceptionInfo) at clojure.tools.deps.alpha.extensions/throw-bad-manifest (extensions.clj:158).
Manifest type not detected when finding deps for monopero/module-a in coordinate #:local{:root "/home/mthl/src/scratch/a"}

Full report at:
/tmp/clojure-5135322536447899533.edn

And here is the content of /tmp/clojure-5135322536447899533.edn

{:clojure.main/message
 "Execution error (ExceptionInfo) at clojure.tools.deps.alpha.extensions/throw-bad-manifest (extensions.clj:158).\nManifest type not detected when finding deps for monopero/module-a in coordinate #:local{:root \"/home/mthl/src/scratch/a\"}\n",
 :clojure.main/triage
 {:clojure.error/class clojure.lang.ExceptionInfo,
  :clojure.error/line 158,
  :clojure.error/cause
  "Manifest type not detected when finding deps for monopero/module-a in coordinate #:local{:root \"/home/mthl/src/scratch/a\"}",
  :clojure.error/symbol
  clojure.tools.deps.alpha.extensions/throw-bad-manifest,
  :clojure.error/source "extensions.clj",
  :clojure.error/phase :execution},
 :clojure.main/trace
 {:via
  [{:type clojure.lang.ExceptionInfo,
    :message
    "Manifest type not detected when finding deps for monopero/module-a in coordinate #:local{:root \"/home/mthl/src/scratch/a\"}",
    :data
    {:lib monopero/module-a,
     :coord {:local/root "/home/mthl/src/scratch/a"}},
    :at
    [clojure.tools.deps.alpha.extensions$throw_bad_manifest
     invokeStatic
     "extensions.clj"
     158]}],
  :trace
  [[clojure.tools.deps.alpha.extensions$throw_bad_manifest
    invokeStatic
    "extensions.clj"
    158]
   [clojure.tools.deps.alpha.extensions$throw_bad_manifest
    invoke
    "extensions.clj"
    153]
   [clojure.tools.deps.alpha.extensions$eval443$fn__444
    invoke
    "extensions.clj"
    166]
   [clojure.lang.MultiFn invoke "MultiFn.java" 244]
   [clojure.tools.deps.alpha$expand_deps$children_task__611$fn__613$fn__614
    invoke
    "alpha.clj"
    405]
   [clojure.tools.deps.alpha.util.concurrent$submit_task$task__247
    invoke
    "concurrent.clj"
    35]
   [clojure.lang.AFn call "AFn.java" 18]
   [java.util.concurrent.FutureTask run "FutureTask.java" 264]
   [java.util.concurrent.ThreadPoolExecutor
    runWorker
    "ThreadPoolExecutor.java"
    1128]
   [java.util.concurrent.ThreadPoolExecutor$Worker
    run
    "ThreadPoolExecutor.java"
    628]
   [java.lang.Thread run "Thread.java" 829]],
  :cause
  "Manifest type not detected when finding deps for monopero/module-a in coordinate #:local{:root \"/home/mthl/src/scratch/a\"}",
  :data
  {:lib monopero/module-a,
   :coord {:local/root "/home/mthl/src/scratch/a"}}}}

As I understand it the issue is that the "../a" local reference in module B is resolved from top-level directory instead of module B directory. While looking at the code I noticed that clojure.tools.deps.alpha/prep-libs! is not changing the current directory when creating the basis. My intuition is that it should do so with something like the following snippet

(let [root-dir (jio/file root)
      basis (dir/with-dir root-dir
              (create-basis
               {:extra {:aliases {:deps/TOOL {:replace-deps {} :replace-paths ["."]}}}
                :aliases [:deps/TOOL alias]}))
      ,,,]
  ,,,)

In case it matters I am using Clojure CLI version 1.11.1.1113

1 Answer

+1 vote
by
selected by
 
Best answer

Sounds like a reasonable hypothesis, I'll take a look.

by
I pushed a new dev release of Clojure CLI, version 1.11.1.1129 with this change (also added a test for this scenario).

You can test it by uninstalling your current Clojure CLI (if using brew, `brew uninstall clojure`) and then installing the new specific prerelease: `brew install clojure/tools/clojure@1.11.1.1129`. If on Linux, just install that version in the usual way.
by
I have tested this dev release and the problem is fixed. Thank you very much.
by
Thanks for trying it!
...