2024 Clojure调查问卷中分享您的想法!

欢迎!有关此功能的工作方式,请参阅关于页面以获取更多信息。

0
tools.deps
封闭
{code:title=src/foo/core.clj}
(ns foo.core)

(defn -main [& args]
  (prn args))



$ clj -Srepro -Sdeps '{:aliases {:space {:main-opts ["-m" "foo.core" "-co" "{:aot-cache true}"]}}}' -Aspace
("-co" "{:aot-cache" "true}")


期望传递给{{foo.core/-main}}的两个选项,而不是三个。
用以下备注封闭: Clojure CLI 1.10.2.786预发行版中提供了修复

13 个答案

0

评论者:pesterhazy

附上两个补丁,一个用于“brew install”仓库,另一个用于“tools deps”仓库。

采用的方法是使用反斜杠引号引用写入到.main文件的参数,例如

\-\-n\a\m\e \J\o\h\n\ \S\n\o\w

更改的bash部分使用eval解引用字符串,将其分成多个参数。

两个补丁都需要同时应用。

0
_由 pesterhazy_ 制作的评论:

应用补丁后,示例正确打印


("-co" "{:aot-cache true}")


FWIW,我发现辅助脚本来测试涉及 brew-install 和 tools.deps.alpha 的更改很有用:"try" 和 "demo":https://github.com/pesterhazy/brew-install/pull/1/files#diff-d67b65744525f3bb15715e95ba3117eb
0

由 alexmiller 制作的评论:

能否讨论一下引号方法或使用 eval 的任何缺点?

你还遇到了其他处理该问题的方法吗?

0

由 alexmiller 制作的评论:

此外,如果用户现有(非反斜杠的)缓存的主文件,他们的体验如何?也就是说,它与现有的缓存文件是否兼容?

0

由 alexmiller 制作的评论:

这种使用 eval 读取任意用户文件(可能在两点之间被操作)的方式似乎有重大安全风险: http://mywiki.wooledge.org/BashFAQ/048 因此我更愿意在这里寻找替代方案。

0

评论者:pesterhazy

关于替代方案,Bash 代码需要能够读取 .main 文件并将内容拆分为单个参数。理想情况下,这应该仅使用 Bash 内置命令完成,即不 spawn 另一个进程。

使用纯 Bash 解析 JSON 或 EDN 是不可能的。另一种可能性是将参数通过换行符分隔。但是,回读这些内容到数组中的 Bash 代码不会太简单,或者至少不如使用 eval 解析内容简单。

使用 eval 内置命令的潜在缺点是,与 Clojure 读取器类似,Bash 读取器可能会有副作用。例如,当内容包含 $(rm /important/file)>/important/file 时。

但是,我们控制写入文件的代码并转义所有字符。因此,美元符号和更大的字符前面将加上反斜杠。我认为这是安全的。

我必须考虑向前/向后兼容性-这是个好观点。

0

评论者:pesterhazy

解决向后兼容问题的简单方案是使用不同的后缀,例如 .qmain,或者以一个法术字符串(例如1. 引号)开始文件。

0

评论者:pesterhazy

另一个选择是在使用 eval 之前检查输入:

[[ "\\a\\b\\c \\d" =~ ^(\\.| )*$ ]]

0

评论人:arichiardi

确实是非常有用的脚本(我的意思是尝试和演示)

0

评论者:pesterhazy

作为 eval 的替代方案,Bash 代码可以手动将字符串读入一个数组,一个字符一个字符。参数需要由分隔符分隔。

以下三个可能的分隔符值得考虑

  • NUL:不会工作,因为 Bash3(由 macOS 强制实施)中没有提供 readarray,NUL 也不能存储在 Bash 变量中
  • 空格
  • 换行符

由于换行符在主选项中出现的可能性较小,因此我的选择将是换行符。然而,换行符仍然可能发生,因此Clojure 代码应使用反斜杠转义它们。此外,还需要转义字面反斜杠。

我已经证明了这个方案在 Bash3 中有效:[https://github.com/clojure/brew-install/pull/3/files#diff-b3212e45e19f61de4754a755466b793f](https://github.com/clojure/brew-install/pull/3/files#diff-b3212e45e19f61de4754a755466b793f)

如果听起来合适,我会更新补丁。

0

评论人:dottedmag

我已经附件了 {{brew-install-nul-terminated.patch}} 和 {{tda-nul-terminated.patch}},它们将 {{.main}} 文件的格式改为具有以 NUL 结尾的参数,而不是空格分隔。

向后兼容性
- 这些补丁更改缓存标识符,因此使用旧 {{.main}} 格式的缓存将不会被重用
- 在 {{:main-opts}} 中的 NUL 字符之前处理方式不一致:在 Bash < 4.3(例如 MacOS)中,NUL 字符之后的部分参数被跳过,在 Bash >= 4.3(例如新的 Linux)中,NUL 字符被跳过,所以我们在这里重复使用 NUL 作为参数分隔符并没有破坏任何东西。

操作系统兼容性
- Bash >= 2.04(约于 2000 年发布,所有相关操作系统都有更新的 Bash)

替代方案

  • 转义空格而不是 NUL 终止行
    -- 优点:没有?
    -- 缺点:Bash 解析代码变得更加复杂(除非使用 {{eval}} 及其相关问题)
  • 使用 {{.main2}} 文件而不是更改现有缓存条目的哈希
    -- 优点:升级后,不需要 {{.main}} 文件的现有缓存条目可以重复使用
    -- 缺点:需要额外的复杂逻辑来检测带有 {{.main}} 文件的缓存条目,将它们视为已过时,并在刷新缓存后删除旧的 {{.main}} 文件。
0
by
参考: https://clojure.atlassian.net/browse/TDEPS-56(由 mfikes 报告)
...