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”存储库。

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

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

修改中使用的bash部分的字符串通过eval解除引用,将其分成多个参数。

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

0票数
_由 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票数

由 alexmiller 发表的评论:

你能讨论一下关于引号方法或使用 eval 的任何缺点吗?

你还在处理这个问题时遇到了其他选项吗?

0票数

由 alexmiller 发表的评论:

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

0票数

由 alexmiller 发表的评论:

看起来使用 eval 读取任意用户文件(文件内容可能在两个点之间被操纵)的方式带来了重大的安全风险:[链接](http://mywiki.wooledge.org/BashFAQ/048) 因此我更希望在这里找到一个替代方法。

0票数

评论者: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票数
by
参考:[链接](https://clojure.atlassian.net/browse/TDEPS-56)(由 mfikes 报告)
...