Jargon::CLI
A command-line parser driven by one or more schemas. A CLI is either flat
(a single schema) or in subcommand mode (a map of named subcommands,
each its own Schema or nested CLI). Build one with Jargon.cli/Jargon.new,
then parse arguments into a Result, json straight to validated data,
or run to also handle --help, completion, and error exits.
Constants
Alone on a command line, or after the subcommand, it reads options as
JSON from stdin (xerp mark -@ < options.json).
Constructors
Create a CLI from a JSON or YAML schema file. Auto-detects multi-doc format for subcommands.
Create a CLI from a JSON schema string. Auto-detects multi-doc format (relaxed JSONL) for subcommands.
Create a CLI from a YAML schema string. Auto-detects multi-doc format for subcommands.
Instance methods
Control whether a bare key=value token — no leading dashes — may
implicitly assign to a named property. On by default. When off, such a
token is never read as an assignment: it falls to positional capture if a
slot is open, otherwise it is an unexpected argument. Turn it off for
deterministic parsing with zero implicit-assignment magic, e.g. when
operands legitimately contain = (name=value pairs passed through to
another tool) and you never want one silently absorbed as a property.
Note that a positional slot already captures =-bearing operands
literally regardless of this setting; the switch only governs the
implicit-assignment fallback. It does not affect --flag=value, which is
standard long-option syntax and always honored. Applies to this CLI and
its directly attached Schema subcommands; a nested CLI keeps its own
setting. (A colon is never an assignment separator: key:value is always
an ordinary token.)
Generate a shell completion shim. By default it calls back into this
program; pass command: to point completion at a separate (e.g. lighter)
binary that answers the hidden __complete verb.
Register a dynamic completer for a field, identified by its dotted path:
the field name for a flat CLI, or subcommand.field (a.b.field when
nested). The block receives a Completion::Context and returns the
candidate strings. Raises if the path does not match a schema field, so
typos and renames fail fast.
Read config files ending in any of extensions with the block, which
turns a file's text into anything that can be written as JSON: a TOML
library's TOML.parse, say. An added format is looked for ahead of
YAML and JSON, and ahead of formats added after it, its extensions in
the order given, so where a directory has both app.toml and
app.yaml, app.toml takes precedence. Adding yaml, yml, or
json replaces that extension's parser, and it keeps its place.
cli.config_format("toml") { |text| TOML.parse(text) }
cli.config_format("yaml", "yml") { |text| YAML.parse(text) } # in place of Jargon's YAML reader
Returns the list of config paths load_config would search, given the
same project: setting.
Generate a shell completion shim. By default it calls back into this
program; pass command: to point completion at a separate (e.g. lighter)
binary that answers the hidden __complete verb.
If this invocation is a completion request (the hidden __complete
verb), print candidates and — unless exit_process: false — exit 0.
Returns true when it handled completion, false otherwise, so it can be
called early in a program (before heavy initialization) or as the whole
body of a dedicated completion helper binary. The developer never types
the verb itself; the generated shim supplies it.
Render help for a single subcommand. subcommand is space-separated for
nested commands (e.g. "remote add"). Raises ArgumentError for a
subcommand the CLI doesn't have, as validate does.
Render the program's help text: a command listing when subcommands are defined, an option listing for a flat CLI, or a bare usage line otherwise.
Parse and return just the data, raising ParseError on validation errors.
Use when you want the values directly and treat invalid input as fatal.
Load config from standard locations.
Supports YAML (.yaml, .yml) and JSON (.json) files, and any format
added with config_format, which is looked for ahead of them.
Paths searched (in order):
- ./.config/{program_name}.yaml/.yml/.json (project local, flat; project: true only)
- ./.config/{program_name}/config.yaml/.yml/.json (project local, directory; project: true only)
- $XDG_CONFIG_HOME/{program_name}.yaml/.yml/.json (user global, flat)
- $XDG_CONFIG_HOME/{program_name}/config.yaml/.yml/.json (user global, directory)
Project-local configs are read from the current directory, which may be one someone else controls (a freshly cloned repository), and they would take precedence over the user's own config. So they are off by default; pass project: true to opt in.
With merge: true (default), merges all configs found (project wins over user). With merge: false, returns first config found. Returns nil if no config file found.
:ditto: input supplies the stream read for the -@ (stdin JSON) form.
Parse arguments into a Result (parsed data plus any validation errors);
never raises on invalid input. defaults seeds values not given on the
command line (e.g. from a config file), below CLI args and env vars.
With subcommands, a mapping in defaults under a subcommand's name is
that subcommand's section, and any other key is global. A subcommand
takes the global keys it has an option for, then its section's keys
over them, every one of them. A nested CLI's section holds its own
subcommands' sections the same way.
Run the CLI with automatic --help, --completions, and error handling. Prints help/completions and exits 0, prints errors and exits 1, otherwise returns/yields result.
Load subcommand(s) from a file.
- Single-doc file: requires name, loads as single subcommand
- Multi-doc file without name: loads each doc as top-level subcommand
- Multi-doc file with name: loads docs as nested subcommands under name
Load subcommands from a multi-document file (no parent name). Each document must have a "name" field.
Set the JSON key that names the subcommand when parsing full JSON from
stdin (the -@ form). Defaults to "subcommand".
Validate data against a schema, returning any errors. If no schema is provided, uses the CLI's root schema. For subcommand validation, pass the subcommand name (space-separated for nested).
:ditto: Validate a previously parsed Result against its subcommand.