#!/usr/bin/env python3 """Enforce a ratcheted source file line-budget contract. The check fails when: - a file exceeds the configured line budget and is not allowlisted; or - an allowlist entry is stale (file removed or now within budget). """ from __future__ import annotations import argparse from pathlib import Path def _iter_source_files(roots: list[str], exts: set[str]) -> list[Path]: files: list[Path] = [] for root_text in roots: root = Path(root_text) if not root.exists(): continue for path in root.rglob("*"): if not path.is_file(): continue if path.suffix not in exts: continue if "__pycache__" in path.parts or ".venv" in path.parts: continue files.append(path.resolve()) return sorted(files) def _load_waivers(path: Path) -> dict[str, str]: waivers: dict[str, str] = {} if not path.exists(): return waivers for raw_line in path.read_text(encoding="utf-8").splitlines(): line = raw_line.strip() if not line or line.startswith("#"): continue parts = line.split("\t") rel_path = parts[0].strip() reason = parts[1].strip() if len(parts) > 1 else "" if rel_path: waivers[rel_path] = reason return waivers def main() -> int: parser = argparse.ArgumentParser() parser.add_argument("--roots", nargs="+", default=["ariadne", "scripts", "tests"]) parser.add_argument("--max-lines", type=int, default=500) parser.add_argument("--waivers", default="scripts/loc_hygiene_waivers.tsv") args = parser.parse_args() repo_root = Path.cwd().resolve() waivers = _load_waivers(repo_root / args.waivers) source_files = _iter_source_files(args.roots, {".py", ".sh"}) violations: dict[str, int] = {} for path in source_files: rel = path.relative_to(repo_root).as_posix() lines = len(path.read_text(encoding="utf-8", errors="ignore").splitlines()) if lines > args.max_lines: violations[rel] = lines unexpected = sorted(rel for rel in violations if rel not in waivers) stale = sorted(rel for rel in waivers if rel not in violations) if not unexpected and not stale: print( f"[hygiene] source line budget check passed (limit={args.max_lines}, over_limit={len(violations)}, waivers={len(waivers)})" ) return 0 if unexpected: print("[hygiene] files over budget missing from waiver list:") for rel in unexpected: print(f"- {rel}: {violations[rel]} lines (limit {args.max_lines})") if stale: print("[hygiene] stale waiver entries (remove from waiver list):") for rel in stale: print(f"- {rel}") return 1 if __name__ == "__main__": raise SystemExit(main())