Skip to content

Commit

Permalink
Fix exec args priority (#74)
Browse files Browse the repository at this point in the history
  • Loading branch information
borkdude authored Nov 14, 2023
1 parent 6291140 commit ce3410f
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 31 deletions.
58 changes: 47 additions & 11 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,18 @@
- [`coerce`](#coerce) - Coerce string <code>s</code> using <code>f</code>
- [`dispatch`](#dispatch) - Subcommand dispatcher.
- [`format-opts`](#format-opts)
- [`format-table`](#format-table)
- [`merge-opts`](#merge-opts) - Merges babashka CLI options.
- [`number-char?`](#number-char?)
- [`opts->table`](#opts->table)
- [`pad`](#pad)
- [`pad-cells`](#pad-cells)
- [`parse-args`](#parse-args) - Same as <code>parse-opts</code> but separates parsed opts into <code>:opts</code> and adds
- [`parse-cmds`](#parse-cmds) - Parses sub-commands (arguments not starting with an option prefix) and returns a
- [`parse-keyword`](#parse-keyword) - Parse keyword from <code>s</code>
- [`parse-opts`](#parse-opts) - Parse the command line arguments <code>args</code>, a seq of strings.
- [`spec->opts`](#spec-opts) - Converts spec into opts format.
- [`rows`](#rows)
- [`spec->opts`](#spec->opts) - Converts spec into opts format
- [`babashka.cli.exec`](#babashkacliexec)
- [`-main`](#-main) - Main entrypoint for command line usage.
- [`main`](#main)
Expand Down Expand Up @@ -79,14 +84,21 @@ Subcommand dispatcher.
Each entry in the table may have additional [`parse-args`](#parse-args) options.

Examples: see [README.md](README.md#subcommands).
<br><sub>[source](https://github.com/babashka/cli/blob/main/src/babashka/cli.cljc#L544-L588)</sub>
<br><sub>[source](https://github.com/babashka/cli/blob/main/src/babashka/cli.cljc#L567-L611)</sub>
## `format-opts`
``` clojure

(format-opts {:keys [spec indent order header], :or {indent 2}})
(format-opts {:as cfg, :keys [indent], :or {indent 2}})
```

<sub>[source](https://github.com/babashka/cli/blob/main/src/babashka/cli.cljc#L504-L569)</sub>
<sub>[source](https://github.com/babashka/cli/blob/main/src/babashka/cli.cljc#L556-L560)</sub>
## `format-table`
``` clojure

(format-table {:keys [rows indent]})
```

<sub>[source](https://github.com/babashka/cli/blob/main/src/babashka/cli.cljc#L516-L527)</sub>
## `merge-opts`
``` clojure

Expand All @@ -103,6 +115,27 @@ Merges babashka CLI options.
```

<sub>[source](https://github.com/babashka/cli/blob/main/src/babashka/cli.cljc#L53-L55)</sub>
## `opts->table`
``` clojure

(opts->table {:keys [spec order]})
```

<sub>[source](https://github.com/babashka/cli/blob/main/src/babashka/cli.cljc#L537-L554)</sub>
## `pad`
``` clojure

(pad len s)
```

<sub>[source](https://github.com/babashka/cli/blob/main/src/babashka/cli.cljc#L506-L506)</sub>
## `pad-cells`
``` clojure

(pad-cells rows)
```

<sub>[source](https://github.com/babashka/cli/blob/main/src/babashka/cli.cljc#L508-L514)</sub>
## `parse-args`
``` clojure

Expand All @@ -113,7 +146,7 @@ Merges babashka CLI options.

Same as [`parse-opts`](#parse-opts) but separates parsed opts into `:opts` and adds
`:cmds` and `:rest-args` on the top level instead of metadata.
<br><sub>[source](https://github.com/babashka/cli/blob/main/src/babashka/cli.cljc#L459-L466)</sub>
<br><sub>[source](https://github.com/babashka/cli/blob/main/src/babashka/cli.cljc#L484-L491)</sub>
## `parse-cmds`
``` clojure

Expand All @@ -125,7 +158,7 @@ Same as [`parse-opts`](#parse-opts) but separates parsed opts into `:opts` and a
Parses sub-commands (arguments not starting with an option prefix) and returns a map with:
* `:cmds` - The parsed subcommands
* `:args` - The remaining (unparsed) arguments
<br><sub>[source](https://github.com/babashka/cli/blob/main/src/babashka/cli.cljc#L203-L213)</sub>
<br><sub>[source](https://github.com/babashka/cli/blob/main/src/babashka/cli.cljc#L205-L215)</sub>
## `parse-keyword`
``` clojure

Expand Down Expand Up @@ -173,16 +206,19 @@ Parse the command line arguments `args`, a seq of strings.
;; => throws 'Unknown option --qux' exception b/c there is no :qux key in the spec
```

<br><sub>[source](https://github.com/babashka/cli/blob/main/src/babashka/cli.cljc#L250-L457)</sub>
<br><sub>[source](https://github.com/babashka/cli/blob/main/src/babashka/cli.cljc#L257-L482)</sub>
## `rows`
<sub>[source](https://github.com/babashka/cli/blob/main/src/babashka/cli.cljc#L530-L532)</sub>
## `spec->opts`
``` clojure

(spec->opts spec)
(spec->opts spec {:keys [exec-args]})
```


Converts spec into opts format.
<br><sub>[source](https://github.com/babashka/cli/blob/main/src/babashka/cli.cljc#L184-L201)</sub>
Converts spec into opts format. Pass existing opts as optional second argument.
<br><sub>[source](https://github.com/babashka/cli/blob/main/src/babashka/cli.cljc#L184-L203)</sub>
# babashka.cli.exec


Expand All @@ -207,11 +243,11 @@ Main entrypoint for command line usage.
clojure -M:exec clojure.core prn :a 1 :b 2
;;=> {:a "1" :b "2"}
```
<br><sub>[source](https://github.com/babashka/cli/blob/main/src/babashka/cli/exec.clj#L67-L81)</sub>
<br><sub>[source](https://github.com/babashka/cli/blob/main/src/babashka/cli/exec.clj#L88-L101)</sub>
## `main`
``` clojure

(main & args)
```

<sub>[source](https://github.com/babashka/cli/blob/main/src/babashka/cli/exec.clj#L63-L65)</sub>
<sub>[source](https://github.com/babashka/cli/blob/main/src/babashka/cli/exec.clj#L83-L86)</sub>
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ For breaking changes, check [here](#breaking-changes).

[Babashka CLI](https://github.com/babashka/cli): turn Clojure functions into CLIs!

## Unreleased (2023-11-14)

- Prioritize `:exec-args` over spec `:default`s

## v0.7.53 (2023-09-28)

- [#72](https://github.com/babashka/cli/issues/72): add possibility to add a header to format-opts ([@Sohalt](https://github.com/Sohalt))
Expand Down
38 changes: 20 additions & 18 deletions src/babashka/cli.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -182,23 +182,25 @@
(assoc acc current-opt arg))))

(defn spec->opts
"Converts spec into opts format."
[spec]
(reduce
(fn [acc [k {:keys [coerce alias default require validate]}]]
(cond-> acc
coerce (update :coerce assoc k coerce)
alias (update :alias
(fn [aliases]
(when (contains? aliases alias)
(throw (ex-info (str "Conflicting alias " alias " between " (get aliases alias) " and " k)
{:alias alias})))
(assoc aliases alias k)))
require (update :require (fnil #(conj % k) #{}))
validate (update :validate assoc k validate)
default (update :exec-args assoc k default)))
{}
spec))
"Converts spec into opts format. Pass existing opts as optional second argument."
([spec] (spec->opts spec nil))
([spec {:keys [exec-args]}]
(reduce
(fn [acc [k {:keys [coerce alias default require validate]}]]
(cond-> acc
coerce (update :coerce assoc k coerce)
alias (update :alias
(fn [aliases]
(when (contains? aliases alias)
(throw (ex-info (str "Conflicting alias " alias " between " (get aliases alias) " and " k)
{:alias alias})))
(assoc aliases alias k)))
require (update :require (fnil #(conj % k) #{}))
validate (update :validate assoc k validate)
default (update :exec-args (fn [new-exec-args]
(assoc new-exec-args k (get exec-args k default))))))
{}
spec)))

(defn parse-cmds
"Parses sub-commands (arguments not starting with an option prefix) and returns a map with:
Expand Down Expand Up @@ -289,7 +291,7 @@
opts (if spec
(merge-opts
opts
(spec->opts spec))
(spec->opts spec opts))
opts)
coerce-opts (:coerce opts)
aliases (or
Expand Down
9 changes: 7 additions & 2 deletions test/babashka/cli_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@
:to :keyword, :paths []},
:alias {:i :from, :o :to, :p :pretty},
:exec-args {:from :edn, :to :json, :paths ["src" "test"]}}
(cli/spec->opts spec)))
(cli/spec->opts spec nil)))
(is (= (str/trim "
-p, --pretty Pretty-print output.
--paths src test Paths of files to transform.
Expand All @@ -214,7 +214,12 @@
(is (submap?
#:deps{:root "the-root"}
(cli/parse-opts ["--deps/root" "the-root"]
{:spec [[:deps/root {:desc "The root"}]]})))))
{:spec [[:deps/root {:desc "The root"}]]})))
(testing "exec-args wins over spec"
(is (= 2 (:foo (cli/parse-opts [] {:spec {:foo {:default 1}}
:exec-args {:foo 2}}))))
(is (nil? (:foo (cli/parse-opts [] {:spec {:foo {:default 1}}
:exec-args {:foo nil}})))))))

(deftest args-test
(is (submap? {:foo true} (cli/parse-opts ["--foo" "--"])))
Expand Down

0 comments on commit ce3410f

Please sign in to comment.