Skip to content

Commit c3ff1ff

Browse files
committed
refactor so optional args not just for :arg "bool"
- keep it backwards compatible - support flags with `:optional-arg?` and `:default` - needed to handle presence of [nil] in the flags get-flags-set :all couldn't used properly w/o handling this case new private `add-index` avoid this - add some useful supporting helpers
1 parent 10fdfa2 commit c3ff1ff

1 file changed

Lines changed: 50 additions & 9 deletions

File tree

src/main/clojure/cljs/cli.clj

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,8 @@ present"
560560
flag set (:init + :main)."
561561
[commands phase]
562562
(if (= :all phase)
563-
(into (get-options commands :main) (get-options commands :init))
563+
;; remove the nil opt, this is not a real flag
564+
(disj (into (get-options commands :main) (get-options commands :init)) nil)
564565
(-> (get commands (keyword (str (name phase) "-dispatch")))
565566
keys set)))
566567

@@ -570,6 +571,7 @@ present"
570571
(get-options commands phase))
571572

572573
(defn bool-init-options
574+
"Kept here only for backwards compatibility. See optional-arg-init-flags."
573575
[commands]
574576
(reduce
575577
(fn [ret [flags config]]
@@ -578,12 +580,34 @@ present"
578580
(into flags)))
579581
#{} (:init commands)))
580582

583+
(defn optional-arg-init-flags
584+
"Given commands, return all :init flags that are
585+
either :arg \"bool\" or declare :optional-args true
586+
as a set."
587+
[commands]
588+
(reduce
589+
(fn [ret [flags config]]
590+
(cond-> ret
591+
(or (= "bool" (:arg config))
592+
(:optional-arg? config))
593+
(into flags)))
594+
#{} (:init commands)))
595+
581596
(defn dispatch?
582597
"Given a commands map, a phase (:init or :main) and a command line flag,
583598
return true if the flag has a handler."
584599
[commands phase opt]
585600
(contains? (get-flags-set commands phase) opt))
586601

602+
(defn- add-index
603+
[commands]
604+
(assoc commands :index
605+
(reduce
606+
(fn [ret [flags config]]
607+
(merge ret (zipmap flags (repeat config))))
608+
;; the nil opt is not a real flag
609+
{} (dissoc (merge (:main commands) (:init commands)) [nil]))))
610+
587611
(defn add-commands
588612
"Given commands map (see below), create a commands map with :init-dispatch
589613
and :main-dispatch keys where short and long arguments are mapped individually
@@ -604,7 +628,8 @@ present"
604628
(update-in [:main] merge main)
605629
(update-in [:init] merge init)
606630
(merge-dispatch :init-dispatch init)
607-
(merge-dispatch :main-dispatch main)))))
631+
(merge-dispatch :main-dispatch main)
632+
add-index))))
608633

609634
(def ^{:doc "Default commands for ClojureScript REPLs. :groups are to support
610635
printing organized output for --help. a :main option must come at the end, they
@@ -695,6 +720,20 @@ generic - the combinations must be explicitly supported"}
695720
["-h" "--help" "-?"] {:fn help-opt
696721
:doc "Print this help message and exit"}}}))
697722

723+
(defn get-arg-default
724+
"Given commands and arg, return the :defaults value for that arg. The
725+
arg should either be a bool, or declare :optional-arg? in the config"
726+
[commands arg]
727+
(let [config (get-in commands [:index arg])]
728+
(if (= "bool" (:arg config))
729+
"true"
730+
(:default config))))
731+
732+
(defn flag?
733+
"Given commands and arg, checks to see if the arg is actually a known command flag."
734+
[commands arg]
735+
(contains? (get-flags-set commands :all) arg))
736+
698737
(defn normalize
699738
"Given a commands map (flag + value -> option processor fn) and the sequence of
700739
command line arguments passed to the process, normalize it. Boolean flags don't
@@ -703,16 +742,18 @@ generic - the combinations must be explicitly supported"}
703742
[commands args]
704743
(letfn [(normalize* [args*]
705744
(if (not (contains? (get-flags-set commands :main) (first args*)))
706-
(let [pred (complement (bool-init-options commands))
707-
[pre post] ((juxt #(take-while pred %)
708-
#(drop-while pred %))
709-
args*)]
745+
(let [not-optional-arg? (complement (optional-arg-init-flags commands))
746+
[pre post] ((juxt #(take-while not-optional-arg? %)
747+
#(drop-while not-optional-arg? %)) args*)]
710748
(cond
749+
;; nothing changed, done
711750
(= pre args*) pre
712751

713-
(not (#{"true" "false"} (fnext post)))
714-
(concat pre [(first post) "true"]
715-
(normalize commands (next post)))
752+
(flag? commands (fnext post))
753+
(let [flag (first post)
754+
flag+default [flag (get-arg-default commands flag)]]
755+
(concat pre flag+default
756+
(normalize commands (next post))))
716757

717758
:else
718759
(concat pre [(first post) (fnext post)]

0 commit comments

Comments
 (0)