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}")


就事论事,我发现两个辅助脚本"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内建函数完成,即没有派生另一个进程。

解析JSON或EDN在纯Bash中是不可能的。另一个可能的方法是通过换行符分离参数。但这种将内容读取回数组中的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(由 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 提出)
...