docs(link): generate the CLI, configuration, and API references from … - #1416
Closed
evanorti wants to merge 8 commits into
Closed
docs(link): generate the CLI, configuration, and API references from …#1416evanorti wants to merge 8 commits into
evanorti wants to merge 8 commits into
Conversation
…source
The three reference pages under link/docs are derived from the code rather
than typed by hand, so they cannot drift from it. Tables live between
<!-- GEN:... --> markers and are written by link/docs/tools/refgen.py; the
prose around them is hand-written and never touched by the tool.
python3 link/docs/tools/refgen.py all --check # fails if a table moved
python3 link/docs/tools/refgen.py all # heals it
Sources: the config structs for configuration, the built binary's --help tree
for the CLI, and proto/link/*.proto for the API. Facts that live in neither a
struct nor a schema are read out of the code that enforces them: config
required-ness from the Validate methods, required flags from the
MarkFlagRequired calls in the command wiring.
The generator refuses to write rather than guess. A new command in no task
group, a new config key with no description, a region with no marker on its
page, a renamed default constant, or a flag documented nowhere all fail
loudly, because a table that silently omits something looks complete.
Two test suites: test-refgen.py covers the marker engine and the extraction,
and test-refgen-e2e.py mutates a copy of the source fifteen ways and asserts
what happens, including removals. Every "it fails loudly" claim above is one
of those cases.
The workflow runs check mode on any change under link/, proto/, or gen/. It
only reports; regenerating stays a human's command for now.
Comment on lines
+39
to
+71
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: "3.12" | ||
|
|
||
| # The CLI generator builds the binary, because Cobra computes a flag's | ||
| # default when the flag is registered, so --help is the honest source. | ||
| - uses: actions/setup-go@v5 | ||
| with: | ||
| # read from the module rather than pinned here, so a Go bump in | ||
| # link/go.mod does not silently break this job | ||
| go-version-file: link/go.mod | ||
|
|
||
| - name: Generator tests | ||
| run: python3 link/docs/tools/test-refgen.py | ||
|
|
||
| # Mutates a temp copy of the source and asserts that a stale page goes | ||
| # red and that each loud failure fires. Slower, because four cases | ||
| # rebuild the binary. | ||
| - name: The loop still fails when the source moves | ||
| run: python3 link/docs/tools/test-refgen-e2e.py | ||
|
|
||
| - name: Reference pages are current | ||
| run: python3 link/docs/tools/refgen.py all --check | ||
|
|
||
| # When the step above fails, the prose around those tables is suspect | ||
| # too. `--list-regions` names what moved, for the reference-drift pass. | ||
| - name: Name the stale regions | ||
| if: failure() | ||
| run: python3 link/docs/tools/refgen.py all --list-regions || true |
Region discovery no longer uses hardcoded lists. Config blocks are every struct reachable from Config, protos come from a walk of proto/, and a command group's flags are found rather than named, so a new block, file, or group cannot be silently absent from a page. Each hand-written key description now carries a fingerprint of the source it describes, so a key whose meaning changes under a stable name stops the generator instead of keeping a stale sentence. refgen.py all --plan reports every gap as JSON: stale regions, regions the page has nowhere to put with their tables already rendered, orphaned markers, and the choices only a person can make. link/docs/README.md says where to edit and what never to touch.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The three reference pages under link/docs are derived from the code rather than typed by hand, so they cannot drift from it. Tables live between markers and are written by link/docs/tools/refgen.py; the prose around them is hand-written and never touched by the tool.
Sources: the config structs for configuration, the built binary's --help tree for the CLI, and proto/link/*.proto for the API. Facts that live in neither a struct nor a schema are read out of the code that enforces them: config required-ness from the Validate methods, required flags from the MarkFlagRequired calls in the command wiring.
The generator refuses to write rather than guess. A new command in no task group, a new config key with no description, a region with no marker on its page, a renamed default constant, or a flag documented nowhere all fail loudly, because a table that silently omits something looks complete.
Two test suites: test-refgen.py covers the marker engine and the extraction, and test-refgen-e2e.py mutates a copy of the source fifteen ways and asserts what happens, including removals. Every "it fails loudly" claim above is one of those cases.
The workflow runs check mode on any change under link/, proto/, or gen/. It only reports; regenerating stays a human's command for now.