from pathlib import Path import hashlib, json, zipfile root = Path(__file__).resolve().parent archive = next((root / 'dist').glob('*.zip')) expected = (Path(str(archive)+'.sha256')).read_text().split()[0] assert hashlib.sha256(archive.read_bytes()).hexdigest() == expected target = root / 'extracted' target.mkdir(exist_ok=False) with zipfile.ZipFile(archive) as z: assert len(z.namelist()) == len(set(z.namelist())) == 565 for name in z.namelist(): p = Path(name) assert not p.is_absolute() and '..' not in p.parts z.extractall(target) bundle = next(target.iterdir()) manifest = {} for line in (bundle / 'SHA256SUMS.txt').read_text().splitlines(): digest, name = line.split(' ', 1) assert name not in manifest assert hashlib.sha256((bundle / name).read_bytes()).hexdigest() == digest, name manifest[name] = digest names = {p.relative_to(bundle).as_posix() for p in bundle.rglob('*') if p.is_file()} assert names == set(manifest) | {'SHA256SUMS.txt'} manifest['SHA256SUMS.txt'] = hashlib.sha256((bundle / 'SHA256SUMS.txt').read_bytes()).hexdigest() report = {'status': 'PASS', 'archive': archive.name, 'archive_bytes': archive.stat().st_size, 'archive_sha256': expected, 'files': len(names), 'bundle': str(bundle), 'sha256': manifest} (root / 'extraction-check.json').write_text(json.dumps(report, indent=2)+'\n', encoding='utf-8') print(json.dumps({k:v for k,v in report.items() if k!='sha256'}, indent=2))