请分享您的看法在2024年Clojure调查!

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

+1 投票
tools.cli

这其实是一个修辞问题,因为在我看来,tools.cli并不能对位置参数做任何事情,只是将它们作为字符串向量传递给库的用户。但我还是会分享我的用例。

我正在编写一个工具,它可以将文件从一个目录复制到另一个目录。它接受两个位置参数,源和目标。目前我的代码包含了两次输入验证和解析,第一次是为工具使用tools.cli,然后是第二次在我的自己的函数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 投票

你认为这能节省你多少工作?

位置参数带来了可选参数、序列、键值对等挑战,也许“减号选项”(dash options)就像“find”和“unzip”一样,只不过是这条河里的更多鱼。Clojure Spec已经阐明了这条道路。也许你可以将Spec集成到tools.cli扩展中。

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

...