mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 02:54:26 +00:00
Two of them lived inside docs/ next to the pages they render, which is why both had grown a __file__ upward walk to find the repository root, a sys.path insert to import from utils, and a nocheck for each. A generator parked among documents reads as documentation and drops out of the checks that apply to code. Moving them surfaced six real violations that the old location had hidden: yaml.safe_load instead of the shared cache, two uncached read_text calls, five hard-coded role paths instead of ROLE_FILE_META_SERVICES and ROLE_FILE_META_MCP, two make targets without an alias, and a requirement reference in code. All six are fixed at the root, none with a suppression, and both generators lose their project-root exemptions because a package supplies PROJECT_ROOT. cli/build/readme joins them so the three generators that write into docs/ sit together. A new lint keeps docs/ to .md, .html, .rst and .nocheck; it enumerates through git ls-files so untracked __pycache__ is not its business. Checked against HEAD, it names exactly the three .py files that moved. 026-unified-addon-syntax stated that the matrix generator stays under docs/requirements/. The lint makes that impossible, so the requirement now records where the generator actually lives. Verified: every one of the twelve modules under the new tree imports, no old module path survives anywhere in the repository, 482 lint tests and 1246 cli unit tests pass, and both generators run without drift. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
101 lines
3.4 KiB
Python
Executable File
101 lines
3.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Generate or complete role README.md files from the schema template.
|
|
|
|
Usage:
|
|
python -m cli.build.docs.readme [roles...] [--override] [--check] [--roles-dir DIR]
|
|
|
|
With no role names every role directory is processed. ``--override``
|
|
regenerates the managed sections (Cosmos, Quick Setup, Credits) even when
|
|
they already exist; without it, only missing sections are added.
|
|
``--update-cosmos`` regenerates only the Cosmos diagram. Prose sections are
|
|
never rewritten. ``--check`` writes nothing and exits non-zero when any
|
|
file would change (for CI).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
from pathlib import Path
|
|
|
|
from cli.build.docs.readme.generate import MANAGED_SECTIONS, generate_readme, role_dirs
|
|
from utils.cache.files import PROJECT_ROOT
|
|
from utils.roles.mapping import ROLE_FILE_README
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser(description="Generate role README.md files.")
|
|
parser.add_argument("roles", nargs="*", help="Role names (default: all).")
|
|
parser.add_argument(
|
|
"--override",
|
|
action="store_true",
|
|
help="Regenerate managed sections even when present (default: only add missing).",
|
|
)
|
|
parser.add_argument(
|
|
"--update-cosmos",
|
|
action="store_true",
|
|
help="Regenerate only the Cosmos diagram (implies override for it).",
|
|
)
|
|
parser.add_argument(
|
|
"--update-quick-setup",
|
|
action="store_true",
|
|
help="Regenerate only the Quick Setup section (implies override for it).",
|
|
)
|
|
parser.add_argument(
|
|
"--check",
|
|
action="store_true",
|
|
help="Do not write; exit non-zero if any README would change.",
|
|
)
|
|
parser.add_argument(
|
|
"--roles-dir",
|
|
default=str(PROJECT_ROOT / "roles"),
|
|
help="Directory containing role subfolders.",
|
|
)
|
|
args = parser.parse_args()
|
|
|
|
roles_root = Path(args.roles_dir)
|
|
if not roles_root.is_dir():
|
|
parser.error(f"Roles directory not found: {roles_root}")
|
|
|
|
if args.roles:
|
|
targets = [roles_root / name for name in args.roles]
|
|
missing = [str(p) for p in targets if not p.is_dir()]
|
|
if missing:
|
|
parser.error("Unknown role(s): " + ", ".join(missing))
|
|
else:
|
|
targets = role_dirs(roles_root)
|
|
|
|
if args.update_cosmos:
|
|
only, override = ("Cosmos",), True
|
|
elif args.update_quick_setup:
|
|
only, override = ("Quick Setup",), True
|
|
else:
|
|
only, override = MANAGED_SECTIONS, args.override
|
|
|
|
changed = 0
|
|
for role_dir in targets:
|
|
if not (role_dir / ROLE_FILE_README).is_file() and not (role_dir / "meta").is_dir():
|
|
continue
|
|
new_text, actions = generate_readme(
|
|
role_dir, role_dir.name, override=override, only=only
|
|
)
|
|
if new_text is None:
|
|
continue
|
|
changed += 1
|
|
rel = role_dir.relative_to(PROJECT_ROOT)
|
|
if args.check:
|
|
print(f"would update {rel}/README.md: {', '.join(actions)}")
|
|
continue
|
|
(role_dir / ROLE_FILE_README).write_text(new_text, encoding="utf-8")
|
|
print(f"updated {rel}/README.md: {', '.join(actions)}")
|
|
|
|
if args.check and changed:
|
|
print(f"\n{changed} README.md file(s) would change. Run: make readme-generate")
|
|
return 1
|
|
if not args.check:
|
|
print(f"\n{changed} README.md file(s) written.")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|