分享您的想法,请参加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,但在做出任何决定之前需要进行分析。根据没有人之前提出过这个请求,我认为这不像你说的那么常见。
我认为这一点在之前没有被要求过是有道理的,因为过去由于 JVM 启动时间的原因,Clojure 并不是一个构建基于 CLI 的程序的有效工具。现在 babashka 出现了,随着使用 Clojure 构建 CLIs 的人数增加,我猜想会有更多要求改进 Clojure 的 CLI 构建工具。如果你看看其他更常用作构建 CLIs 的生态系统(例如 Python、Ruby 等),它们有更复杂的 CLI 构建工具。例如,Python 的 argparse(在标准库中)除了处理选项外还处理位置参数,并为你构建 --help 文本。Python 的 click 在此基础上增加了构建“嵌套”CLIs 的工具,就像 AWS CLI 或 leiningen 那样。相比之下,Clojure 的工具相当简陋,这在生态系统之前的状态中是有意义的,但可能未来不再是。
我也对这种行为感到困惑,因为我正在尝试使用 tools.cli 来强制必选项。正如在 #clojure 电报频道中建议的那样

(def cli-options
  [["-U" "--gitlab-uri URI" "Gitlab 主机 URI" :parse-fn #(URI. %)]
   ["-t" "--gitlab-token TOKEN" "Gitlab 令牌"
    :default ::absent
    :validate [(fn [x] (println "XXXXX:" x) (not= ::absent)) "缺少必需的选项:--gitlab-token"]
    ]
   ["-h" "--help"]])

由于 :validate 函数从未被调用,所以它不起作用。我实际上更喜欢某种类型的 :mandatory(:required 已经被占用)属性来强制用户设置此选项。
在 tools.cli 中,“required”意味着选项后面需要一个值,而不是选项本身是必须的。

我看到了几个增强请求,它们都属于后处理类别,例如处理非选项参数和处理强制性选项检查等。目前 tools.cli 没有任何“钩子”可以处理这些,但这是一个很好的增强领域,所以我将考虑这一点。

感谢对此的反馈。
...