64 lines
2.3 KiB
Python
64 lines
2.3 KiB
Python
"""Materialize pinned baseline/candidate headers under a new explicit output path."""
|
|
|
|
import argparse
|
|
import hashlib
|
|
import json
|
|
from pathlib import Path
|
|
import shutil
|
|
import subprocess
|
|
|
|
HERE = Path(__file__).resolve().parent
|
|
REPO = HERE.parents[2]
|
|
DATA = HERE / "data"
|
|
PIN = "d79e3f6f0a424f5bcc3a1a6d610313e49daf97a2"
|
|
|
|
|
|
def manifest():
|
|
result = json.loads((DATA / "source_manifest.json").read_text())
|
|
if result["baseline_commit"] != PIN:
|
|
raise RuntimeError("Wrong baseline pin")
|
|
return result
|
|
|
|
|
|
def verify_candidate(root):
|
|
for name, expected in manifest()["files"].items():
|
|
if hashlib.sha256((root / name).read_bytes()).hexdigest() != expected:
|
|
raise RuntimeError("Candidate header hash mismatch: " + name)
|
|
|
|
|
|
def materialize(repo, output):
|
|
"""Copy only the two exact source headers, then patch the isolated copy."""
|
|
expected = manifest()
|
|
headers = [
|
|
Path(name).relative_to("baseline")
|
|
for name in expected["files"]
|
|
if name.startswith("baseline/")
|
|
]
|
|
for relative in headers:
|
|
wanted = expected["files"][str(Path("baseline") / relative)]
|
|
if hashlib.sha256((repo / relative).read_bytes()).hexdigest() != wanted:
|
|
raise RuntimeError("Production header does not match d79: " + str(relative))
|
|
output.mkdir(parents=True, exist_ok=False)
|
|
for mode in ("baseline", "patched"):
|
|
for relative in headers:
|
|
target = output / mode / relative
|
|
target.parent.mkdir(parents=True, exist_ok=True)
|
|
shutil.copyfile(repo / relative, target)
|
|
patch = DATA / "smagorinsky_normalization.patch"
|
|
subprocess.run(
|
|
["git", "apply", "--check", str(patch)], cwd=output / "patched", check=True
|
|
)
|
|
subprocess.run(["git", "apply", str(patch)], cwd=output / "patched", check=True)
|
|
verify_candidate(output)
|
|
(output / "source_manifest.json").write_text(json.dumps(expected, indent=2) + "\n")
|
|
return output
|
|
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument("--repo", type=Path, default=REPO)
|
|
parser.add_argument("--output-dir", type=Path, required=True)
|
|
args = parser.parse_args()
|
|
materialize(args.repo.resolve(), args.output_dir.resolve())
|
|
print("Pinned baseline/candidate headers verified; production files unchanged.")
|