diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ba9e03..7742390 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ For breaking changes, check [here](#breaking-changes). - Fix [#102](https://github.com/babashka/cli/issues/102): `format-table` correctly pads cells containing ANSI escape codes - Fix [#106](https://github.com/babashka/cli/issues/106): Multiple options before subcommand conflict with subcommand +- Fix [#104](https://github.com/babashka/cli/issues/104): Allow extra arguments to be passed before options in exec function ## v0.8.60 (2024-07-23) diff --git a/src/babashka/cli/exec.clj b/src/babashka/cli/exec.clj index 50c5267..99c4843 100644 --- a/src/babashka/cli/exec.clj +++ b/src/babashka/cli/exec.clj @@ -7,7 +7,6 @@ (set! *warn-on-reflection* true) -#_:clj-kondo/ignore (def ^:private ^:dynamic *basis* "For testing" nil) (defmacro ^:private req-resolve [f] @@ -54,16 +53,18 @@ (str/starts-with? f "{") [(edn/read-string f) cmds] :else [nil (cons f cmds)]) - f (case (count cmds) - 0 (resolve-exec-fn ns-default exec-fn) - 1 (let [f (first cmds)] - (if (str/includes? f "/") - (symbol f) - (resolve-exec-fn ns-default (symbol f)))) - 2 (let [[ns-default f] cmds] - (if (str/includes? f "/") - (symbol f) - (resolve-exec-fn (symbol ns-default) (symbol f))))) + [f unconsumed-args] (case (count cmds) + 0 [(resolve-exec-fn ns-default exec-fn)] + 1 [(let [f (first cmds)] + (if (str/includes? f "/") + (symbol f) + (resolve-exec-fn ns-default (symbol f))))] + (let [[ns-default f & unconsumed-args] cmds] + [(if (str/includes? f "/") + (symbol f) + (resolve-exec-fn (symbol ns-default) (symbol f))) + unconsumed-args])) + args (concat unconsumed-args args) f* f f (req-resolve f) _ (assert (ifn? f) (str "Could not resolve function: " f*)) diff --git a/test/babashka/cli/exec_test.clj b/test/babashka/cli/exec_test.clj index 5161033..52af6fa 100644 --- a/test/babashka/cli/exec_test.clj +++ b/test/babashka/cli/exec_test.clj @@ -20,6 +20,11 @@ (is (submap? {:a 1 :b 2} (main "babashka.cli.exec-test/foo" ":a" "1" ":b" "2"))) (is (submap? {:b 1} (main "babashka.cli.exec-test" "foo" ":b" "1"))) (is (submap? {:a 1 :b 2} (main "babashka.cli.exec-test" "foo" ":a" "1" ":b" "2"))) + (is (submap? {:args ["arg"] + :exec true} + (-> (main "babashka.cli.exec-test" "foo" "arg" ":a" "1" ":b" "2") + meta + :org.babashka/cli))) (is (submap? {:a 1 :b 2} (main "{:coerce {:a :long}}" "babashka.cli.exec-test" "foo" ":a" "1" ":b" "2"))) @@ -35,20 +40,20 @@ ":a" "1" ":b" "2")))) (is (submap? {:a 1 :b 2} (binding [babashka.cli.exec/*basis* '{:argmap {:org.babashka/cli {:coerce {:a :long}} - :exec-fn babashka.cli.exec-test/foo}}] + :exec-fn babashka.cli.exec-test/foo}}] (main ":a" "1" ":b" "2")))) (is (submap? {:a 1 :b 2} (binding [babashka.cli.exec/*basis* '{:argmap {:org.babashka/cli {:coerce {:a :long}} - :ns-default babashka.cli.exec-test}}] + :ns-default babashka.cli.exec-test}}] (main "foo" ":a" "1" ":b" "2")))) (is (submap? {:a 1 :b 2} (binding [babashka.cli.exec/*basis* '{:argmap {:org.babashka/cli {:coerce {:a :long}} - :ns-default babashka.cli.exec-test - :exec-fn foo}}] + :ns-default babashka.cli.exec-test + :exec-fn foo}}] (main ":a" "1" ":b" "2")))) (let [basis "{:argmap {:org.babashka/cli {:coerce {:a :long}} :ns-default babashka.cli.exec-test @@ -63,18 +68,20 @@ (edn/read-string (with-out-str (binding [babashka.cli.exec/*basis* '{:argmap {:org.babashka/cli {:coerce {:a :long}} - :ns-default babashka.cli.exec-test - :exec-fn foo}}] + :ns-default babashka.cli.exec-test + :exec-fn foo}}] (main "clojure.core/prn" ":a" "1" ":b" "2")))))) (is (submap? {:a 1 :b 2} (edn/read-string (with-out-str (binding [babashka.cli.exec/*basis* '{:argmap {:ns-default clojure.pprint - :exec-fn foo}}] + :exec-fn foo}}] (main "pprint" ":a" "1" ":b" "2")))))) (is (:exec (:org.babashka/cli (meta (binding [babashka.cli.exec/*basis* '{:argmap {:org.babashka/cli {:coerce {:a :long}} - :ns-default babashka.cli.exec-test - :exec-fn foo}}] - (main ":a" "1" ":b" "2"))))))) + :ns-default babashka.cli.exec-test + :exec-fn foo}}] + (main ":a" "1" ":b" "2")))))) + + )