diff --git a/CHANGELOG.md b/CHANGELOG.md index d32e62e..2b972e3 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! +## Unreleased + +- Populate `:msg` in the `:error-fn` data for `dispatch` command errors (`:no-match`, `:input-exhausted`), like option errors already carry it + ## 0.12.81 - Fix: a required `:inherit` option is no longer reported missing when supplied after its command diff --git a/src/babashka/cli.cljc b/src/babashka/cli.cljc index 30dc2ae..4b8bb1a 100644 --- a/src/babashka/cli.cljc +++ b/src/babashka/cli.cljc @@ -1956,6 +1956,15 @@ $env.config.completions.external.completer = {|spans| [{:keys [tree dispatch prog inherit]}] (println (format-command-help {:table tree :cmds (or dispatch []) :prog prog :inherit inherit}))) +(defn- dispatch-error-msg + "The terse one-line `:msg` for a command-level dispatch error, or nil for an + option error (whose `:msg` comes from the parser)." + [cause wrong-input] + (case cause + :no-match (str "Unknown command: " wrong-input) + :input-exhausted "No command given." + nil)) + (defn format-command-error "Render a terse, helpful message (a string) for a dispatch error. It is given the data `dispatch` passes to its `:error-fn`: @@ -1994,11 +2003,8 @@ $env.config.completions.external.completer = {|spans| [(str "Commands:\n" (format-table {:rows cmds :indent 2})) ""]) [hint]))))] (cond - (= :no-match cause) - (command-error (str "Unknown command: " wrong-input)) - - (= :input-exhausted cause) - (command-error "No command given.") + (or (= :no-match cause) (= :input-exhausted cause)) + (command-error (or msg (dispatch-error-msg cause wrong-input))) ;; genuine option error (restrict / require / validate / coerce): terse. ;; The lib message already names the option the user typed. @@ -2143,6 +2149,7 @@ $env.config.completions.external.completer = {|spans| (error-fn (thread-dispatch-context (merge {:type :org.babashka/cli :cause error + :msg (dispatch-error-msg error (:wrong-input res)) :all-commands available-commands :tree tree} (select-keys res [:wrong-input :opts :dispatch])) diff --git a/test/babashka/cli_test.cljc b/test/babashka/cli_test.cljc index 7188e99..1c36e2b 100644 --- a/test/babashka/cli_test.cljc +++ b/test/babashka/cli_test.cljc @@ -598,11 +598,11 @@ (-> (cli/dispatch table ["foo" "bar" "--version" "2000" "some-arg"]))))) - (testing "dispatch errors return :dispatch key" + (testing "dispatch errors return :dispatch key, and a :msg like option errors do" ;; submap?: dispatch also enriches error data with :tree (and :prog/:inherit when set) - (is (submap? {:type :org.babashka/cli, :dispatch ["foo" "bar"], :all-commands '("baz"), :cause :input-exhausted, :opts {}} + (is (submap? {:type :org.babashka/cli, :dispatch ["foo" "bar"], :all-commands '("baz"), :cause :input-exhausted, :msg "No command given.", :opts {}} (cli/dispatch [{:cmds ["foo" "bar" "baz"] :fn identity}] ["foo" "bar"] {:error-fn identity}))) - (is (submap? {:type :org.babashka/cli, :dispatch ["foo" "bar"], :wrong-input "wrong", :all-commands '("baz"), :cause :no-match, :opts {}} + (is (submap? {:type :org.babashka/cli, :dispatch ["foo" "bar"], :wrong-input "wrong", :all-commands '("baz"), :cause :no-match, :msg "Unknown command: wrong", :opts {}} (cli/dispatch [{:cmds ["foo" "bar" "baz"] :fn identity}] ["foo" "bar" "wrong"] {:error-fn identity}))))))) (deftest table->tree-test