Open ieugen opened 2 years ago
I added this to test/cli_matic/presets_test.cljc
(comment
(test-string)
(use 'clojure.tools.trace)
(trace-ns cli-matic.core)
(trace-ns cli-matic.utils)
(trace-ns cli-matic.utils-v2)
(untrace-ns clojure.tools.cli)
(parse-cmds-simpler
["foo"]
(mkDummyCfg {:option "val" :as "x" :type :string :multiple true
:default ["a" "b" "c"]}))
(parse-cmds-simpler
["foo" "--val" "x" "--val" "y"]
(mkDummyCfg {:option "val" :as "x" :type :string :multiple true
:default ["a" "b" "c"]}))
)
And it seems the issue might be related to mk-cli-option
in src/cli_matic/utils.cljc
.
TRACE t10880: | | (cli-matic.core/parse-cmds-with-defaults [{:option "val", :as "x", :type :string, :multiple true, :default ["a" "b" "c"]}] [] false #function[cli-matic.platform/read-env])
TRACE t10881: | | | (cli-matic.utils/cm-opts->cli-opts [{:option "val", :as "x", :type :string, :multiple true, :default ["a" "b" "c"]}])
TRACE t10882: | | | | (cli-matic.utils/mk-cli-option {:option "val", :as "x", :type :string, :multiple true, :default ["a" "b" "c"]})
TRACE t10883: | | | | | (cli-matic.utils/asString "x")
TRACE t10883: | | | | | => "x"
TRACE t10884: | | | | | (cli-matic.utils/get-cli-option :string)
TRACE t10884: | | | | | => {:placeholder "S"}
TRACE t10885: | | | | | (cli-matic.utils/mk-short-opt nil)
TRACE t10885: | | | | | => nil
TRACE t10886: | | | | | (cli-matic.utils/mk-long-opt "val" "S" :string)
TRACE t10886: | | | | | => "--val S"
TRACE t10887: | | | | | (cli-matic.utils/mk-env-name "x" nil false)
TRACE t10887: | | | | | => "x"
TRACE t10882: | | | | => [nil "--val S" "x" :default "a" "b" "c" :assoc-fn #function[clojure.tools.trace/trace-var*/fn--8942/tracing-wrapper--8943]]
TRACE t10881: | | | => [[nil "--val S" "x" :default "a" "b" "c" :assoc-fn #function[clojure.tools.trace/trace-var*/fn--8942/tracing-wrapper--8943]] ["-?" "--help" "" :id :_help_trigger]]
TRACE t10880: | | => {:options {:val "a"}, :arguments [], :summary " --val S a x\n -?, --help", :errors nil}
The issue is with the use of flatten
call in the case of multiple
.
(defn mk-cli-option
"Builds a tools.cli option out of our own format.
If for-parsing is true, the option will be used for parsing;
if false, for generating help messages.
"
[{:keys [option short as type default multiple env]}]
(let [as_description (asString as)
preset (get-cli-option type)
placeholder (str (:placeholder preset)
(if (= :present default) "*" ""))
positional-opts [(mk-short-opt short)
(mk-long-opt option placeholder type)
(mk-env-name as_description env false)]
;; step 1 - remove :placeholder
opts-1 (dissoc preset :placeholder)
;; step 2 - add default if present and is not ":present"
opts-2 (if (and (some? default)
(not= :present default))
(assoc opts-1 :default default)
opts-1)
;; step 3 - if multivalue, add correct assoc-fns
opts-3 (if multiple
(assoc opts-2 :assoc-fn assoc-new-multivalue)
opts-2)]
(println "p-opts" positional-opts)
(println "1" opts-1)
(println "2" opts-2)
(println "3" opts-3)
(apply
conj positional-opts
(flatten (seq opts-3)))))
(comment
(use 'clojure.tools.cli)
(let [opt
(mk-cli-option
{:option "val", :as "x", :type :string, :multiple true, :default ["a" "b" "c"]})]
(println "optsss" opt)
(parse-opts [] [opt]))
)
Results;
p-opts [nil --val S x]
1 {}
2 {:default [a b c]}
3 {:default [a b c], :assoc-fn #function[cli-matic.utils/assoc-new-multivalue]}
optsss [nil --val S x :default a b c :assoc-fn #function[cli-matic.utils/assoc-new-multivalue]]
{:options {:val "a"}, :arguments [], :summary " --val S a x", :errors nil}
; Warning: The following options to parse-opts are unrecognized: b
The issue is with flatten.
Seems like the issue is with tools-cli or my understanding of how to use it.
Copied the example from the repo and added a value to :default
for -f
.
(def cli-options
[
["-f" "--file NAME" "File names to read"
:multi true ; use :update-fn to combine multiple instance of -f/--file
:default ["test"]
;; with :multi true, the :update-fn is passed both the existing parsed
;; value(s) and the new parsed value from each option
:update-fn conj]
])
(parse-opts args cli-options)
Parsing cli args using the above structure yields both default and the user supplied options.
clj -M -m cli.example -f csv
{:options {:file [test csv]}, :arguments [], :summary
-f, --file NAME ["test"] File names to read
:errors nil}
Problem
I tried to use a multiple with default value and I get an error.
Also the error message is not very helpful:
No value supplied for key: cli_matic.utils$assoc_new_multivalue@a520a55
Repro
Expected vs actual behavior
Version / Platform