Something went wrong. Try again.
atproto Thingiverse but good
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186#!/usr/bin/env python3"""Check current-state documentation references against source and the filesystem."""from __future__ import annotations
import argparseimport reimport sysimport tempfilefrom pathlib import Path
DOCS = ("README.md", "DESIGN.md", "AGENTS.md", "src/oauth/mod.rs")STALE_REFERENCES = ("cards.css", "001_projection_schema.sql")REQUIRED_ARCHITECTURE_TERMS = ( "SQLite", "appview projection", "Hydrant", "Fjall", "pending_writes", "pending_deletes",)STYLE_DECLARATION = re.compile(r'asset!\("/assets/styling/([^"/]+\.css)"\)')REQUIRED_SOURCE_FILES = ("src/main.rs", "migrations/0001_initial_schema.sql")
def fail(message: str) -> None: raise ValueError(message)
def selected_documents(root: Path) -> list[tuple[Path, str]]: documents: list[tuple[Path, str]] = [] for relative in DOCS: path = root / relative if not path.is_file(): fail(f"missing documentation source: {relative}") documents.append((path, path.read_text(encoding="utf-8"))) return documents
def check_paths(root: Path, documents: list[tuple[Path, str]]) -> None: source = root / "src/main.rs" if not source.is_file(): fail("missing source of truth: src/main.rs") declarations = STYLE_DECLARATION.findall(source.read_text(encoding="utf-8")) if not declarations: fail("src/main.rs has no stylesheet declarations") for stylesheet in declarations: if not (root / "assets/styling" / stylesheet).is_file(): fail(f"stylesheet declared by src/main.rs does not exist: {stylesheet}") for relative in REQUIRED_SOURCE_FILES: if not (root / relative).is_file(): fail(f"required current path does not exist: {relative}") for path, text in documents: if "assets/styling/" in text: for reference in re.findall(r"assets/styling/([A-Za-z0-9_.-]+\.css)", text): if not (root / "assets/styling" / reference).is_file(): fail(f"{path.relative_to(root)} references missing stylesheet: {reference}") for reference in re.findall(r"migrations/[A-Za-z0-9_.-]+\.sql", text): if not (root / reference).is_file(): fail(f"{path.relative_to(root)} references missing migration: {reference}")
def check_current_maps(root: Path, documents: list[tuple[Path, str]]) -> None: text_by_name = {path.name: text for path, text in documents} architecture_text = "\n".join(text_by_name[name] for name in ("README.md", "AGENTS.md")) for term in REQUIRED_ARCHITECTURE_TERMS: if term not in architecture_text: fail(f"current architecture maps omit required term: {term}") source = (root / "src/main.rs").read_text(encoding="utf-8") expected_cascade = STYLE_DECLARATION.findall(source) agents = text_by_name["AGENTS.md"] cascade_line = next((line for line in agents.splitlines() if "layered cascade" in line), "") if not cascade_line: fail("AGENTS.md does not describe the stylesheet cascade") positions = [cascade_line.find(stylesheet) for stylesheet in expected_cascade] if any(position < 0 for position in positions) or positions != sorted(positions): fail("AGENTS.md does not describe the stylesheet cascade in src/main.rs order")
def check_stale_references(documents: list[tuple[Path, str]]) -> None: for path, text in documents: for stale in STALE_REFERENCES: if stale in text: fail(f"{path.relative_to(path.parents[1]) if path.name == 'mod.rs' else path.name} contains stale reference: {stale}")
def validate(root: Path) -> None: documents = selected_documents(root) check_paths(root, documents) check_current_maps(root, documents) check_stale_references(documents)
def write_fixture(root: Path) -> None: (root / "src/oauth").mkdir(parents=True, exist_ok=True) (root / "assets/styling").mkdir(parents=True, exist_ok=True) (root / "migrations").mkdir(exist_ok=True) (root / "src/main.rs").write_text( "\n".join(f'const STYLE: Asset = asset!("/assets/styling/{name}");' for name in ( "theme.css", "base.css", "primitives.css", "shell.css", "home.css", "thing-detail.css", "profile.css", "viewer.css", "publish.css", "placeholders.css", "about.css", )), encoding="utf-8", ) for name in ( "theme.css", "base.css", "primitives.css", "shell.css", "home.css", "thing-detail.css", "profile.css", "viewer.css", "publish.css", "placeholders.css", "about.css", ): (root / "assets/styling" / name).write_text("", encoding="utf-8") (root / "migrations/0001_initial_schema.sql").write_text("", encoding="utf-8") (root / "README.md").write_text( "SQLite appview projection; Hydrant retains raw events in Fjall. " "pending_writes and pending_deletes define the pending-operation boundary.\n", encoding="utf-8", ) (root / "DESIGN.md").write_text("Use assets/styling/theme.css and primitives.css.\n", encoding="utf-8") (root / "AGENTS.md").write_text( "SQLite appview projection; Hydrant and Fjall; pending_writes and pending_deletes.\n" "assets/styling/ follows a layered cascade: " "theme.css base.css primitives.css shell.css home.css thing-detail.css profile.css " "viewer.css publish.css placeholders.css about.css\n", encoding="utf-8", ) (root / "src/oauth/mod.rs").write_text( "See migrations/0001_initial_schema.sql.\n", encoding="utf-8" )
def self_test() -> None: with tempfile.TemporaryDirectory() as directory: root = Path(directory) write_fixture(root) validate(root) (root / "assets/styling/cards.css").write_text("", encoding="utf-8") (root / "DESIGN.md").write_text( "Use assets/styling/cards.css.\n", encoding="utf-8" ) try: validate(root) except ValueError: pass else: fail("negative stale-stylesheet fixture unexpectedly passed") write_fixture(root) (root / "migrations/001_projection_schema.sql").write_text("", encoding="utf-8") (root / "src/oauth/mod.rs").write_text( "See migrations/001_projection_schema.sql.\n", encoding="utf-8" ) try: validate(root) except ValueError: pass else: fail("negative stale-migration fixture unexpectedly passed") write_fixture(root) (root / "assets/styling/about.css").unlink() try: validate(root) except ValueError: pass else: fail("negative missing-stylesheet fixture unexpectedly passed") print("check-doc-references self-test passed")
def main() -> int: parser = argparse.ArgumentParser() parser.add_argument("--self-test", action="store_true") parser.add_argument("root", nargs="?", type=Path, default=Path(__file__).resolve().parents[1]) args = parser.parse_args() try: if args.self_test: self_test() else: validate(args.root.resolve()) print(f"check-doc-references passed: {args.root.resolve()}") except (OSError, ValueError) as exc: print(f"check-doc-references failed: {exc}", file=sys.stderr) return 1 return 0
if __name__ == "__main__": raise SystemExit(main())