在包含多个模块的 monorepo 的上下文中,我发现了一个 clojure.tools.build.api/compile-clj
的问题,这使得当基本的工程根目录不在当前目录时,编译文件变得困难。
以下是一个演示问题的最小方案。
我有顶级 monorepo deps.edn
使用 tools.build 准备/打包其模块。
{:deps {monorepo/module-a {:local/root "modules/a"}}
:aliases {:build {:deps {io.github.clojure/tools.build {:git/tag "v0.8.2"
:git/sha "ba1a2bf"}}
:ns-default build}}}
模块 A 包含一些 clojure 源文件。这里是 modules/a/deps.edn
。
{:paths ["src"]}
这些文件需要编译步骤。这里是处理这些文件的顶级 build.clj
文件。
(ns build
(:require [clojure.tools.build.api :as b]))
(def module-a (binding [b/*project-root* "modules/a"]
(b/create-basis {:project "deps.edn"})))
(defn compile-a [_]
(b/compile-clj
{:basis module-a
:src-dirs ["modules/a/src"]
:class-dir "target/module-a/classes"}))
但是,当我从顶级目录调用 clojure -T:build compile-a
时,我遇到了以下错误。
Execution error (FileNotFoundException) at user/eval136$fn (compile.clj:5).
Could not locate monorepo/module/a__init.class, monorepo/module/a.clj or monorepo/module/a.cljc on classpath.
问题是 "src" 相对目录没有被展开在前面的 :classpath-roots
中,这导致 compile-clj
在错误的位置搜索源文件。通过再次绑定 *project-root*
并根据模块 A 的根目录调整 :src-dirs
和 class-dir
,可以绕过这个问题。
(defn compile-a [_]
(binding [b/*project-root* "modules/a"]
(b/compile-clj
{:basis module-a
:src-dirs ["src"]
:class-dir "../../target/module-a/classes"})))
然而据我所知,如果将基础中的计算路径完全展开,将相对路径转换为绝对路径,会更好,这样就可以避免这种额外的仪式。
您怎么看?
为什么相对源路径目录当前保持为相对路径?