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 Yap

附上两个补丁,一个用于“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,我发现在涉及brew-install和tools.deps.alpha的更改测试中,“try”和“demo”这两个辅助脚本很有用: https://github.com/pesterhazy/brew-install/pull/1/files#diff-d67b65744525f3bb15715e95ba3117eb
0

评论者:alexmiller

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

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

0

评论者:alexmiller

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

0

评论者:alexmiller

使用eval方式读取任意用户文件(这些文件可能在两点之间被操纵)存在明显的安全风险: http://mywiki.wooledge.org/BashFAQ/048 因此,我宁愿在这里寻找替代方案。

0

评论由:pesterhazy Yap

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

仅使用Bash无法解析JSON或EDN。另一种可能性是按换行符分隔参数。但将读取回数组的Bash代码不会很简单,至少不如使用eval解析内容简单。

使用eval内置的缺点是,与Clojure读取器一样,Bash读取器可能有副作用。例如,当内容包含$(rm /important/file)>/important/file时。

但是,我们控制着写入文件的代码并转义所有字符。所以美元符号和更大的符号前面应该加上反斜杠。我认为这是安全的。

我必须考虑向前/向后兼容性 - 这是一个好点子。

0

评论由:pesterhazy Yap

要解决向后兼容性问题的一个简单解决方案是使用不同的后缀,如.qmain,或者以一个魔术字符串开头,例如“1. 引用。

0

评论由:pesterhazy Yap

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

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

0

评论者:arichiardi

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

0

评论由:pesterhazy Yap

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

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

  • NUL:不适用,因为在Bash3(由macOS强制规定)中不可用,而且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](https://clojure.atlassian.net/browse/TDEPS-56)(由 mfikes 报告)
...