Skip to content

Commit

Permalink
Fix #66: dispatch improvements (#77)
Browse files Browse the repository at this point in the history
Co-authored-by: sohalt <sohalt@sohalt.net>
  • Loading branch information
borkdude and Sohalt authored Jan 4, 2024
1 parent 6b2f85c commit 712fee8
Show file tree
Hide file tree
Showing 10 changed files with 450 additions and 152 deletions.
26 changes: 26 additions & 0 deletions .clj-kondo/borkdude/deflet/borkdude/deflet.clj_kondo
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
(ns borkdude.deflet
(:require [clj-kondo.hooks-api :as hooks-api]))

(defn deflet* [children]
(let [f (first children)
r (next children)]
(if (and (hooks-api/list-node? f)
(#{'def 'defp} (hooks-api/sexpr (first (:children f)))))
(let [def-children (:children f)]
(with-meta (hooks-api/list-node
[(hooks-api/coerce 'clojure.core/let)
(hooks-api/vector-node [(second def-children)
(nth def-children 2)])
(deflet* r)])
(meta f)))
(if-not r (or f (hooks-api/coerce nil))
(with-meta
(hooks-api/list-node (list (hooks-api/coerce 'do)
f
(deflet* r)))
(meta f))))))

(defn deflet [{:keys [node]}]
(let [children (:children node)
new-node (deflet* children)]
{:node new-node}))
3 changes: 3 additions & 0 deletions .clj-kondo/borkdude/deflet/config.edn
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{:lint-as {borkdude.deflet/defp clojure.core/def}
:hooks {:analyze-call {borkdude.deflet/deflet borkdude.deflet/deflet
borkdude.deflet/defletp borkdude.deflet/deflet}}}
2 changes: 1 addition & 1 deletion .dir-locals.el
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
((clojure-mode
(cider-clojure-cli-aliases . ":repl")))
(cider-clojure-cli-aliases . ":repl:test")))
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ target
.clj-kondo/rewrite-clj
.clj-kondo/funcool
cljs-test-runner-out
src/scratch.clj
13 changes: 7 additions & 6 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,8 @@ Coerce string `s` using `f`. Does not coerce when `s` is not a string.

Subcommand dispatcher.

Dispatches on first matching command entry in `table`. A match is
determines by whether `:cmds`, a vector of strings, is a subsequence
(matching from the start) of the invoked commands.
Dispatches on longest matching command entry in `table` by matching
subcommands to the `:cmds` vector and invoking the correspondig `:fn`.

Table is in the form:

Expand All @@ -79,12 +78,14 @@ Subcommand dispatcher.
* `:args` - concatenation of unparsed commands and args
* `:rest-cmds`: DEPRECATED, this will be removed in a future version

This function does not throw. Use an empty `:cmds` vector to always match.
Use an empty `:cmds` vector to always match or to provide global options.

Provide an `:error-fn` to deal with non-matches.

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#L567-L611)</sub>
For more information and examples, see [README.md](README.md#subcommands).
<br><sub>[source](https://github.com/babashka/cli/blob/main/src/babashka/cli.cljc#L650-L682)</sub>
## `format-opts`
``` clojure

Expand Down
46 changes: 46 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,52 @@ Additional `parse-arg` options may be passed in each table entry:
{:cmds [] :fn help}])
```

Since cli 0.8.54 the order of `:cmds` in the table doesn't matter.

### Shared options

Since cli 0.8.54, babashka.cli supports parsing shared options in between and before the subcommands.

E.g.:

``` clojure
(def global-spec {:foo {:coerce :keyword}})
(def sub1-spec {:bar {:coerce :keyword}})
(def sub2-spec {:baz {:coerce :keyword}})

(def table
[{:cmds [] :spec global-spec}
{:cmds ["sub1"] :fn identity :spec sub1-spec}
{:cmds ["sub1" "sub2"] :fn identity :spec sub2-spec}])

(cli/dispatch table ["--foo" "a" "sub1" "--bar" "b" "sub2" "--baz" "c" "arg"])

;;=>

{:dispatch ["sub1" "sub2"],
:opts {:foo :a, :bar :b, :baz :c},
:args ["arg"]}
```

Note that specs are not merged, such that:

``` clojure
(cli/dispatch table ["sub1" "--foo" "bar"])
```

returns `{:dispatch ["sub1"], :opts {:foo "bar"}}` (`"bar"` is not coerced as a keyword).

Note that it is possible to use `:args->opts` but subcommands are always prioritized over arguments:

``` clojure
(def table
[{:cmds ["sub1"] :fn identity :spec sub1-spec :args->opts [:some-opt]}
{:cmds ["sub1" "sub2"] :fn identity :spec sub2-spec}])

(cli/dispatch table ["sub1" "dude"]) ;;=> {:dispatch ["sub1"], :opts {:some-opt "dude"}}
(cli/dispatch table ["sub1" "sub2"]) ;;=> {:dispatch ["sub1" "sub2"], :opts {}}
```

## Babashka tasks

For documentation on babashka tasks, go
Expand Down
2 changes: 1 addition & 1 deletion bb.edn
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
:task (apply clojure "-M:test" *command-line-args*)}

cljs-test {:doc "Run CLJS tests"
:task (apply clojure "-M:cljs-test" *command-line-args*)}
:task (apply clojure "-M:test:cljs-test" *command-line-args*)}

quickdoc {:doc "Invoke quickdoc"
:requires ([quickdoc.api :as api])
Expand Down
3 changes: 2 additions & 1 deletion deps.edn
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
{:extra-paths ["test"]
:extra-deps {io.github.cognitect-labs/test-runner
{:git/tag "v0.5.1" :git/sha "dfb30dd"}
babashka/fs {:mvn/version "0.1.11"}}
babashka/fs {:mvn/version "0.1.11"}
io.github.borkdude/deflet {:mvn/version "0.1.0"}}
:exec-args {:cmd "bb test"}
:main-opts ["-m" "babashka.cli.exec"]
:exec-fn babashka.test-runner/test #_cognitect.test-runner.api/test}
Expand Down
Loading

0 comments on commit 712fee8

Please sign in to comment.