initial commit
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Export the second PDFium candidate, preserving the first candidate evidence."""
|
||||
import difflib
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import tarfile
|
||||
import tempfile
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
|
||||
|
||||
def sha(path):
|
||||
with path.open('rb') as stream:
|
||||
return hashlib.file_digest(stream, 'sha256').hexdigest()
|
||||
|
||||
|
||||
def main():
|
||||
results = ROOT / 'tests/results/pdfium-intent-context'
|
||||
materialization = json.loads((ROOT / 'tests/results/pdfium-intent-build/source-materialization.json').read_text())
|
||||
repository = next(row for row in materialization['repositories'] if row['path'] == '.')
|
||||
archive = ROOT / repository['archive']
|
||||
inventory = ROOT / repository['inventory']
|
||||
assert sha(archive) == repository['archiveSha256']
|
||||
assert sha(inventory) == repository['inventorySha256']
|
||||
source = ROOT / 'build-pdfium-intent-context/source'
|
||||
originals = {row['path']: row for line in inventory.open()
|
||||
if (row := json.loads(line))['archived'] and row['path'].startswith('core/')}
|
||||
changed = {}
|
||||
for name, row in originals.items():
|
||||
assert row['mode'] == '100644'
|
||||
if sha(source / name) != row['sha256']:
|
||||
changed[name] = row
|
||||
added = {str(path.relative_to(source)) for path in (source / 'core').rglob('*')
|
||||
if path.is_file() and str(path.relative_to(source)) not in originals}
|
||||
assert all(Path(name).suffix in ('.h', '.cpp') for name in added)
|
||||
chunks = []
|
||||
records = []
|
||||
with tarfile.open(archive) as tar:
|
||||
for name in sorted(changed.keys() | added):
|
||||
before = b'' if name in added else tar.extractfile('pdfium/' + name).read()
|
||||
if name in changed:
|
||||
assert hashlib.sha256(before).hexdigest() == changed[name]['sha256']
|
||||
after = (source / name).read_bytes()
|
||||
diff = ''.join(difflib.unified_diff(
|
||||
before.decode().splitlines(keepends=True),
|
||||
after.decode().splitlines(keepends=True),
|
||||
fromfile='/dev/null' if name in added else 'a/' + name,
|
||||
tofile='b/' + name))
|
||||
assert diff
|
||||
chunks.append('diff --git a/' + name + ' b/' + name + '\n' + diff)
|
||||
records.append({'path': name, 'added': name in added,
|
||||
'beforeSha256': None if name in added else hashlib.sha256(before).hexdigest(),
|
||||
'afterSha256': hashlib.sha256(after).hexdigest()})
|
||||
destination = ROOT / 'cmake/patches/pdfium-rendering-intent-context.patch'
|
||||
destination.parent.mkdir(parents=True, exist_ok=True)
|
||||
destination.write_text(''.join(chunks))
|
||||
snapshot = results / 'patches' / (sha(destination) + '.patch')
|
||||
snapshot.parent.mkdir(exist_ok=True)
|
||||
if snapshot.exists():
|
||||
assert snapshot.read_bytes() == destination.read_bytes()
|
||||
else:
|
||||
snapshot.write_bytes(destination.read_bytes())
|
||||
# Check that this reviewable patch, rather than an unrecorded local change,
|
||||
# reproduces every modified core source without fuzzy matching.
|
||||
with tempfile.TemporaryDirectory(prefix='docview-pdfium-patch-') as folder:
|
||||
check_root = Path(folder)
|
||||
with tarfile.open(archive) as tar:
|
||||
for name in changed:
|
||||
target = check_root / name
|
||||
target.parent.mkdir(parents=True, exist_ok=True)
|
||||
target.write_bytes(tar.extractfile('pdfium/' + name).read())
|
||||
result = subprocess.run(['patch', '-p1', '--batch', '--fuzz=0', '-i', str(destination)],
|
||||
cwd=check_root, capture_output=True, text=True)
|
||||
assert result.returncode == 0, result.stdout + result.stderr
|
||||
for row in records:
|
||||
assert sha(check_root / row['path']) == row['afterSha256']
|
||||
record = {'success': True, 'exporterSha256': sha(Path(__file__)),
|
||||
'source': str(source.relative_to(ROOT)),
|
||||
'parentRecord': 'tests/results/pdfium-intent-build/record.json',
|
||||
'parentRecordSha256': sha(ROOT / 'tests/results/pdfium-intent-build/record.json'),
|
||||
'baseRevision': repository['revision'], 'archiveSha256': sha(archive),
|
||||
'patch': str(destination.relative_to(ROOT)), 'patchSha256': sha(destination),
|
||||
'patchSnapshot': str(snapshot.relative_to(ROOT)),
|
||||
'appliesWithoutFuzz': True, 'appliedSourcesByteIdentical': True,
|
||||
'files': records,
|
||||
'scope': 'Candidate core patch only. Provider shared-library/public-header patches are recorded separately. Production dependency is not replaced by this exporter.'}
|
||||
(results / 'candidate-patch.json').write_text(json.dumps(record, indent=2) + '\n')
|
||||
print(json.dumps({'files': len(records), 'patchBytes': destination.stat().st_size,
|
||||
'patchSha256': record['patchSha256']}))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user