# -*- coding: utf-8 -*- """REUSE.md refs check — staleness defense for the per-repo reuse maps. Usage: python scripts/reuse_refs_check.py [ ...] For each repo root given, parses /REUSE.md, extracts every cited file path (*.go, *.py, *.html, *.css, *.yml, *.yaml, *.sh) and verifies the file exists in the tree. Only slash-containing (repo-relative) tokens are checked — bare filenames are conventions, not citations. Prints offending lines; exits non-zero if any cited path is missing. Symbols are NOT checked here — those are spot-verified by the reviewer at file:line. """ import io, os, re, sys # path-looking tokens ending in a checked extension; globs (*) are conventions, not refs PATH_RE = re.compile(r'[A-Za-z0-9_][A-Za-z0-9_./\-]*/[A-Za-z0-9_./\-]*\.(?:go|py|html|css|yml|yaml|sh)\b') fails = 0 def check_repo(root): global fails root = os.path.abspath(root) reuse = os.path.join(root, "REUSE.md") name = os.path.basename(root) if not os.path.isfile(reuse): print("FAIL [%s]: no REUSE.md at %s" % (name, reuse)) fails += 1 return seen, missing = set(), 0 with io.open(reuse, encoding="utf-8") as f: for lineno, line in enumerate(f, 1): for m in PATH_RE.finditer(line): p = m.group(0) if "*" in line[max(0, m.start() - 2):m.end() + 2]: continue # glob like scripts/*.py — a convention, not a file ref if p in seen: continue seen.add(p) if not os.path.isfile(os.path.join(root, p)): print("FAIL [%s] line %d: cited path missing: %s" % (name, lineno, p)) missing += 1 if missing: fails += missing else: print("OK [%s]: %d cited paths, all exist" % (name, len(seen))) if len(sys.argv) < 2: print(__doc__) sys.exit(2) for r in sys.argv[1:]: check_repo(r) sys.exit(1 if fails else 0)