|
175 | 175 | "Expanded dispatch options into tool options, leveraging a cache." |
176 | 176 | [options] |
177 | 177 | (let [{:keys [cache-dir]} options |
178 | | - options' (select-keys options [:tool-name |
179 | | - :doc |
180 | | - :namespaces |
181 | | - :groups]) |
182 | | - cache-dir' (when cache-dir |
183 | | - (fs/expand-home cache-dir)) |
184 | | - digest (when cache-dir' |
185 | | - (cache/classpath-digest options')) |
186 | | - cached (when digest |
187 | | - (cache/read-from-cache cache-dir' digest)) |
188 | | - result (if cached |
189 | | - cached |
190 | | - (let [expanded (impl/expand-tool-options options')] |
| 178 | + ;; Only include the options that should be part of the digest. |
| 179 | + digest-options (select-keys options [:tool-name |
| 180 | + :doc |
| 181 | + :namespaces |
| 182 | + :groups |
| 183 | + :source-dirs]) |
| 184 | + cache-dir' (when cache-dir |
| 185 | + (fs/expand-home cache-dir)) |
| 186 | + digest (when cache-dir' |
| 187 | + (cache/classpath-digest digest-options)) |
| 188 | + cached (when digest |
| 189 | + (cache/read-from-cache cache-dir' digest)) |
| 190 | + result (if cached |
| 191 | + cached |
| 192 | + (let [expanded (impl/expand-tool-options options)] |
191 | 193 | (when cache-dir' |
192 | 194 | (cache/write-to-cache cache-dir' digest expanded)) |
193 | 195 | expanded))] |
|
271 | 273 | - :groups - map of group command (a string) to a group map |
272 | 274 | - :handler - function to handle tool-level options, defaults to [[default-tool-handler]] |
273 | 275 | - :cache-dir (optional, string) - directory to cache data in, or nil to disable cache |
| 276 | + - :transformer (optional, function) - transforms the root command map |
| 277 | + - :source-dirs (optional, seq of strings) - additional directories related to caching |
274 | 278 |
|
275 | 279 | The :tool-name option is only semi-optional; in a Babashka script, it will default |
276 | 280 | from the `babashka.file` system property, if any. An exception is thrown if :tool-name |
|
294 | 298 | be loaded. :cache-dir defaults to the value of the CLI_TOOLS_CACHE_DIR environment variable, or |
295 | 299 | to the default value `~/.cli-tools-cache`. If set to nil, then caching is disabled. |
296 | 300 |
|
| 301 | + The :source-dirs option is typically used with the :transformer option; the source directories are |
| 302 | + additional directories whose contents should be included by the cache digest (because the transformer |
| 303 | + reads files in those directories). |
| 304 | +
|
| 305 | + The transformer function is passed the dispatch options and the root commands map and returns |
| 306 | + an updated commands map; typically this involves identifying additional commands and adding them |
| 307 | + via [[inject-command]]. |
| 308 | +
|
297 | 309 | Returns nil." |
298 | 310 | [dispatch-options] |
299 | 311 | (let [options' (merge {:arguments *command-line-args*} |
|
496 | 508 | :value true} |
497 | 509 | {:label "no" |
498 | 510 | :value false}]) |
| 511 | + |
| 512 | +(defn selected-command |
| 513 | + "Returns a map defining the selected command. This will be nil until the end of |
| 514 | + dispatch (i.e., just before the command function is invoked). This can be used |
| 515 | + in the implementation of commands not defined by [[defcommand]]." |
| 516 | + {:added "0.16.0"} |
| 517 | + [] |
| 518 | + impl/*command-map*) |
| 519 | + |
| 520 | +(defn- inject |
| 521 | + [commands-map remaining-command-path path-to-here command-map] |
| 522 | + (let [command (first remaining-command-path) |
| 523 | + remaining' (next remaining-command-path) |
| 524 | + path' (conj path-to-here command)] |
| 525 | + (cond |
| 526 | + (nil? remaining') |
| 527 | + (assoc commands-map command command-map) |
| 528 | + |
| 529 | + (contains? commands-map command) |
| 530 | + (update-in commands-map [command :subs] |
| 531 | + inject remaining' path' command-map) |
| 532 | + |
| 533 | + :else |
| 534 | + (assoc commands-map command |
| 535 | + {:command-path path' |
| 536 | + :command command |
| 537 | + :subs (inject {} remaining' path' command-map)})))) |
| 538 | + |
| 539 | +(defn inject-command |
| 540 | + "Injects a new command into the command root; presumably one not defined via |
| 541 | + [[defcommand]]. |
| 542 | +
|
| 543 | + command-path - a seq of command name strings leading to the new command |
| 544 | + command-map - map that defines the command |
| 545 | +
|
| 546 | + The final term of the command path is the name of the command itself. |
| 547 | +
|
| 548 | + A command map has keys: |
| 549 | + - :fn (keyword, required) - identifies function to invoke |
| 550 | + - :doc (string, required) - long description of the command |
| 551 | + - :title (string, optional) - short description of the command |
| 552 | + " |
| 553 | + {:added "0.16.0"} |
| 554 | + [command-root command-path command-map] |
| 555 | + (let [command-map' (assoc command-map |
| 556 | + :command (last command-path) |
| 557 | + :command-path command-path)] |
| 558 | + (inject command-root command-path [] command-map'))) |
| 559 | + |
0 commit comments