Skip to main content

24  cli standard library

The cli module provides declarative, type-safe command-line parsing for options (cli::opt), named positional arguments (cli::pos), and recursive subcommands (cli::cmd), with automatic --help/-h and --version/-v generation, automatic --no-<long> negation for boolean flags, mandatory argument enforcement, and custom validator lambdas.

#use cli
#use io

opts = cli::Opts(
   cli::opt("p:port", 8080, "Port to listen on", p => p ![1...65535] | <- "port must be 1..65535" ->),
   cli::opt("v:verbose", <->, "Enable verbose output"),
   cli::opt("H:host", "127.0.0.1", "Bind address"),
   cli::pos("action", "status", "Action to run")
)

res = cli::parse_args(opts, cli::Args("-p", "9000", "--verbose", "serve"))
res
   | p =>
      io::out $ cli::int(p, "port")
      io::out $ cli::flag(p, "verbose")
      io::out $ cli::str(p, "host")
      io::out $ cli::str(p, "action")
   | err =>
      io::out $ err

24.1 Specification builders: cli::opt, cli::pos, and cli::cmd

All items in cli::Opts(...) have type Opt:

  • cli::opt(spec, default_or_type, description[, validator]):
    • spec (String): "s:long" for both short (-s) and long (--long), "long" for long-only, or "s:" for short-only.
    • default_or_type:
      • Passing a default value (<-> / <+>, Int, Float, String, or String{}) sets both the option’s type and its default value.
      • Passing a type token (Int, Float, or String) marks the option as mandatory (missing mandatory options fail validation).
      • Boolean flags (<>) automatically accept --no-<long> to negate the flag.
      • String{} (cli::Args) options are repeatable (-I a -I b accumulates all values).
    • description (String): Help text displayed in -h / --help.
    • validator (optional lambda): T => < | String > returning <- "error message" -> when invalid.
  • cli::pos(name, default_or_type[, description[, validator]]):
    • Declares a named positional argument in order of appearance:
      • Required <name>: cli::pos("input", String, "Input file")
      • Optional [name]: cli::pos("dir", ".", "Target directory")
      • Optional variadic [name...]: cli::pos("files", cli::Args(), "Source files")
      • Required variadic <name...>: cli::pos("files...", String, "Source files")
    • Queried by name with the same accessors (cli::str, cli::int, cli::float, cli::strs, cli::has, cli::into) as cli::opt.
  • cli::cmd(spec, description[, sub_opts]):
    • Declares a subcommand with optional |-separated aliases (e.g. "rm|remove", "tree|graph") and optional nested cli::Opts(...).
    • cli::subcmd(p) always returns the primary (first) name in spec.

24.2 Function catalog

Category Function Signature Description
Declaration cli::opt(spec, def_or_ty, desc[, validator]) Polymorphic => Opt Declares a flag or option (-s, --long) with default or mandatory type and optional validator
cli::pos(name, def_or_ty[, desc[, validator]]) Polymorphic => Opt Declares a named positional argument (<name>, [name], [name...], <name...>)
cli::cmd(spec, desc[, sub_opts]) Polymorphic => Opt Declares a subcommand (with optional | aliases and nested Opts)
cli::opts_for(T) #! T: Type => Opts Generates Opts automatically from record T’s fields, types, and default values
Parsing cli::parse(opts[, desc[, version[, empty_is_help]]]) Opts, ... => Parsed Parses sys::argv, handles --help/--version (including scoped <subcmd> --help), and exits 1 on error
cli::parse_args(opts, argv) Opts, Args => < Parsed | String > Parses an explicit Args array without exiting
cli::into(T, p) #! T: Type, Parsed => < T | String > Materializes a Parsed result directly into record T (resolving both opt and pos names)
cli::parse_into(opts, argv) #! T: Type, Opts, Args => < T | String > Parses argv against opts (or opts_for(T)) and populates record T
cli::format_help(opts, prog, desc, version) Opts, String, String, String => String Formats aligned Usage:, Commands:, Arguments:, and Options: help sections
Querying Parsed cli::subcmd(p) Parsed => String Canonical name of the matched subcommand at level p (or "" if none)
cli::sub(p) Parsed => < Parsed | > Returns <+ sub_parsed +> for nested subcommand trees, or <-->
cli::has(p, name) Parsed, String => <> <+> if option or positional name was explicitly passed on the command line
cli::flag(p, name) Parsed, String => <> Effective boolean flag value for name (reflecting default, --flag, or --no-flag)
cli::int(p, name) Parsed, String => Int Returns Int option or positional value for name
cli::float(p, name) Parsed, String => Float Returns Float option or positional value for name
cli::str(p, name) Parsed, String => String Returns String option or positional value for name
cli::strs(p, name) Parsed, String => Args Returns accumulated String{} values for repeatable option or variadic positional name
cli::rest(p) Parsed => Args Returns positional arguments collected at the active command level
cli::passthrough(p) Parsed => Args Returns pass-through arguments appearing after --
Raw argv Helpers cli::count() () => Int Number of raw command-line arguments (sys::argc)
cli::program() () => String Program name (argv[0])
cli::arg(idx) Int => < String | > Argument at idx (0-based)
cli::arg_or(idx, fallback) Int, String => String Argument at idx or fallback
cli::args() () => Args All arguments after argv[0]