Files
Nomarchy/tools/check-option-docs.py
Bernardo Magri 56f1cc3fa9
All checks were successful
Check / eval (push) Successful in 2m59s
docs(options): README tables reconciled + permanent option-docs check (item 6a)
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>
2026-07-04 19:31:20 +01:00

61 lines
2.1 KiB
Python

#!/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")