49 lines
2.4 KiB
Python
49 lines
2.4 KiB
Python
#!/usr/bin/env python3
|
|
"""Create a bounded source/PDFium snapshot, excluding results, builds and VM keys."""
|
|
import argparse
|
|
import hashlib
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
import re
|
|
import tarfile
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument('--name', required=True)
|
|
args = parser.parse_args()
|
|
if not re.fullmatch(r'[a-z0-9][a-z0-9-]{0,63}', args.name):
|
|
parser.error('Use a short lowercase snapshot name')
|
|
work = Path(os.environ.get('DOCVIEW_VM_WORK', ROOT / 'build-ubuntu-vm')).resolve()
|
|
archive = work / (args.name + '.tar.gz')
|
|
manifest = work / 'metadata' / (args.name + '.json')
|
|
if archive.exists() or manifest.exists():
|
|
parser.error('Choose a new name to preserve previous source evidence')
|
|
files = [ROOT / name for name in ('CMakeLists.txt', 'resources.qrc', 'README.md')]
|
|
for name in ('src', 'qml', 'cmake', 'resources', 'tools', 'tests', 'docs', '.deps/pdfium'):
|
|
directory = ROOT / name
|
|
for base, directories, leaves in os.walk(directory, followlinks=False):
|
|
directories[:] = [d for d in directories if d not in ('results', '__pycache__', '.git')
|
|
and not (Path(base) / d).is_symlink()]
|
|
files.extend(Path(base) / leaf for leaf in leaves if leaf != 'validation-record.json')
|
|
rows, total = [], 0
|
|
for path in sorted(set(files)):
|
|
if path.is_symlink() or not path.is_file() or not path.resolve().is_relative_to(ROOT):
|
|
raise SystemExit('Unexpected non-regular source input')
|
|
size = path.stat().st_size
|
|
total += size
|
|
if len(rows) >= 10000 or size > 256 * 1024 * 1024 or total > 512 * 1024 * 1024:
|
|
raise SystemExit('Source snapshot exceeds finite limits')
|
|
with path.open('rb') as stream:
|
|
digest = hashlib.file_digest(stream, 'sha256').hexdigest()
|
|
rows.append({'path': str(path.relative_to(ROOT)), 'size': size, 'sha256': digest})
|
|
work.mkdir(parents=True, exist_ok=True)
|
|
manifest.parent.mkdir(parents=True, exist_ok=True)
|
|
with tarfile.open(archive, 'x:gz') as stream:
|
|
for row in rows:
|
|
stream.add(ROOT / row['path'], arcname=row['path'], recursive=False)
|
|
with archive.open('rb') as stream:
|
|
digest = hashlib.file_digest(stream, 'sha256').hexdigest()
|
|
manifest.write_text(json.dumps({'archiveSha256': digest, 'files': rows}, indent=2) + '\n')
|
|
print(json.dumps({'files': len(rows), 'sourceBytes': total, 'archiveSha256': digest}))
|