Build command-line interfaces using typed spec definitions:
from cli.cli import run
from cli.model import CliArg, CliCommand, CliOption, CliSpec
import process
let args: List[CliArg] = [CliArg("name", True, False, "string")]
let opts: List[CliOption] = [CliOption("uppercase", "u", "Uppercase output", False, False, False, None, None, "string")]
let no_subs: List[CliCommand] = []
let no_aliases: List[Str] = []
let greet = CliCommand("greet", "Greet someone", None, no_aliases, args, opts, no_subs)
let cmds: List[CliCommand] = [greet]
let global: List[CliOption] = []
let examples: List[Str] = ["mytool greet Alice -u"]
let spec = CliSpec("mytool", "1.0.0", "A greeting tool", None, cmds, global, examples)
let m = run(spec, process.argv())
if m.command() == "greet" {
mut msg = "Hello, " + m.arg("name") + "!"
if m.flag("uppercase") {
msg = msg.upper()
}
print(msg)
}
Define your CLI structure with CliSpec, CliCommand, CliArg, and CliOption data types, then use run() or parse() to process arguments.
| Function | Returns | Description |
|---|---|---|
run(spec, argv) | CliMatch | Parse args, print errors and exit on failure |
parse(spec, argv) | Result[CliMatch, CliError] | Parse args, return Result for manual error handling |
parse_env(spec, argv, env) | Result[CliMatch, CliError] | Parse with env var fallback and defaults |
| Method | Returns | Description |
|---|---|---|
m.command() | Str? | Matched command name |
m.arg(name) | Str | Get positional argument (raises if missing) |
m.opt(name) | Str? | Get option value |
m.flag(name) | Bool | Check if flag is set |
m.has(name) | Bool | Check if any arg/opt/flag exists |
CliSpec(name, version?, summary?, description?, commands, global_options, examples) - top-level CLI definition.
CliCommand(name, summary?, description?, aliases, args, options, subcommands) - a command or subcommand.
CliArg(name, required, repeated, parser) - a positional argument.
CliOption(long, short?, summary?, takes_value, required, repeated, default_value?, env_var?, parser) - a named option or flag. Set takes_value to True for options that accept a value, False for boolean flags.
Set the parser field on CliArg or CliOption to validate values automatically:
| Parser | Description |
|---|---|
"string" | Accept any string (default) |
parser_int() | Parse integer |
parser_float() | Parse float |
parser_bool() | Parse boolean |
parser_one_of(["a", "b"]) | Restrict to allowed values |
parser_path_exists() | Validate path exists |
parser_file_exists() | Validate file exists |
parser_dir_exists() | Validate directory exists |
| Feature | Behavior |
|---|---|
-h / --help | Always recognized; prints structured help |
help <command> | Shows command-specific help |
| Unknown commands/options | Shows "Did you mean ...?" suggestions |
| Error handling | Exits code 2 with location and suggestion |
| Function | Returns | Description |
|---|---|---|
render_json_error(err) | Str | Stable JSON error for machine parsing |
render_json_help(spec, path) | Str | Stable JSON help for automation |
completion(spec, shell) | Str | Shell completion script (bash, zsh, fish) |
render_help(spec) | Str | Formatted help text |
The docopt-style parse_cli(spec_text) function is still available for simple use cases but the typed spec API above is preferred for new code.