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

欢迎!请查看关于页面以了解更多有关如何使用本站的信息。

+1 点赞
tools.cli

这实际上是一个修辞问题,因为我已经了解到,tools.cli无法对位置参数执行任何操作,只是将它们作为字符串向量传递给库的使用者。但我会分享我的用例。

我正在编写一个工具,该工具将文件从一个目录复制到另一个目录。它接受两个位置参数,即源和目的地。目前我的代码包含两次输入验证和解码,第一次使用tools.li,然后是第二次使用自己的函数parse-arguments。如果能将这两件事情一起完成会很好。

下面是使用示例代码。

(ns multi-machine-rsync.cli
  (:require [clojure.tools.cli :as cli]
            [clojure.java.io   :as io]
            [clojure.string    :as string]))

(defn read-settings
  [path]
  (read-string (slurp path)))

(def cli-options
  [["-h" "--help" "Show this help text"]
   ["-s" "--settings SETTING-FILE" "Path to the settings file."
    :parse-fn read-settings
    :default  "settings.edn"]])

(defn usage
  [options-summary]
  (string/join
   \newline
   ["Copies a directory from one place to another in a common"
    "directory structure using multiple machines."
    ""
    "Usage: multi-machine-rsync [OPTIONS] SOURCE DESTINATION"
    ""
    "Options:"
    options-summary]))

(defn parse-arguments
  "Parse and validate command line arguments. Either return a map                                                                                         
  indicating the program should exit (with a error message, and                                                                                           
  optional ok status), or a map indicating the action the program                                                                                         
  should take and the options provided."
  [args]
  (let [{:keys [arguments options errors summary]} (cli/parse-opts args cli-options)
  	[source destination]                       (map io/file arguments)]
    (cond
      (:help options)              {:exit-message (usage summary) :ok? true}
      errors                       {:exit-message errors}
      (nil? source)                {:exit-message "First positional argument SOURCE not given."}
      (nil? destination)           {:exit-message "Second positional argument DESTINATION not given."}
      (not (.exists source))       {:exit-message "Source directory does not exist."}
      (not (.exists destination))  {:exit-message "Destination directory does not exist."}
      :else                        {:options      options
                                    :source       source
                                    :destination  destination})))

2 答案

+1 点赞

作为 tools.cli 的维护者,我将考虑这个问题并决定是否为此创建一个 JIRA 问题。

大多数使用 tools.cli 的程序最终都需要一些帮助/用法的样板代码,以及一些额外的参数解析和/或验证,因此如果可以以相当简单的方式实现,增强库以使这更容易将有助于“所有人”。

要解决的问题之一是,指定选项的格式仅适用于实际选项(即以 --- 开头的)因此目前还没有任何地方可以“挂钩”任何纯文本参数处理。

0 点赞

你认为这能节省你很多工作吗?

位置参数带来了可选项、系列、键值对等的挑战。也许“短横线选项”只是那些溪流中的更多鱼,就像“find”和“unzip”一样。Clojure Spec已经开启了这条道路。也许你能将Spec集成到tools.cli扩展中。

(或者放弃并使用--src和--dest!)

...