61 lines
2.8 KiB
Python
61 lines
2.8 KiB
Python
"""Apply exactly reviewed source; never deploy or confer runtime authority."""
|
|
from pathlib import Path
|
|
import argparse
|
|
import datetime
|
|
import hashlib
|
|
import json
|
|
import shutil
|
|
import subprocess
|
|
import tempfile
|
|
|
|
ROOT = Path(__file__).resolve().parent
|
|
PLAN = json.loads((ROOT / 'source-wave7-integration-plan.json').read_text())
|
|
|
|
def git(repo, *args):
|
|
return subprocess.check_output(['git', *args], cwd=repo, text=True).strip()
|
|
|
|
def digest(path):
|
|
return 'sha256:' + hashlib.sha256(path.read_bytes()).hexdigest()
|
|
|
|
def apply(repo, step):
|
|
for patch in step['patches']:
|
|
path = ROOT / patch['path']
|
|
assert digest(path) == 'sha256:' + patch['sha256']
|
|
subprocess.run(['git', 'apply', '--check', str(path)], cwd=repo, check=True)
|
|
subprocess.run(['git', 'apply', str(path)], cwd=repo, check=True)
|
|
for name, expected in step['files_sha256'].items():
|
|
assert digest(repo / name) == expected, name
|
|
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument('--apply', action='store_true')
|
|
args = parser.parse_args()
|
|
# Check every base and target before any owner mutation. Reconstruct exact final
|
|
# source independently in disposable directories, including dependent patches.
|
|
for step in PLAN:
|
|
repo = Path('/home/worsch') / step['repo']
|
|
assert git(repo, 'rev-parse', 'HEAD') == step['base'], step['repo']
|
|
assert not git(repo, 'status', '--porcelain', '--', *step['files_sha256']), step['repo']
|
|
with tempfile.TemporaryDirectory(prefix='netkingdom-wave7-preflight-') as temp:
|
|
target = Path(temp)
|
|
for name in step['files_sha256']:
|
|
source = repo / name
|
|
if source.exists():
|
|
assert source.is_file() and not source.is_symlink(), name
|
|
(target / name).parent.mkdir(parents=True, exist_ok=True)
|
|
shutil.copy2(source, target / name)
|
|
apply(target, step)
|
|
print('Preflight passed:', step['repo'], flush=True)
|
|
if args.apply:
|
|
for step in PLAN:
|
|
repo = Path('/home/worsch') / step['repo']
|
|
assert git(repo, 'rev-parse', 'HEAD') == step['base']
|
|
assert not git(repo, 'status', '--porcelain', '--', *step['files_sha256'])
|
|
apply(repo, step)
|
|
subprocess.run(['git', 'diff', '--check', '--', *step['files_sha256']], cwd=repo, check=True)
|
|
receipt = dict(step, integrated_at=datetime.datetime.now(datetime.timezone.utc).isoformat(),
|
|
source_integrated=True, committed=False, published=False,
|
|
native_accepted=False, scope='Reviewed source only; native custody and admission remain open')
|
|
for patch in receipt['patches']:
|
|
patch['sha256'] = 'sha256:' + patch['sha256']
|
|
(ROOT / step['receipt']).write_text(json.dumps(receipt, indent=2) + '\n')
|
|
print('Integrated exact source:', step['repo'], flush=True)
|