62 lines
3.4 KiB
Python
62 lines
3.4 KiB
Python
"""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()
|