main.bend checks
raw source on the hub · import shake@0.5.0.0/main.bend as Main
shake: a proven command-line argument parser for Bend 2, with subcommands and help.
Describe a program with app, sub, flag, opt, many, pos and
rest, and give an argument an env var to fall back to with env; parse
binds argv against it (parse_env also takes the values of the env vars,
which env_vars reads), and
the result is read one command at a time, as clap's: get, get_all and
on read a command's own bindings, and sub_name, sub_of, at and
path_of reach the subcommands selected under it. help writes the usage
page for a command path. For a failed parse, help_path tells a request for help
from an error, err_text writes the message and err_path names the command
it failed in, and suggestion the long spelling a mistyped one was likely
meant to be. check reports a spec that contradicts itself. argv is the
process's arguments. This file is the interface: everything under src/ is
internal.
4 imports
import Base import ./src/cli.bend as S import ./src/args.bend as Args import ./src/check.bend as K
Definitions
def Cli source · line 22 · raw
Data
a program spec
def Sub source · line 26 · raw
Data
a nested command
def Arg source · line 30 · raw
Data
one argument: a flag, an option, a positional or a rest positional
def Matched source · line 35 · raw
Data
a successful parse, one command at a time: the bindings the command made, and the subcommand selected under it with its own Matched
def Var source · line 40 · raw
Data
an env var's name and its value, a pair (name, value): parse_env takes a
list of them, and env_vars reads one for each env var that is set
def ParseErr source · line 44 · raw
Data
a failed parse
def SpecErr source · line 48 · raw
Data
one way a spec contradicts itself
def app source · line 52 · raw
@+name:String -> @+about:String -> @version:Maybe<&2, String> -> @args:List<&2, 0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Arg> -> @subs:List<&2, 0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Sub> -> 0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Cli
a program: name, about, optional version, top-level args and commands
def sub source · line 62 · raw
@+name:String -> @+about:String -> @args:List<&2, 0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Arg> -> @subs:List<&2, 0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Sub> -> 0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Sub
a nested command
def flag source · line 71 · raw
@+name:String -> @short:Maybe<&2, String> -> @long:Maybe<&2, String> -> @+help:String -> 0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Arg
a boolean flag
def opt source · line 80 · raw
@+name:String -> @short:Maybe<&2, String> -> @long:Maybe<&2, String> -> @+help:String -> @required:Bool -> @default:Maybe<&2, String> -> @choices:List<&2, String> -> 0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Arg
a valued option
def many source · line 93 · raw
@+name:String -> @short:Maybe<&2, String> -> @long:Maybe<&2, String> -> @+help:String -> @required:Bool -> @default:Maybe<&2, String> -> @choices:List<&2, String> -> 0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Arg
an option that may be given more than once; get_all reads every value, in
order, and get the last
def pos source · line 105 · raw
@+name:String -> @+help:String -> @required:Bool -> @default:Maybe<&2, String> -> @choices:List<&2, String> -> 0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Arg
a positional
def rest source · line 115 · raw
@+name:String -> @+help:String -> @required:Bool -> @default:Maybe<&2, String> -> @choices:List<&2, String> -> 0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Arg
a rest positional: every leftover word, as one name
def env source · line 127 · raw
@arg:0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Arg -> @+var:String -> 0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Arg
this argument, falling back to the env var var when the words leave it
unbound, before its default, as clap's .env(var): parse_env reads it,
and help shows [env: VAR]
def check source · line 135 · raw
@spec:0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Cli -> List<&2, 0x1b64bb5828eb2210a4a61a1ba480631a/src/check.SpecErr>
every way a spec contradicts itself: a rest positional that is not the
last, a repeated argument name or spelling, a repeated subcommand name, a
subcommand named help, a default outside its choices, a required
positional after an optional one. Empty for a well-formed spec, which is
what SPEC.md's parse guarantees are about; parse does not call it
def spec_err_text source · line 139 · raw
@err:0x1b64bb5828eb2210a4a61a1ba480631a/src/check.SpecErr -> String
a report of check as one line
def parse source · line 143 · raw
@spec:0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Cli -> @words:List<&2, String> -> Result<&2, &2, 0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.ParseErr, 0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Matched>
argv against a program spec
def parse_env source · line 149 · raw
@+spec:0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Cli -> @words:List<&2, String> -> @+vars:List<&2, 0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Var> -> Result<&2, &2, 0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.ParseErr, 0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Matched>
argv against a program spec, with vars, name and value pairs, for the env
vars: an argument the words leave unbound falls back to its env var's value
when it is set and not empty, then to its default
def get source · line 157 · raw
@found:0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Matched -> @+name:String -> Maybe<&2, String>
the value this command bound to name last, or None when it bound none
def get_all source · line 161 · raw
@found:0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Matched -> @+name:String -> List<&2, String>
every value this command bound to name, in argv order
def on source · line 165 · raw
@found:0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Matched -> @+name:String -> Bool
whether this command's flag named name was set
def path_of source · line 170 · raw
@found:0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Matched -> List<&2, String>
the names of the subcommands selected below this command, in order: the
whole selected path for the Matched parse answers
def sub_name source · line 174 · raw
@found:0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Matched -> Maybe<&2, String>
the name of the subcommand selected under this command, or None
def sub_of source · line 178 · raw
@found:0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Matched -> @+name:String -> Maybe<&2, 0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Matched>
the Matched of subcommand name when it is the one selected, else None
def at source · line 183 · raw
@found:0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Matched -> @path:List<&2, String> -> Maybe<&2, 0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Matched>
the Matched of the command path names below this one, following sub_of
name by name, or None where a name is not the one selected
def help source · line 188 · raw
@+spec:0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Cli -> @path:List<&2, String> -> String
the usage page for path under spec; an unknown name in the path is
skipped
def err_text source · line 193 · raw
@+spec:0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Cli -> @err:0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.ParseErr -> String
the message for a failed parse, ending with the root usage line; empty for
a request for help, which the caller answers with help
def suggestion source · line 199 · raw
@+spec:0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Cli -> @err:0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.ParseErr -> Maybe<&2, String>
for an unknown long option, the long option word of the current command it
was likely meant to be, as --name for --nmae, which err_text shows as
clap's tip; None for every other error and when nothing is close
def err_path source · line 204 · raw
@err:0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.ParseErr -> List<&2, String>
the command path where the parse failed: the path selected when it did, or for a request for help the path it asks about
def help_path source · line 224 · raw
@err:0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.ParseErr -> Maybe<&2, List<&2, String>>
the command path of a request for help (help, help <path>, --help),
or None
when the parse failed for another reason
def env_vars source · line 243 · raw
@spec:0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Cli -> IO(List<&2, 0x1b64bb5828eb2210a4a61a1ba480631a/src/cli.Var>)
the env vars spec gives its arguments, each that is set with its value,
for parse_env
def argv source · line 251 · raw
IO(List<&2, String>)
the process's arguments, each word reusable, without the program name
that IO.args starts with (bend 2.0.32 and later). A compiled program's
runtime has already acted on --bend-help, --gpu-build, --threads N
and --gpu X and taken the first --, passing every word after it here
unexamined; so the -- that parse sees is the user's second one