"""Bind explicitly named Process gate captures to Git commits; no builds or checkouts.""" from pathlib import Path import argparse import datetime import json import re from verify import (HERE, TOOLS, COMPARISON, EXPLICIT_FIXTURES, need, pin, parsed, compare_commit, verify_data, raw_captures, packaged, verify_package) def encode(value): return (json.dumps(value, indent=2, sort_keys=True) + "\n").encode("utf-8") def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--repo", required=True, type=Path, help="repository containing the explicitly named full commit IDs") parser.add_argument("--raw-gates", type=Path, help="completed raw captures; required unless --checks provided") parser.add_argument("--checks", type=Path, help="completed portable Process checks package; required for writing") parser.add_argument("--gate", nargs=2, action="append", required=True, metavar=("RUN", "COMMIT")) parser.add_argument("--check-only", action="store_true") parser.add_argument("--output", type=Path, help="new source package directory") args = parser.parse_args() pairs = {} for run, commit in args.gate: need(re.fullmatch(r"[A-Za-z0-9][A-Za-z0-9._-]*", run) is not None, "safe gate name") need(re.fullmatch(r"[0-9a-f]{40}", commit) is not None, "explicit full commit ID required") need(run not in pairs, "duplicate gate") pairs[run] = commit need(args.raw_gates is not None or args.checks is not None, "capture input required") captured = packaged(args.checks, pairs) if args.checks else raw_captures(args.raw_gates, pairs) if args.checks and args.raw_gates: need(captured == raw_captures(args.raw_gates, pairs), "raw and packaged captures differ") specs, receipts = {}, {} for run, commit in pairs.items(): map_bytes, result, _archive = captured[run] spec = {"commit": commit, "inputCount": 742, "inputMap": pin(map_bytes), "explicitCompileTimeFixtures": sorted(EXPLICIT_FIXTURES)} # No receipt is written until every capture and exact commit comparison passes. receipts[run] = encode({**spec, "gate": run, "comparison": COMPARISON, "checked": datetime.datetime.now(datetime.timezone.utc).isoformat()}) specs[run] = {**spec, "receiptPin": pin(receipts[run])} summary = verify_data(receipts, captured, specs, args.repo) if args.check_only: need(args.output is None, "--check-only does not write output") print("PASS source check-only; no package written:", summary) return need(args.checks is not None and args.output is not None, "writing requires completed --checks and new --output") out = args.output.resolve() need(not out.exists(), "existing output refused") payload = {name:(HERE/name).read_bytes() for name in TOOLS} payload["manifest.json"] = encode({"schema":1, "kind":"process-multiselect-source", "runs":specs}) payload.update({"source-"+run+".json": value for run,value in receipts.items()}) out.mkdir(parents=True) for name, value in payload.items(): with (out/name).open("xb") as stream: stream.write(value) with (out/"files.json").open("xb") as stream: stream.write(encode({name:pin(value) for name,value in sorted(payload.items())})) print("PASS written package readback:", verify_package(out,args.checks), out) if __name__ == "__main__": main()