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

(根据关于https://clojure.atlassian.net/browse/CLJ-2638状态的Slack讨论提出)

看似别名依赖于其他别名的想法可能最初看起来不太有用,但我相信它是一种组织Clojure单仓库的很强大的结构。当然,解决Clojure单仓库问题的方法有很多,但一种简单的方法是

  • 在仓库根目录中维护一个单独的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
另一个好处是它很好地与持续集成和运维兼容,因为它防止了在添加别名时需要更新无数脚本(例如,您始终可以在任何地方使用相同的“main”别名并添加/删除它需要的别名,外部 `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中学到的一个关键经验是避免这些方法,而使用组合,这提供了更大的灵活性。

使用tools.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 函数。
是的,这是一个已知的问题,但仍然可以通过提供定制的 :main-opts 来解决,将所有工具的主函数调用组合在一起,例如,按照 Cam Saul 的 Lein-alike 语法示例。这样它将是最后一个,并覆盖其余的。
马克,你的意思是可以有一个包含“-e”和一个表达式的:main-opts,这个表达式会程序性地调用这三个:main 函数?就像“(do (eastwood/-main) (kibit/-main) (antq/-main))”
(无论主命名空间是什么)。

鉴于许多工具有在最后调用(shutdown-agents)的习惯,之后你可能无法再运行:main 函数...
...