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,我发现这两个辅助脚本“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,另一个可能性是按换行符分隔参数。但将Bash代码读回到数组中的操作不会很简单,至少不会像使用eval解析内容那样简单。

使用内建命令eval的潜在缺点是,犹如Clojure reader,Bash reader也可能有副作用。例如,当内容包含$(rm /important/file)>/important/file时。

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

我需要考虑前向/后向兼容性 - 一个好的观点。

0

评论者:pesterhazy

解决向后兼容问题的一个简单方法可以是使用像.qmain这样的不同后缀,或者以1.引号中的魔术字符串开始文件。

0

评论者:pesterhazy

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

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

0

评论者:arichiardi

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

0

评论者:pesterhazy

作为eval的替代方案,Bash代码可以手动将字符串逐字符读取到数组中。参数需要用分隔符分隔。

我想到了三个可能的分隔符

  • NUL:不会工作,因为Bash3中没有提供readarray(受macOS强制),且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终止的参数,而不是以空格分隔。

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

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

替代方法

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