docs(options): README tables reconciled + permanent option-docs check (item 6a)
All checks were successful
Check / eval (push) Successful in 2m59s
All checks were successful
Check / eval (push) Successful in 2m59s
Slice (a) of the docs review: 9 undocumented nomarchy.* options got README rows or inline .leaf mentions (autoTimezone, camera IR-hide, intel.guc, amd.pstate/vaapi, package, system.stateFile, restic.paths). The diff is now a flake check: option names are eval-walked from the four option-declaring modules (config halves stay lazy) and compared to the tables by tools/check-option-docs.py — undocumented options and stale table rows both fail. Negative-tested against the pre-fix README (reports exactly the 9 gaps). Item 6 split into slices a–d in BACKLOG. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
60
tools/check-option-docs.py
Normal file
60
tools/check-option-docs.py
Normal file
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Option-surface ↔ README drift check (flake check `option-docs`).
|
||||
|
||||
Usage: check-option-docs.py <option-surface.txt> <README.md>
|
||||
|
||||
<option-surface.txt> is one full option path per line (nomarchy.…),
|
||||
generated at eval time in flake.nix by walking the four option-declaring
|
||||
modules — so the "live surface" side can never go stale by itself.
|
||||
|
||||
Two directions:
|
||||
|
||||
1. Every live option must be documented in the README: either its full
|
||||
path appears verbatim (a table row), or — for sub-knobs that don't end
|
||||
in `.enable` — a backticked `.leaf` shorthand appears somewhere (the
|
||||
convention for tuning knobs documented inline in their parent row,
|
||||
e.g. nightlight's `.temperature`). `.enable` options always get their
|
||||
own row: the shorthand `` `.enable` `` would match any of them.
|
||||
|
||||
2. Every `nomarchy.*` path in a README option-table row (lines starting
|
||||
`| `nomarchy.`) must still exist — catches rows for renamed/removed
|
||||
options.
|
||||
"""
|
||||
|
||||
import re
|
||||
import sys
|
||||
|
||||
surface_file, readme_file = sys.argv[1], sys.argv[2]
|
||||
|
||||
surface = [l.strip() for l in open(surface_file) if l.strip()]
|
||||
readme = open(readme_file).read()
|
||||
|
||||
# Backticked `.leaf` shorthands present in the README (inline sub-knob docs).
|
||||
shorthands = set(re.findall(r"`(\.[A-Za-z][A-Za-z0-9]*)`", readme))
|
||||
|
||||
failures = []
|
||||
|
||||
for opt in surface:
|
||||
if opt in readme:
|
||||
continue
|
||||
leaf = "." + opt.rsplit(".", 1)[1]
|
||||
if leaf != ".enable" and leaf in shorthands:
|
||||
continue
|
||||
failures.append(
|
||||
f"undocumented option: {opt} — add a README table row"
|
||||
+ ("" if leaf == ".enable" else f" or an inline `{leaf}` mention")
|
||||
)
|
||||
|
||||
# Reverse: option paths claimed by table rows must exist.
|
||||
for line in readme.splitlines():
|
||||
m = re.match(r"\|\s*`(nomarchy\.[A-Za-z0-9.]+)`", line)
|
||||
if m and m.group(1) not in surface:
|
||||
failures.append(f"stale README table row: {m.group(1)} is not a live option")
|
||||
|
||||
if failures:
|
||||
print(f"option-docs: {len(failures)} problem(s)")
|
||||
for f in failures:
|
||||
print(" " + f)
|
||||
sys.exit(1)
|
||||
|
||||
print(f"option-docs: {len(surface)} options all documented, no stale rows")
|
||||
Reference in New Issue
Block a user