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
by
_由 pesterhazy 提出的评论:

应用补丁后,示例代码按预期输出


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


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

由 alexmiller 提出的评论:

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

在处理这个问题时,是否还遇到了其他选项?

0
by

由 alexmiller 提出的评论:

此外,如果用户有现有的(非转义的)缓存的 main 文件,他们的体验如何?也就是说,这是否与现有的缓存文件向后/向前兼容?

0
by

由 alexmiller 提出的评论:

看来使用 eval 以这种方式读取任意用户文件(可能在这两点之间被操纵)具有显著的安全风险: http://mywiki.wooledge.org/BashFAQ/048 因此,我更愿意在这里找到一种替代方法。

0
by

评论者:pesterhazy

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

使用纯 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

如果听起来没问题,我将对补丁进行更新。

0

评论者:dottedmag

我附上了 {{brew-install-nul-terminated.patch}} 和 {{tda-nul-terminated.patch}},这两个补丁将 {{.main}} 文件的格式更改为以NUL结尾的参数,而不是空格分隔。

向后兼容性
- 这些补丁更改缓存ID,因此使用旧 {{.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}}文件的现有缓存条目可以重用
    -- 缺点:在Clojure中需要额外复杂的逻辑来检测含{{.main}}文件的缓存条目,将它们视为过时,并在刷新缓存后删除旧的{{.main}}文件。
0
参考:https://clojure.atlassian.net/browse/TDEPS-56(由mfikes报告)
...