Files
ARCADIA-Studio/harness/experiments/runtime-notices-20260913/tools/integrate-runtime-notices-20260913.py
T

54 lines
3.7 KiB
Python

from pathlib import Path
import hashlib,json,subprocess,datetime,time,os
R=Path(__file__).resolve().parent.parent
P=R/'.local/runtime-notices-20260913'
Q=R/'.local/runtime-notices-integration-20260913';Q.mkdir()
def sha(b):return hashlib.sha256(b).hexdigest()
def new(p,b):
with p.open('xb') as f:f.write(b)
def record(p):
b=p.read_bytes();return {'path':str(p.relative_to(R)),'bytes':len(b),'sha256':sha(b)}
manifest=R/'scripts/windows-notices/manifest.json';before=manifest.read_bytes()
assert sha(before)=='b39beaee5d8aeedcb45c7fd9b65c1b88a4fe784ddb9fe3d4126f5750e478c081'
entry=json.loads((P/'runtime-entry.json').read_bytes());base=json.loads(before)
expected=json.loads(json.dumps(base));expected['runtimes'].append(entry)
assert expected==json.loads((P/'notice-inputs/manifest.json').read_bytes())
nl=b'\r\n' if b'\r\n' in before else b'\n'
suffix=nl.join([b' }',b' ]',b'}',b''])
assert before.endswith(suffix)
encoded=nl.join((' '+s).encode() for s in json.dumps(entry,indent=2).splitlines())
after=before[:-len(suffix)]+b' },'+nl+encoded+nl+b' ]'+nl+b'}'+nl
assert json.loads(after)==expected
new(Q/'manifest-before.json',before)
manifest.write_bytes(after)
attributes=R/'.gitattributes';attrbefore=attributes.read_bytes()
line=b'harness/experiments/runtime-notices-20260913/** -text whitespace=-blank-at-eol,-blank-at-eof,cr-at-eol'
assert line not in attrbefore
attrnl=b'\r\n' if b'\r\n' in attrbefore else b'\n'
attributes.write_bytes(attrbefore+(b'' if attrbefore.endswith(b'\n') else attrnl)+line+attrnl)
new(Q/'attributes-before',attrbefore)
# Exact changed semantics and all actual notice-file digests, without collector/Cargo.
for group in ['packages','assets','runtimes']:
for row in expected[group]:
for n in row.get('notices',[]):
assert sha((R/'scripts/windows-notices'/n['file']).read_bytes())==n['sha256']
assert len([x for x in expected['runtimes'] if x['sha256']==entry['sha256']])==1
assert sha((R/'.local/toolchain/llvm-mingw-20260908-ucrt-x86_64/x86_64-w64-mingw32/bin/libunwind.dll').read_bytes())==entry['sha256']
test=R/'scripts/test-windows-notices.ps1';collector=R/'scripts/windows-notices.ps1'
testbytes=test.read_bytes()
assert b'Remove-Item' not in testbytes and b'Directory]::Delete' not in testbytes and b'rm -' not in testbytes
assert b'Synthetic fixture retained for inspection:' in testbytes
shell=Path(os.environ['SystemRoot'])/'System32/WindowsPowerShell/v1.0/powershell.exe'
command=[str(shell),'-NoProfile','-ExecutionPolicy','Bypass','-File',str(test)]
inputs=[record(p) for p in [test,collector,manifest,attributes]]
start=datetime.datetime.now(datetime.timezone.utc).isoformat();clock=time.monotonic()
with (Q/'synthetic.stdout.log').open('xb') as stdout,(Q/'synthetic.stderr.log').open('xb') as stderr:
process=subprocess.run(command,cwd=R,stdout=stdout,stderr=stderr)
elapsed=time.monotonic()-clock
assert inputs==[record(p) for p in [test,collector,manifest,attributes]]
receipt={'start_utc':start,'end_utc':datetime.datetime.now(datetime.timezone.utc).isoformat(),'command':command,'powershell_executable':{'path':str(shell),'sha256':sha(shell.read_bytes())},'elapsed_seconds':elapsed,'exit':process.returncode,'inputs':inputs,'inputs_unchanged':True,'base_manifest_sha256':sha(before),'mapping_only_append':True,'all_notice_digests_pass':True,'runtime_digest_pass':True,'cleanup_review':'Original script retains GUID-named synthetic temp fixture; no recursive removal/move. Cargo/rustc are local mock functions; no actual compiler invoked.','stdout':record(Q/'synthetic.stdout.log'),'stderr':record(Q/'synthetic.stderr.log')}
new(Q/'result.json',(json.dumps(receipt,indent=2)+'\n').encode())
print(json.dumps(receipt,indent=2))
assert process.returncode==0
assert b'PASS:' in (Q/'synthetic.stdout.log').read_bytes()