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
by

(根据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 和 ops 一起表现良好,因为它防止了在添加别名时更新大量脚本的需求(例如,你可以在任何地方始终使用相同的“main”别名,并添加/删除它所需的别名,No changes outside `deps.edn`)。
by
我们有一个 monorepo,这绝对是我们遇到的一个痛点,直到我们找到了一个更适合 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 指出,当从多个别名继承时可能会发生冲突。因此,引用一个别名向量而不是一个集合可能更可取。由于这个担忧,这里可能存在其他需要解决的问题,但我仍然认为这是一个有用的功能。

by
是的,排序确实很重要
+1 投票
by

我的担忧是将继承(甚至多重继承)的复杂性引入到一个本 rất đơn giản khác. Một trong những điều chính tôi học được từ nhiều năm làm việc Java là tránh các cách tiếp cận này và sử dụng composotion, điều này cung cấp sự linh hoạt lớn hơn nhiều.

Đ]")]

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

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

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

也许避免这个问题的一种方法是有一种类似:meta-aliases的东西,它只能包含别名而不能包含其他:meta-aliases,但这样一来似乎仍然在增加复杂性。

我希望能够解决专门针对 mono-repls 的问题,而不会给deps.edn配置增加复杂性(特别是避免继承或甚至多重继承)。

+1 投票
by

我认为一种可能有效的语法可能类似于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

这对 linting 非常有帮助。

clj -M:eastwood:kibit:antq

可能是

clj -M:lint
当你结合所有包含 :main-opts 的别名时,只会使用最后一个(因为主选项具有位置性,传递给 clojure.main 的 -main 函数),所以你不能通过单个命令行运行多个 lint 工具,即使有多个别名。

你需要其他过程来逐个运行这三个 lint 工具的 -main 函数。
是的,这是一个众所周知的问题,但仍然可以通过提供手工创建的 :main-opts 来克服这个问题,将工具的主要函数调用组合成一个在 :lint 别名内部的函数。例如,按照 Cam Saul 的 Lein 类似语法示例。这样它将是最后一个,应该会覆盖其他所有设置。
by
马克,你的意思是拥有 ":main-opts" 使其包含 "-e" 和一个表达式,该表达式调用每个三个 "-main" 函数?比如 "(do (eastwood/-main) (kibit/-main) (antq/-main))"。
无论主命名空间是什么。

鉴于许多工具在末尾调用 (shutdown-agents),你很可能无法在之后运行 -main 函数...
...