From c6dcaa030b9ecb5e20db1168cb83d7ed9e20bed1 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Ritschard Date: Sun, 11 Nov 2012 11:35:16 +0100 Subject: [PATCH] Allow handling of multiple calls of the same option. As for `:parse-fn`, a function can be supplied, this is useful for standard use-cases such as: -vv, or when you want to build a list from values. --- src/main/clojure/clojure/tools/cli.clj | 7 ++++--- src/test/clojure/clojure/tools/cli_test.clj | 11 +++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/main/clojure/clojure/tools/cli.clj b/src/main/clojure/clojure/tools/cli.clj index e02f58c..1a8cf9c 100644 --- a/src/main/clojure/clojure/tools/cli.clj +++ b/src/main/clojure/clojure/tools/cli.clj @@ -51,7 +51,7 @@ [specs] (reduce (fn [m s] (if (contains? s :default) - (assoc m (:name s) (:default s)) + ((:assoc-fn s) m (:name s) (:default s)) m)) {} specs)) @@ -72,12 +72,12 @@ (throw (Exception. (str "'" opt "' is not a valid argument"))) (and (opt? opt) (spec :flag)) - (recur (assoc options (spec :name) (flag-for opt)) + (recur ((spec :assoc-fn) options (spec :name) (flag-for opt)) extra-args (rest args)) (opt? opt) - (recur (assoc options (spec :name) ((spec :parse-fn) (second args))) + (recur ((spec :assoc-fn) options (spec :name) ((spec :parse-fn) (second args))) extra-args (drop 2 args)) @@ -105,6 +105,7 @@ :aliases (set aliases) :name (keyword (last aliases)) :parse-fn identity + :assoc-fn assoc :flag flag} (when flag {:default false}) options))) diff --git a/src/test/clojure/clojure/tools/cli_test.clj b/src/test/clojure/clojure/tools/cli_test.clj index b0d8e01..27ffaed 100644 --- a/src/test/clojure/clojure/tools/cli_test.clj +++ b/src/test/clojure/clojure/tools/cli_test.clj @@ -58,6 +58,17 @@ (first (cli ["-s" "localhost"] ["-s" "--server"])))))) + (testing "merging args" + (deftest should-merge-identical-arguments + (let [assoc-fn (fn [previous key val] + (assoc previous key + (if-let [oldval (get previous key)] + (merge oldval val) + (hash-set val)))) + [options args _] (cli ["-p" "1" "--port" "2"] + ["-p" "--port" "description" :assoc-fn assoc-fn])] + (is (= {:port #{"1" "2"}} options))))) + (testing "extra arguments" (deftest should-provide-access-to-trailing-args (let [[options args _] (cli ["--foo" "bar" "a" "b" "c"]