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 monorepos的一种简单而强大的构建方法。当然,处理Clojure monorepos的问题有很多种方法,但一种直接的方法是

  • 在repo根处维护一个单独的deps.edn
  • 每个外部依赖一个别名
  • 每个内部“模块”和关注点(例如['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和运维互动良好,因为它可以防止在添加别名时不得不更新大量的脚本(例如,您可以在任何地方始终使用相同的“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 是否是一种解决 mono-repos 问题的更简单方法?

在原始问题中提出的例子中,是否存在一种机制来防止或至少警告 :dev/project1 包括 :dev/all-projects 或其他组别别的别名的情况?这种分组可以到几层?

是否存在明确优先级的规则?
是否有工具可以诊断冲突——也许 -Stree 已经足够,但我不确定。

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

可能的一种回避方法是有一个类似于 :meta-aliases 的东西,它只能包含别名,而不能包含其他 :meta-aliases,但这样似乎还是在增加复杂性。

我希望可以不对 mono-repls 的特定问题向 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-ops的别名组合在一起时,仅使用最后一个(因为main ops是位置参数,传递给clojure.main的弯函数),因此无法通过单行命令运行多个代码审查工具,即使使用多个别名。

需要另一种流程,依次调用三个代码审查工具的弯函数。
是的,这是一个众所周知的问题,但人们应该可以通过提供精制的::main-ops,将所有工具的弯函数调用组合在一个::lint别名中来自行克服。这样,它将是最后一个,并覆盖其他所有内容。
by
马克,你是说希望有包含"-e"和一个程序调用每个三个主函数的 :main-opts?比如 "(do (eastwood/-main) (kibit/-main) (antq/-main))"
(无论主命名空间是什么)。

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