2024 Clojure 状态调查! 中分享您的想法。

欢迎!请访问 关于 页面以获取更多有关此处如何工作的信息。

0
贡献库

以下是我工作中经常出现的一种模式

(def cli
  [["-f" "--foo FOO"
    :default-fn (fn [_] (System/getenv "FOO"))
    :default-desc "$FOO"
    :validate [seq "You must either use --foo or set $FOO"]])

不幸的是,这并不像预期的那样工作。即使使用了 :post-validation true,默认值也不会通过验证器验证。相反,我不得不编写一个单独的手动验证函数。我怀疑这是因为在没有调用选项的情况下,验证器不会运行。

是否有必要让 :post-validation 在具有默认值的选项上运行验证器?或者也许有一个额外的选项更合适,比如 :validate-default

1 个回答

0

由于您控制默认值,所以有两个内在的假设:一是您应该自己检查它——因为如果默认值无效,则这是一处编程错误而不是使用错误。

它还充当一个逃生门,因此您可以为用户提供一个默认值,该值用户无法通过选项来提供,这种情况有时是需要的。

当然,我认为这是一个合理的默认值,但为什么不给开发者提供验证默认值的选项呢?外部值(环境变量、配置文件等)的备选选项模式非常常见,而 tools.cli 可能能更好地支持这一点,这将是一个实现这一点的简单方法。
我会将此问题追踪为 https://clojure.atlassian.net/browse/TCLI-99,但在做出任何决定之前需要进行分析。根据此前没有人提出过这项需求,我认为这并不像你说的那样常见。
我认为之前没有人提出这个需求是有道理的,因为以前 Clojure 由于 JVM 启动时间的原因,并不是构建基于 CLI 的程序的经济实惠的工具。现在有了 babashka 这么好的东西,随着使用 Clojure 构建 CLIs 的人数增加,我猜想会有更多的请求来改进 Clojure 的 CLI 工具。如果你比较其他更常用来构建 CLIs 的生态系统(例如 Python,Ruby 等),它们都有更高级的 CLI 构建工具。例如,Python 的 argparse(在标准库中)除了处理选项外还处理位置参数,并为用户提供 --help 文本。Python 的 click 在此之上增加了构建类似于 AWS CLI 或 leiningen 样式的“嵌套”CLIs 的工具。相比之下,Clojure 的工具相当基础,这在生态系统的先前状态下是合理的,但未来可能不再是这样。
我也对这种行为感到困惑,因为我正在尝试使用 tools.cli 来强制必选项。正如在 #clojure 频道中建议的那样

(def cli-options
  [["-U" "--gitlab-uri URI" "Gitlab host URI" :parse-fn #(URI. %)]
   ["-t" "--gitlab-token TOKEN" "Gitlab token"
    :default ::absent
    :validate [(fn [x] (println "XXXXX:" x) (not= ::absent)) "Missing required option: --gitlab-token"]
    ]
   ["-h" "--help"]])

不起作用,因为 :validate 函数根本不会被调用。我实际上希望有一种类似于 :mandatory(:required 已经被占用)的属性来强制用户设置此选项。
"required" 在 tools.cli 中意味着选项后面需要跟随一个值,并不是说选项本身是必需的。

我看到了几个增强请求,这些都属于后处理类别,例如处理非选项参数和必需选项检查等。这是 tools.cli 目前没有提供任何 "钩子" 的功能,但似乎是一个很好的增强区域,因此我会考虑这一点。

感谢对此提出的意见。
...