The command line of headwater, declared once and derived.
What this replaced, and the contract that went with it
Until HW-DR-0033
the parse was a loop over std::env::args() in main, with thirty-three
arms that read a flag and twenty that read a verb. Every flag of the binary
was admitted before the verb was decided, so a flag belonging to another
verb was accepted and did nothing: headwater check --level L0 exited 0 and
wrote the report that headwater check writes. Two interface contracts and
spec 12 stated that as a promise.
The decision record withdraws it. A flag belongs to the verb that reads it,
and a verb refuses a flag it does not.
Why the types are a library and not a module of the binary
An integration test cannot reach an item of a [[bin]] target, which is why
tests/verbs.rs used to read main.rs as source text and scrape the
["word", …] patterns out of it. A scrape is a parser of Rust that nothing
holds, and it would go blind the moment the arms stopped being written by
hand. With the surface here, that test holds [command] against
[headwater_verbs::VERBS] in both directions, over the tree clap itself
builds.
Where the words come from, and what is deliberately absent
No about on a verb and no summary is written in this file. [command]
reads both off [headwater_verbs::VERBS] and puts them on the tree, because
a summary written here would be the fifth hand-kept copy of the verb list
that #257 was filed
about. The correspondence is by command line rather than by a name repeated
at each variant: [command] walks the table and calls mut_subcommand, so
a verb renamed in one place and not the other is a verb the walk in
tests/verbs.rs reports.
A flag is the other way round, and for the reason HW-DR-0033 gives. A
flag belongs to the verb that reads it, so its description is written at the
declaration of that flag, here. engine/crates/cli/tests/help.rs holds every
argument of every command in the tree to carrying one, which is what stops
the next flag arriving undescribed the way --facet, --tier, --arm,
--category and --seed did.
A global flag is described once and printed twice. [GLOBALS] carries a
one-line summary beside each description, and [first_screen] prints the
summaries rather than letting clap print the descriptions. The description
is the one clap propagates onto every verb page, so the long form is
reachable everywhere it was, and the screen a reader meets first is a list
rather than five paragraphs.
HW-DR-0042
rules that, and it rules out Arg::long_help as the way to do it: clap
renders long_help for --help and help for -h, so the two spellings
would stop printing the same text.
A /// comment on a derived item becomes help text. The commentary on
the types below is // for that reason, and the module documentation you
are reading is //!, which clap does not read either. A house-style doc
comment on a variant or a field would be printed to a caller.
Color is declared off. Nothing here emits an escape sequence, which is the
state the binary was already in and the state its recorded fixtures read.
--no-color is declared anyway, and it is declared as what it is: a caller
who writes it out of habit is answered rather than refused, and its help
says outright that this binary has no color to turn off. That is the
opposite of a flag whose name implies an effect it does not have.
The width is decided in [paint] and never by the terminal. Every string
below is folded before clap sees it, because clap cannot fold at all in
this workspace and the feature that would let it reads the terminal. So the
strings here are written as one long line each and reach a caller folded.