Skip to content

Commit

Permalink
docs: update flag syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
jdx committed Aug 28, 2024
1 parent 3a031ed commit a67de2e
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 54 deletions.
4 changes: 2 additions & 2 deletions docs/cli/scripts.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ single file. Here is an example in bash:

```bash
#!/usr/bin/env usage
flag "-f,--force" help="Overwrite existing <file>"
flag "-u,--user <user>" help="User to run as"
flag "-f --force" help="Overwrite existing <file>"
flag "-u --user <user>" help="User to run as"
arg "<file>" help="The file to write" default="file.txt"

#!/usr/bin/env bash
Expand Down
46 changes: 27 additions & 19 deletions docs/spec/index.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Usage Specification

Usage is a spec and CLI for defining CLI tools. Arguments, flags, environment variables, and config files
can all be defined in a Usage spec. It can be thought of like [OpenAPI (swagger)](https://www.openapis.org/)
Usage is a spec and CLI for defining CLI tools. Arguments, flags, environment variables, and config
files can all be defined in a Usage spec. It can be thought of like [OpenAPI (swagger)](https://www.openapis.org/)
for CLIs. Here are some potential reasons for defining your CLI with a Usage spec:

- Generate autocompletion scripts
Expand All @@ -13,7 +13,8 @@ for CLIs. Here are some potential reasons for defining your CLI with a Usage spe

## Example Usage Spec

Usage specs are written in [kdl](https://kdl.dev/) which is a newer document language that sort of combines
Usage specs are written in [kdl](https://kdl.dev/) which is a newer document language that sort of
combines
the best of XML and JSON. Here is a basic example CLI definition:

```sh
Expand All @@ -26,12 +27,12 @@ author "nobody" # the author of the CLI
license "MIT" # license the CLI is released under

# a standard flag
flag "-f,--force" help="Always do the thing"
flag "-v,--version" help="Print the CLI version"
flag "-h,--help" help="Print the CLI help"
flag "-f --force" help="Always do the thing"
flag "-v --version" help="Print the CLI version"
flag "-h --help" help="Print the CLI help"

# a flag that takes a value
flag "-u,--user <user>" help="User to run as"
flag "-u --user <user>" help="User to run as"

arg "<dir>" help="The directory to use" # required positional argument
arg "[file]" help="The file to read" # optional positional argument
Expand All @@ -40,9 +41,9 @@ arg "[file]" help="The file to read" # optional positional argument
And here is an example CLI with nested subcommands:

```sh
flag "-v,--verbose" "Enable verbose logging" global=true count=true
flag "-q,--quiet" "Enable quiet logging" global=true
flag "-u,--user <user>" help="User to run as"
flag "-v --verbose" "Enable verbose logging" global=true count=true
flag "-q --quiet" "Enable quiet logging" global=true
flag "-u --user <user>" help="User to run as"

cmd "update" help="Update the CLI"
cmd "config" help="Manage the CLI config" {
Expand All @@ -51,7 +52,7 @@ cmd "config" help="Manage the CLI config" {
alias "set"
arg "<key>" help="The key for the config"
arg "<value>" help="The new config value"
flag "-f,--force" help="Overwrite existing config"
flag "-f --force" help="Overwrite existing config"
}
cmd "remove" help="Remove a thing" {
alias "rm"
Expand All @@ -68,24 +69,31 @@ Flags/args can be backed by config files, environment variables, or defaults:

```sh
config_file ".mycli.toml" findup=true
flag "-u,--user <user>" help="User to run as" env="MYCLI_USER" config="settings.user" default="admin"
flag "-u --user <user>" help="User to run as" env="MYCLI_USER" config="settings.user" default="admin"
```

The priority over which is used (CLI flag, env var, config file, default) is the order which they are defined,
The priority over which is used (CLI flag, env var, config file, default) is the order which they
are defined,
so in this example it will be "CLI flag > env var > config file > default".

## Compatibility

Usage is not designed to model every possible CLI. It's generally designed for CLIs that follow standard GNU-style
options. While it is not high priority, adding support for CLIs that differ from the standard may be allowed.
As an example, some CLIs may accept multiple options on a flag: `--flag option1 option2`. This is poor design
as it's unclear to the user if "option2" is another positional arg or not. What we will likely do for behaviors
Usage is not designed to model every possible CLI. It's generally designed for CLIs that follow
standard GNU-style
options. While it is not high priority, adding support for CLIs that differ from the standard may be
allowed.
As an example, some CLIs may accept multiple options on a flag: `--flag option1 option2`. This is
poor design
as it's unclear to the user if "option2" is another positional arg or not. What we will likely do
for behaviors
like this is allow it, but show a warning that it is not recommended.

## CLI Framework Developers

You could think of Usage like an LSP (Language Server Protocol) for CLIs.

Those building CLI frameworks can really benefit from Usage. Rather than building features like autocompletion
for every shell, just output a Usage definition and use the Usage CLI to generate autocompletion scripts for all
Those building CLI frameworks can really benefit from Usage. Rather than building features like
autocompletion
for every shell, just output a Usage definition and use the Usage CLI to generate autocompletion
scripts for all
of the shells it supports.
6 changes: 3 additions & 3 deletions docs/spec/reference/flag.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
# `flag`

```sh
flag "-u,--user <user>" # one way to define a flag
flag "-u --user <user>" # one way to define a flag
flag "--user" { # another way to define the same flag
alias "-u"
arg "<user>"
}
flag "--user" { alias "-u" hide=true } # hide alias from docs and completions

flag "-f,--force" global=true # global can be set on any subcommand
flag "-f --force" global=true # global can be set on any subcommand
flag "--file <file>" default="file.txt" # default value for flag
flag "-v,--verbose" count=true # instead of true/false $usage_verbose is # of times
flag "-v --verbose" count=true # instead of true/false $usage_verbose is # of times
# flag was used (e.g. -vvv = 3)

flag "--color" negate="--no-color" default=true # $usage_color=true by default
Expand Down
63 changes: 33 additions & 30 deletions examples/docs/cli-reference/task/run.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,32 @@
# `mise task run`

* Aliases: `r`

#### Args

* `[TASK]` – Task to run
Can specify multiple tasks by separating with `:::`
e.g.: mise run task1 arg1 arg2 ::: task2 arg1 arg2
Can specify multiple tasks by separating with `:::`
e.g.: mise run task1 arg1 arg2 ::: task2 arg1 arg2
* `[ARGS]...` – Arguments to pass to the task. Use ":::" to separate tasks

#### Flags

* `-C,--cd <CD>` – Change to this directory before executing the command
* `-n,--dry-run` – Don't actually run the task(s), just print them in order of execution
* `-f,--force` – Force the task to run even if outputs are up to date
* `-p,--prefix` – Print stdout/stderr by line, prefixed with the task's label
Defaults to true if --jobs > 1
Configure with `task_output` config or `MISE_TASK_OUTPUT` env var
* `-i,--interleave` – Print directly to stdout/stderr instead of by line
Defaults to true if --jobs == 1
Configure with `task_output` config or `MISE_TASK_OUTPUT` env var
* `-t,--tool <TOOL@VERSION>` – Tool(s) to also add e.g.: node@20 python@3.10
* `-j,--jobs <JOBS>` – Number of tasks to run in parallel
[default: 4]
Configure with `jobs` config or `MISE_JOBS` env var
* `-r,--raw` – Read/write directly to stdin/stdout/stderr instead of by line
Configure with `raw` config or `MISE_RAW` env var
[experimental] Run a task
* `-C --cd <CD>` – Change to this directory before executing the command
* `-n --dry-run` – Don't actually run the task(s), just print them in order of execution
* `-f --force` – Force the task to run even if outputs are up to date
* `-p --prefix` – Print stdout/stderr by line, prefixed with the task's label
Defaults to true if --jobs > 1
Configure with `task_output` config or `MISE_TASK_OUTPUT` env var
* `-i --interleave` – Print directly to stdout/stderr instead of by line
Defaults to true if --jobs == 1
Configure with `task_output` config or `MISE_TASK_OUTPUT` env var
* `-t --tool <TOOL@VERSION>` – Tool(s) to also add e.g.: node@20 python@3.10
* `-j --jobs <JOBS>` – Number of tasks to run in parallel
[default: 4]
Configure with `jobs` config or `MISE_JOBS` env var
* `-r --raw` – Read/write directly to stdin/stdout/stderr instead of by line
Configure with `raw` config or `MISE_RAW` env var
[experimental] Run a task

This command will run a task, or multiple tasks in parallel.
Tasks may have dependencies on other tasks or on source files.
Expand All @@ -48,20 +50,21 @@ The name of the script will be the name of the task.
npm run build
EOF
$ mise run build

Examples:
$ mise run lint
Runs the "lint" task. This needs to either be defined in .mise.toml
or as a standalone script. See the project README for more information.
$ mise run lint
Runs the "lint" task. This needs to either be defined in .mise.toml
or as a standalone script. See the project README for more information.

$ mise run build --force
Forces the "build" task to run even if its sources are up-to-date.
$ mise run build --force
Forces the "build" task to run even if its sources are up-to-date.

$ mise run test --raw
Runs "test" with stdin/stdout/stderr all connected to the current terminal.
This forces `--jobs=1` to prevent interleaving of output.
$ mise run test --raw
Runs "test" with stdin/stdout/stderr all connected to the current terminal.
This forces `--jobs=1` to prevent interleaving of output.

$ mise run lint ::: test ::: check
Runs the "lint", "test", and "check" tasks in parallel.
$ mise run lint ::: test ::: check
Runs the "lint", "test", and "check" tasks in parallel.

$ mise task cmd1 arg1 arg2 ::: cmd2 arg1 arg2
Execute multiple tasks each with their own arguments.
$ mise task cmd1 arg1 arg2 ::: cmd2 arg1 arg2
Execute multiple tasks each with their own arguments.

0 comments on commit a67de2e

Please sign in to comment.