40 lines
3.6 KiB
Python
40 lines
3.6 KiB
Python
from pathlib import Path
|
|
import hashlib,json,urllib.request,zipfile,re,datetime
|
|
O=Path(__file__).resolve().parent;R=O.parents[1]
|
|
def sha(b):return hashlib.sha256(b).hexdigest()
|
|
def new(p,b):
|
|
with p.open('xb') as f:f.write(b)
|
|
def fetch(url,name):
|
|
with urllib.request.urlopen(urllib.request.Request(url,headers={'User-Agent':'Arcadia-runtime-provenance/1'}),timeout=45) as r:b=r.read()
|
|
new(O/name,b);return b
|
|
source=json.loads((O/'source-evidence.json').read_text())
|
|
dist=source['distribution_commit'];llvm=source['llvm_commit']
|
|
workflow=fetch(f'https://raw.githubusercontent.com/mstorsjo/llvm-mingw/{dist}/.github/workflows/build.yml','build-workflow.yml')
|
|
with zipfile.ZipFile(R/'.local/toolchain/llvm-mingw.zip') as z:
|
|
names=[n for n in z.namelist() if re.search(r'/bin/clang-[0-9]+\.exe$',n)]
|
|
versions=[]
|
|
for n in names:
|
|
b=z.read(n)
|
|
strings=[s.decode('ascii') for s in re.findall(rb'[ -~]{15,}',b) if b'github.com/llvm/llvm-project' in s or b'clang version 23' in s]
|
|
versions.append({'member':n,'bytes':len(b),'sha256':sha(b),'strings':strings})
|
|
new(O/'actual-compiler-embedded-version-strings.json',json.dumps(versions,indent=2).encode())
|
|
entry={'name':'libunwind.dll','sha256':'aa282fa47bb2c4e210cea5e470cdbdca58568f0be0bc73e404d86ab9cd95ef6a','provenance':f'Official LLVM-MinGW 20260908 UCRT x86_64 release asset 551256712; local ZIP SHA256 1bcf74d06b724aeecaa6412ca85f5b26fb1da770e7cdcefa9263c9c5c3ad34b6 matches published GitHub asset digest and its runtime member matches this DLL. Distribution tag resolves to {dist}; build-llvm.sh selects llvmorg-23.1.1 ({llvm}), and build-libcxx.sh builds libunwind from that checkout. Component license fetched at this exact LLVM commit. This records official distribution/source provenance, not independently reproduced binary compilation.','notices':[{'file':'llvm-ea7d852a70e8-libunwind-LICENSE.TXT','sha256':'b5efebcaca80879234098e52d1725e6d9eb8fb96a19fce625d39184b705f7b6d','url':f'https://raw.githubusercontent.com/llvm/llvm-project/{llvm}/libunwind/LICENSE.TXT'}]}
|
|
old=R/'scripts/windows-notices';base=json.loads((old/'manifest.json').read_bytes());proposed=json.loads(json.dumps(base))
|
|
assert not any(r['sha256']==entry['sha256'] for r in base['runtimes'])
|
|
proposed['runtimes'].append(entry)
|
|
assert (old/entry['notices'][0]['file']).read_bytes()==(O/'llvm-libunwind-LICENSE.TXT').read_bytes()
|
|
dest=O/'notice-inputs';dest.mkdir()
|
|
copied=[]
|
|
for p in old.iterdir():
|
|
if p.name=='manifest.json':continue
|
|
assert p.is_file() and not p.is_symlink()
|
|
b=p.read_bytes();new(dest/p.name,b);copied.append({'name':p.name,'bytes':len(b),'sha256':sha(b)})
|
|
new(dest/'manifest.json',(json.dumps(proposed,indent=2)+'\n').encode())
|
|
new(O/'runtime-entry.json',(json.dumps(entry,indent=2)+'\n').encode())
|
|
for group in ['packages','assets','runtimes']:
|
|
for row in proposed[group]:
|
|
for n in row.get('notices',[]):
|
|
assert sha((dest/n['file']).read_bytes())==n['sha256']
|
|
new(O/'proposal-verification.json',json.dumps({'utc':datetime.datetime.now(datetime.timezone.utc).isoformat(),'base_manifest_sha256':sha((old/'manifest.json').read_bytes()),'candidate_manifest_sha256':sha((dest/'manifest.json').read_bytes()),'only_semantic_change':'append one exact runtime entry; all old fields/rows preserved','existing_component_license_exactly_equal_to_new_upstream':True,'copied_supplements':copied,'build_workflow_sha256':sha(workflow),'compiler_embedded_metadata':versions,'no_compiler_package_or_native_execution':True},indent=2).encode())
|
|
print(json.dumps({'candidate_manifest_sha256':sha((dest/'manifest.json').read_bytes()),'supplements':len(copied),'versions':versions},indent=2))
|