请在2024 年 Clojure 调查问卷中分享您的看法!

欢迎!请查阅关于页面以获取更多关于这个工作的信息。

+46
tools.deps
重新标记

有一个别名让其他别名生效将是有用的。

一个用例是有时只针对一个项目进行开发,而有时则针对一组项目进行开发。

以下是一个示例

{:aliases 
  {:dev/project1 {:override-deps {:local/root "/some/path/project1"}}
   :dev/project2 {:override-deps {:local/root "/some/path/project2"}}
   :dev/project3 {:override-deps {:local/root "/some/path/project3"}}
   ;; something like the following:
   :dev/all-projects {:aliases #{:dev/project1 :dev/project2 :dev/project3}}}

6 个答案

+2

(在 Slack 上询问 https://clojure.atlassian.net/browse/CLJ-2638 的状态之后)

一开始可能觉得需要一个别名要求其他别名可能不是很有用,但我相信这是一种用于以简单方式组织 Clojure Monorepos 的强大结构。当然,处理 Clojure Monorepos 的问题有很多方法,但一种简单的方法是

  • 在仓库根目录维护一个单独的 deps.edn
  • 每个外部依赖项一个别名
  • 每个内部 "模块" 和关心的问题一个别名(例如::foo/main:foo/test:bar/main:bar/test,…)

这给了我们

  • 所有内容都在一个清晰的 deps.edn
  • 无需动态构建 deps.edn 文件,如某些项目所示(消除了声明性工具的目的)
  • 外部依赖被固定;例如,所有需要外部库的模块都使用相同版本,并使用该库的专用别名来避免重复。
  • 构建精确的类路径非常简单;只需连接别名即可。
  • 没有像传递依赖项未更新这样的情况。
  • 没有使用../../local-lib/src等不洁实践。

这是一个非常精确的方法,而且非常好用。唯一的缺点是,你现在必须与许多别名打交道,而且并不总是明显需要什么或不需要什么。

clj -M:module-1/dev:module-1:main:module-2/main:ext/lib-1:ext/lib-2:ext/lib-3...
当然,你可以编写需要无数别名的调用脚本,但这既复杂又容易出错。如果别名能够要求一系列别名,这个问题就可以解决了。

by
另一个好处是,它与CI和运营良好地协同工作,因为它阻止了添加别名时需要更新无数脚本的情况(即您可以在任何地方始终使用相同的“主”别名,并添加/删除它所需的别名,外部`deps.edn`不可见)。
by
我们有一个单仓,这绝对是我们遇到的一个痛点,直到我们找到了一个更适合deps.edn的结构——请参阅我在corfield.org上有关这一旅程的一系列博客文章——现在我们正在迁移到Polylith,这只需要几个别名。话虽如此,我的开发环境依赖于以下调用:

SOCKET_REPL_PORT=5000 clojure -J-Dlog4j2.configurationFile=log4j2-sean.properties -M:rebel:portal:everything:dev:test:runner:build:add-libs:dev/repl

当然,很乐意将这一切都封装在一个:dev/sean别名中(并且我经常添加几个更多别名以用于特定任务)。
+1 投票
by

感谢John Stevenson指出从多个别名继承可能存在冲突的潜在问题。因此,建议使用别名向量而不是集合进行引用可能更理想。由于这个担忧,可能会有其他设计挑战需要解决,但我仍然认为这是一个有用的功能。

是的,顺序确实是重要的
+1 投票

我的担忧是,将继承(甚至多重继承)的复杂性引入到一个本就简单的配置中。从多年的Java学习中,我学到的是要避免这些方法,并使用组合,这样可以提供更大的灵活性。

使用工具.build来处理这个问题与单仓库相比是不是一个更简单的方法?

在原始问题中提出的例子中,是否会有一种机制来防止或至少警告:dev/project1包含:dev/all-projects或另一个分组别名的情况?这个分组可以扩展到多少层?

是否有明确的优先级规则?
是否有工具可以诊断冲突的来源——可能Stree就足够了,但我并不确定。

别名分组是否仅限于在项目的deps.edn中定义的别名,或者也会包括用户级别的deps.edn(我假设排除用户级别配置会增加更多复杂性)

可能有避免这种情况的一种方法,就是有一种类似于:meta-aliases的东西,它只能包括别名,但不能包括其他:meta-aliases,但这似乎还是在增加复杂性。

我希望能够在不增加deps.edn配置复杂性(特别是避免继承或多重继承)的情况下解决单仓库特有的问题。

+1 投票

我想一种可能可行的语法可能类似于Leiningen所做的那样。

{:aliases
 {:with-tests {:extra-paths ["test"]}
  :with-dev-deps {:extra-deps [...]}
  :dev [:with-test :with-dev-deps {:exec-fn some/fn}]}}

:aliases 中面的别名可以是与我们已经支持的普通映射,也可以是一个带有名称的别名向量,后面可跟一个映射。别名向量可以相当于将那些别名也包括进来,例如上面示例中的 dev 别名基本上相当于 with-tests:with-dev-deps:dev(使用 dev 的映射部分)

0 投票
0 投票

这对于代码风格检查非常有用。

clj -M:eastwood:kibit:antq

可以是

clj -M:lint
当你结合所有包含 :main-opts 的别名时,只有最后一个被使用(因为主要选项是按位置的,传递给 clojure.main 的 -main 函数),因此即使使用多个别名,你也无法通过单个命令行运行多个代码风格检查工具。

你需要其他某个进程来依次运行这三个代码风格检查工具的 -main 函数。
是的,这是一个众所周知的问题,但是人们可以通过在 :lint 别名本身中提供一个手工艺的 :main-opts,将所有工具的主要函数调用组合成一个来解决这个问题,例如根据 Cam Saul 的 Lein-alike 语法示例。这样它将是最后一个,并将覆盖其余的。
by
马克,你的意思是拥有包含"-e"的`:main-opts`和一个按编程方式调用三个-主功能的表达式吗?比如 "(do (eastwood/-main) (kibit/-main) (antq/-main))”?
(不管主命名空间是什么).

鉴于许多工具在最后调用`(shutdown-agents)`,在这个之后你很可能无法运行-主函数...
...