请在 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 构建 CLI 的人数增多时,会有更多请求改进 Clojure 的 CLI 构建工具。如果你看看其他更常用作构建 CLIs 的生态系统(例如 Python、Ruby 等),它们拥有更复杂的 CLI 构建工具。例如,Python 的 argparse(标准库中的一种)除了处理选项外,还处理位置参数并为你处理 --help 文本。Python 的 click 还添加了用于轻松构建类似 AWS CLI 或 leiningen 的“嵌套”CLI 的工具。相比之下,Clojure 的工具相当基础,这对于之前生态系统的状态是有意义的,但可能不会再是这样了。
我也对这种行为感到困惑,因为我正试图使用 tools.cli 强制必要的选项。正如在 #clojure slack 频道中所建议的

(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)) "缺少必要的选项:--gitlab-token"]
    ]
   ["-h" "--help"]])

不起作用,因为 :validate 函数根本从未被调用。我实际上更喜欢某种类型的 :mandatory(:required 已经被占用)属性来强制用户必须设置此选项。
tools.cli中的"required"表示选项后面需要一个值,而不是选项本身是必需的。

我看到了几项增强的请求,它们都属于后处理类别,如处理非选项参数和处理强制选项检查等。目前工具.cli没有提供任何钩子来实现这一点,但看起来这是一个很好的增强区,所以我会考虑一下。

感谢对此提供的输入。
...