diff --git a/CHANGELOG.md b/CHANGELOG.md index 22deb2a..6fad63f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ For breaking changes, check [here](#breaking-changes). [Babashka CLI](https://github.com/babashka/cli): turn Clojure functions into CLIs! +## v0.8.56 (2024-02-13) + +- Add `:opts` to `:error-fn` input + ## v0.8.55 (2024-01-04) - Fix `--no-option` (`--no` prefix) in combination with subcommands diff --git a/src/babashka/cli.cljc b/src/babashka/cli.cljc index 54b9283..2130fe6 100644 --- a/src/babashka/cli.cljc +++ b/src/babashka/cli.cljc @@ -437,7 +437,8 @@ :msg #?(:clj (.getMessage e) :cljs (ex-message e)) :option current-opt - :value arg}) + :value arg + :opts acc}) ;; Since we've encountered an error, don't add this opt acc)) opt @@ -462,14 +463,16 @@ (error-fn {:cause :restrict :msg (str "Unknown option: " k) :restrict restrict - :option k})))) + :option k + :opts opts})))) (when require (doseq [k require] (when-not (find opts k) (error-fn {:cause :require :msg (str "Required option: " k) :require require - :option k})))) + :option k + :opts opts})))) (when validate (doseq [[k vf] validate] (let [f (or (and @@ -487,7 +490,8 @@ :msg (ex-msg-fn {:option k :value v}) :validate validate :option k - :value v}))))))) + :value v + :opts opts}))))))) opts))) (defn parse-args diff --git a/test/babashka/cli_test.cljc b/test/babashka/cli_test.cljc index b9d0a39..67de968 100644 --- a/test/babashka/cli_test.cljc +++ b/test/babashka/cli_test.cljc @@ -63,7 +63,8 @@ :msg "Coerce failure: cannot transform input \"dude\" to long" :option :b :value "dude" - :spec nil} + :spec nil + :opts {}} (ex-data e))))) (is (submap? {:a [1 1]} (cli/parse-opts ["-a" "1" "-a" "1"] {:collect {:a []} :coerce {:a :long}}))) @@ -123,7 +124,8 @@ :msg "Unknown option: :b" :option :b :restrict #{:foo} - :spec {:foo {}}} + :spec {:foo {}} + :opts {:foo "bar", :b true}} (ex-data e)))))) (testing ":closed #{:foo} w/ only --foo in opts is allowed" (is (= {:foo "bar"} (cli/parse-opts ["--foo=bar"] @@ -142,7 +144,8 @@ :msg "Unknown option: :bar" :option :bar :restrict #{:foo} - :spec nil} + :spec nil + :opts {:foo true, :bar true}} (ex-data e)))))) (testing ":closed true w/ :aliases {:f :foo} w/ only -f in opts is allowed" (is (= {:foo true} (cli/parse-opts ["-f"] @@ -508,11 +511,12 @@ :spec nil :value 0 :validate {:foo {:pred pos? - :ex-msg ex-msg-fn}}} + :ex-msg ex-msg-fn}} + :opts {:foo 0}} (ex-data e))))))) (deftest error-fn-test - (let [errors (atom #{}) + (let [errors (atom []) spec {:a {:require true} :b {:validate pos?} :c {:coerce :long}}] @@ -522,31 +526,13 @@ {:error-fn (fn [error] (swap! errors conj error)) :restrict true :spec spec}) - (is (= #{{:type :org.babashka/cli - :cause :validate - :msg "Invalid value for option :b: 0" - :option :b - :value 0 - :validate {:b pos?} - :spec spec} - {:type :org.babashka/cli - :cause :coerce - :msg "Coerce failure: cannot transform input \"nope!\" to long" - :option :c - :value "nope!" - :spec spec} - {:type :org.babashka/cli - :cause :restrict - :msg "Unknown option: :extra" - :option :extra - :restrict #{:a :b :c} - :spec spec} - {:type :org.babashka/cli - :cause :require - :msg (str "Required option: :a") - :require #{:a} - :option :a - :spec spec}} + (is (= [{:spec spec, :type :org.babashka/cli, :cause :coerce, + :msg "Coerce failure: cannot transform input \"nope!\" to long", :option :c, + :value "nope!", :opts {:b 0}} + {:spec spec, :type :org.babashka/cli, :cause :restrict, :msg "Unknown option: :extra", :restrict #{:c :b :a}, :option :extra, :opts {:b 0, :extra "bad!"}} + {:spec spec, :type :org.babashka/cli, :cause :require, :msg "Required option: :a", :require #{:a}, :option :a, :opts {:b 0, :extra "bad!"}} + {:spec spec, :type :org.babashka/cli, :cause :validate, :msg "Invalid value for option :b: 0", :validate {:b pos?}, :option :b, :value 0, + :opts {:b 0, :extra "bad!"}}] @errors)))) (deftest exec-args-replaced-test