Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ For breaking changes, check [here](#breaking-changes).

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

## Unreleased

- [#141](https://github.com/babashka/cli/issues/141): docs: briefly cover adding production polish to a cli
([@lread](https://github.com/lread))


## v0.8.67 (2025-11-21)

- [#126](https://github.com/babashka/cli/issues/126): `-` value accidentally parsed as option, e.g. `--file -`
Expand Down
41 changes: 24 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,14 @@ The main ideas:
- But with a better UX by not having to use quotes on the command line as a
result of having to pass EDN directly: `:dir foo` instead of `:dir '"foo"'` or
who knows how to write the latter in `cmd.exe` or Powershell.
- Open world assumption: passing extra arguments does not break and arguments
- By default, employ an open world assumption: passing extra arguments does not break and arguments
can be re-used in multiple contexts.
- But also support incremental validations as a form of polishing a cli for production use.

Both `:` and `--` are supported as the initial characters of a named option, but
cannot be mixed. See [options](https://github.com/babashka/cli#options) for more
details.
cannot be mixed. See [options](#options) for more details.

See [clojure CLI](https://github.com/babashka/cli#clojure-cli) for how to turn
your exec functions into CLIs.
See [clojure CLI](#clojure-cli) for how to turn your exec functions into CLIs.

## Projects using babashka CLI

Expand All @@ -67,13 +66,15 @@ your exec functions into CLIs.
- [Simple example](#simple-example)
- [Options](#options)
- [Arguments](#arguments)
- [Adding Production Polish](#adding-production-polish)
- [Subcommands](#subcommands)
- [Babashka tasks](#babashka-tasks)
- [Clojure CLI](#clojure-cli)
- [Leiningen](#leiningen)

## Simple example
Here is an example script to get you started!
Babashka cli works in Clojure, ClojureScript and [babashka](https://book.babashka.org/).
Here is an example babashka script to get you started!

```clojure
#!/usr/bin/env bb
Expand Down Expand Up @@ -134,12 +135,12 @@ Missing required argument: :num
--flag I am just a flag
```

Using the [`spec`](https://github.com/babashka/cli#spec) format is optional and you can implement you own parsing logic just with [`parse-opts`/`parse-args`](https://github.com/babashka/cli#options).
Using the [`spec`](#spec) format is optional and you can implement you own parsing logic just with [`parse-opts`/`parse-args`](#options).
However, many would find the above example familiar.

## Options

For parsing options, use either [`parse-opts`](https://github.com/babashka/cli/blob/main/API.md#parse-opts) or [`parse-args`](https://github.com/babashka/cli/blob/main/API.md#parse-args).
For parsing options, use either [`parse-opts`](/API.md#parse-opts) or [`parse-args`](/API.md#parse-args).

Examples:

Expand Down Expand Up @@ -225,7 +226,7 @@ Here's an example of parsing out `,` separated multi-arg-values:

Since `v0.3.35` babashka CLI auto-coerces values that have no explicit coercion
with
[`auto-coerce`](https://github.com/babashka/cli/blob/main/API.md#auto-coerce):
[`auto-coerce`](/API.md#auto-coerce):
it automatically tries to convert booleans, numbers and keywords.

## Arguments
Expand Down Expand Up @@ -283,6 +284,13 @@ and specify the variable number of arguments with `repeat`:
;;=> {:foo "arg1", :bar ["arg2" "arg3" "arg4"]}
```

## Adding Production Polish
Babashka cli lets you get up and running quickly.
As you move toward production quality, it’s helpful to let users know when their inputs are invalid.
Strict validation can be introduced with [:restrict](#restrict), [:require](#require), and [:validate](#validate).

As you add polish, you'll likely make use of a [:spec](#spec), a custom [:error_fn](#error-handling), and maybe [subcommand dispatching](#subcommands).

## Restrict

Use the `:restrict` option to restrict options to only those explicitly mentioned in configuration:
Expand Down Expand Up @@ -372,12 +380,10 @@ The following keys are present depending on `:cause`:
- `:cause :coerce`
- `:value` - the value of the option that failed coercion.

It is recommended to either throw an exception or otherwise exit in the error
handler function, unless you want to collect all of the errors and act on them
in the end (see `babashka.cli-test/error-fn-test` for an example of this).

For example:
By default, babashka cli will throw exception on errors it detects.
You can do the same from your custom error handler.

For a more polished user experience, you might choose to have your custom error handler print the error and exit. For example:
``` clojure
(cli/parse-opts
[]
Expand All @@ -396,14 +402,15 @@ For example:
(throw (ex-info msg data)))
(System/exit 1))})
```

would print:

```
Missing required argument:
--foo <val> You know what this is.
```

You can also choose collect and then report all detected errors (see `babashka.cli-test/error-fn-test` for an example of this).

## Spec

This library can work with partial information to parse options. As such, the
Expand Down Expand Up @@ -527,7 +534,7 @@ user=> (cli/parse-opts ["-vvv"] {:spec spec})
## Subcommands

To handle subcommands, use
[dispatch](https://github.com/babashka/cli/blob/main/API.md#dispatch).
[dispatch](/API.md#dispatch).

An example. Say we want to create a CLI that can be called as:

Expand Down Expand Up @@ -918,6 +925,6 @@ $ lein clj-new app --name foobar/baz --verbose 3 -f

## License

Copyright © 2022 Michiel Borkent
Copyright © 2022-2026 Michiel Borkent

Distributed under the MIT License. See LICENSE.
Loading