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 制作

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

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变量中
  • 空格
  • 换行符

由于在main选项中不太可能出现换行符,因此我会选择换行符。然而,换行符仍然可能存在,因此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](https://clojure.atlassian.net/browse/TDEPS-56)(由 mfikes 报告)
...