请在 Clojure 2024 调查中分享您的想法!

欢迎!请参阅关于页面获取更多有关本网站如何工作的信息。

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

既然您控制着默认值,那么您自己检查它是理所当然的——因为如果有默认值无效,那就是编程错误,而不是用法错误。

这还像一个逃生舱,允许您提供一个用户通过选项无法提供的自定义默认值,这在某些情况下是必要的。

当然,我认为这是一个合理的默认值,但为什么不给开发者提供选项来验证默认值呢?将选项落到某种外部值(环境变量、配置文件等)是一种极其常见的模式,工具 CLI 可能可以更好地支持这一点,这将是一种简单的方法来实现。
我将将其跟踪为https://clojure.atlassian.net/browse/TCLI-99,但在做出任何决定之前需要进行分析。我认为这并不像您说的那样常见,因为之前没有人提出过此要求。
我觉得此前一直没有提出这样的请求是有道理的,因为以前Clojure由于JVM启动时间的问题,并不是一个建设基于CLI程序的可行工具。现在有babashka出现,我相信随着使用Clojure构建CLI程序的人越来越多,会有更多人要求提供改进Clojure的CLI构建工具。如果我们看看其他更常用于构建CLI环境的生态系统(例如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`已被占用)属性来强制用户设置此选项。
"required" 在 tools.cli 中的意思是选项后面需要一个值,而不是选项本身是必需的。

我看到了几个需要增强的请求,它们都属于后处理类别,比如处理非选项参数和处理强制选项检查等。这是 tools.cli 目前没有任何“钩子”的领域,但似乎非常适合增强,所以我会考虑一下。

感谢对这个问题的反馈。
...