Documentation
¶
Overview ¶
Purpose: resolve each scanned invocation's command path against the
real cobra tree and check its flags against what that exact node accepts.
Inputs: the tree built by buildTree, plus invocations from scanFile. Outputs: one failure per flag the binary would reject, one skip per
command path that isn't part of the core binary at all (plugin-provided — must never fail the gate).
Constraints: an unresolved path token is treated as plugin-provided (skip,
never fail) whenever it occurs under a node that itself has subcommands — a "router". `region`/`alerts`/`dr` fail to resolve directly under root, which is exactly this case, but so does `nself service templates ...` or `nself plugin cdn ...`: `service` and `plugin` both have known children, and `templates`/`cdn` are not among them, so this may be a typo'd command path or a subcommand a plugin registers at runtime under that group — either way it cannot be resolved from the core binary alone, and checking flags against the router itself produced exactly the false positive this package's docs warned about (`--wildcard` living on `ssl setup`, not `ssl`, in reverse: a word that isn't a real child must not silently fall back to its parent's flag set). An unresolved token under a *leaf* node (no children at all, e.g. `init`) is instead treated as a positional argument — `nself init myproject --env prod` — and flags are checked against that leaf, since a leaf can never have a plugin-registered subcommand hiding under it.
Command flagaudit catches documented or scripted `nself ... --flag` invocations whose flag was never registered on the cobra command it names.
Purpose: PR #258 fixed `nself doctor --quick`: the flag was documented
in help_topics.go and relied on by scripts/golden-path.sh, but was never added to the doctor command's flag set, so every invocation died at the flag parser before RunE ran. That went unnoticed for over a month because nothing checked docs and scripts against the binary's actual flags. This tool is that check, run as a CI gate (see .github/workflows/doc-sync.yml).
Inputs: .github/wiki/*.md and scripts/**/*.sh (override with -wiki
and -scripts), scanned for `nself <path> --flag` text; the real cobra tree from cmd/commands.RootCmd for what those flags actually resolve to.
Outputs: exit 1 and one line per undocumented-vs-unregistered flag,
naming the flag, the offending file:line, and the resolved command, when any are found. Also prints, without failing, the set of top-level command words used in the wiki/scripts that the core binary does not register at all — these are plugin-provided (region, alerts, dr, ... per CLI-R11) and cannot be checked without the plugin installed.
Constraints: read-only. Never execs the built binary — flags are resolved
by importing cmd/commands and walking the same cobra registration `nself --help` would report, which also means this works in CI without a build step.
Purpose: find every `nself <command path> ... --flag` invocation
written in the wiki or in shell scripts, so audit.go can check each flag against what the binary actually registers.
Inputs: .github/wiki/*.md and scripts/**/*.sh. Outputs: one invocation per matched command line. Constraints: only scans code, never prose. Wiki prose talks *about* the
CLI in plain English ("nself was designed to...", "the build
nself downloads..."), and a bare word-boundary match on
"nself" over raw text drowns real invocations in hundreds of
false positives. So for .md files this only looks inside
fenced ```/~~~ code blocks and inline `single-backtick`
spans — the two places a wiki page ever shows a real command
— and skips prose between them entirely. For .sh files the
whole file is already code; only full-line `#` comments are
skipped. Within a code segment, "nself" still must be
followed by a space to match (so "nself.org" inside a code
block, e.g. a curl URL, is not mistaken for the command). A
real invocation nested inside another tool's example — e.g.
the `ssh host 'nself start --wait-healthy'` pattern used by
the soak scripts — is deliberately still caught: the
wrapping ssh/docker/curl command is irrelevant, the nested
nself command is exactly the kind of drift this gate exists
to catch. Flags are resolved from the deepest command-path
segment recognised before the first flag or unrecognised
token, so `nself ssl setup --wildcard` is checked against
`ssl setup`, not `ssl`.
Purpose: walk the real cobra command tree (the same registration the
shipped binary uses, via cmd/commands — no separate parser to drift) and record, for every command path, the full set of flags that would actually parse there.
Inputs: commands.RootCmd, after commands.ApplyCommandGroups(). Outputs: a map from command path ("nself ssl setup") to the flag names
valid on that exact invocation.
Constraints: tools/cmdinventory's committed JSON is generated at -depth 2,
so it does not carry flags for deeper subcommands (e.g. `nself ssl setup`). This walks the live tree to unlimited depth instead of reusing that JSON. A flag registered with PersistentFlags() on an ancestor is valid on every descendant (cobra's own inheritance, exposed by InheritedFlags()); a flag registered with Flags() only is local to that one node (LocalFlags()) — both are folded into one set per path so a flag is never wrongly flagged just because it lives on the parent rather than the leaf, or vice versa.