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 单元仓库的一种强大的结构。当然,处理 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...
当然可以编写需要无数别名的脚本调用,但这既复杂又容易出错。一个别名能够要求一个别名向量就能解决这个问题,case settled.

by
另一个好处是它很好地与CI和运营配合使用,因为它防止了添加别名时需要更新无数脚本的情况(即无论在哪里都可以使用相同的"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指出,从多个别名继承时可能存在冲突的潜在风险。因此,使用别名向量而不是集合进行引用可能更可取。由于这个担忧,可能会有其他设计挑战需要解决,但我仍然认为这是一个有用的功能。

by
是的,顺序肯定很重要。
+1
by

我的担忧是将继承(甚至多重继承)的复杂性引入到原本简单的配置中。我从多年的Java经验中学会的关键一点是避免这些方法,并使用组合,这提供了更大的灵活性。

使用tools.build是否是一个更简单的方法来在单仓库中解决此问题?

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

是否存在明确的优先级规则?
是否有工具可以诊断冲突所在的地点——也许-Stree足以处理,但我并不确定。

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

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

我希望能够解决单仓库特定的问题,而不要增加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

这对进行代码审查非常有用。

clj -M:eastwood:kibit:antq

可能是

clj -M:lint
当您组合所有包含
:main-opts
的别名时,只有最后一个将被使用(因为主选项是位置参数,传递给
clojure.main
-main
函数),因此您不能通过单个命令行运行多个代码审查工具,即使有多个别名也是如此。

您需要其他进程来依次运行三个代码审查工具的
-main
函数。
是的,这是一个众所周知的问题,但您仍然可以通过提供一个精致的
:main-opts
来克服这个问题,该选项将所有工具的主要函数调用合并成一位于
:lint
别名内部,例如按照Cam Saul的类似Lein的语法示例。这样它将是最后的一个,并且将覆盖其他的。
by
Mark,你的意思是指拥有:main-opts 包含一个 "-e" 和一个对三个 -main 函数逐个程序调用的表达式吗?比如 "(do (eastwood/-main) (kibit/-main) (antq/-main))"
(无论主命名空间是什么)。

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