#!/usr/bin/env python3 """Vendor the Tera arena TypeScript closure into this package. Tera is a TypeScript repository with no Python toolchain, and this package is a Python wheel. The bridge's rule is that a number the model is graded on is computed *once*, in TypeScript, and only ever transported into Python — so the TypeScript has to travel with the wheel rather than be resolved at runtime from a checkout that may not exist on the machine doing the eval. What travels is the transitive import closure of `src/arena/index.ts` and nothing else: 23 files, no bare specifiers, no Three.js, no DOM. That closure is walked here rather than declared, so a new import in `tera` is picked up the next time somebody runs this instead of silently going missing. uv run python scripts/sync_tera.py --tera ~/repos/gitea/tera Writes `tera_spatial/vendor/tera/` for every file in the closure and regenerates `tera_spatial/hashes.py`. Both are committed. `hashes.py` is what `test_replay.py` checks the vendored tree against, so an edit to a vendored file that does not come back through this script fails the gate. """ from __future__ import annotations import argparse import hashlib import shutil import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) from tera_spatial.closure import ENTRY, walk # noqa: E402 def sha256(path: Path) -> str: return "sha256:" + hashlib.sha256(path.read_bytes()).hexdigest() def main(argv: list[str] | None = None) -> int: package = Path(__file__).resolve().parent.parent parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--tera", type=Path, default=Path.home() / "repos/gitea/tera") parser.add_argument("--check", action="store_true", help="verify only; write nothing") args = parser.parse_args(argv) root = args.tera.expanduser().resolve() if not (root / ENTRY).is_file(): print(f"not a tera checkout: {root}", file=sys.stderr) return 2 files, bare = walk(root) if bare: # A bare specifier means the closure needs `node_modules`, and the wheel # would ship a bridge that only runs next to a `npm install`. print("closure is not self-contained:", file=sys.stderr) for entry in bare: print(f" {entry}", file=sys.stderr) return 1 vendor = package / "tera_spatial" / "vendor" / "tera" if args.check: stale = [rel for rel in files if not (vendor / rel).is_file()] if stale: print("missing from vendor:", *stale, sep="\n ", file=sys.stderr) return 1 else: if vendor.exists(): shutil.rmtree(vendor) for rel in files: destination = vendor / rel destination.parent.mkdir(parents=True, exist_ok=True) shutil.copyfile(root / rel, destination) digests = {rel: sha256(vendor / rel) for rel in files} total = sum((vendor / rel).stat().st_size for rel in files) aggregate = hashlib.sha256() for rel in files: aggregate.update(rel.encode()) aggregate.update(b"\0") aggregate.update((vendor / rel).read_bytes()) aggregate.update(b"\0") body = _render(digests, total, "sha256:" + aggregate.hexdigest()) target = package / "tera_spatial" / "hashes.py" if args.check: if target.read_text(encoding="utf-8") != body: print("hashes.py is stale; re-run scripts/sync_tera.py", file=sys.stderr) return 1 print(f"vendored closure ok: {len(files)} files, {total} bytes") return 0 target.write_text(body, encoding="utf-8") print(f"vendored {len(files)} files ({total} bytes) from {root}") return 0 def _render(digests: dict[str, str], total: int, aggregate: str) -> str: lines = [ '"""SHA-256 of every vendored Tera source file. Generated — do not edit.', "", "Regenerate with `scripts/sync_tera.py`. `verify()` is called by the replay", "gate: the checksums a trace carries are only worth something if the code that", "produced them is the code on disk.", '"""', "", "from __future__ import annotations", "", "import hashlib", "from pathlib import Path", "", f"CLOSURE_ENTRY = {ENTRY!r}", f"CLOSURE_BYTES = {total}", f"CLOSURE_SHA256 = {aggregate!r}", "", "VENDORED_FILES: dict[str, str] = {", ] lines += [f" {rel!r}: {digest!r}," for rel, digest in digests.items()] lines += [ "}", "", "VENDOR_ROOT = Path(__file__).resolve().parent / \"vendor\" / \"tera\"", "", "", "def verify() -> list[str]:", ' """Return a list of complaints about the vendored tree. Empty means clean."""', " problems: list[str] = []", " for relative, expected in VENDORED_FILES.items():", " path = VENDOR_ROOT / relative", " if not path.is_file():", " problems.append(f\"missing: {relative}\")", " continue", ' actual = "sha256:" + hashlib.sha256(path.read_bytes()).hexdigest()', " if actual != expected:", ' problems.append(f"modified: {relative} ({actual} != {expected})")', " for path in sorted(VENDOR_ROOT.rglob(\"*\")):", " if path.is_file():", " relative = path.relative_to(VENDOR_ROOT).as_posix()", " if relative not in VENDORED_FILES:", ' problems.append(f"unrecorded: {relative}")', " return problems", "", ] return "\n".join(lines) if __name__ == "__main__": raise SystemExit(main())