#!/usr/bin/env python3 """Verify every packaged file, relocatable metadata and headless executables.""" import argparse import hashlib import json import os from pathlib import Path import subprocess import tarfile import sys import tempfile def main(): p = argparse.ArgumentParser(description=__doc__) p.add_argument('archive', type=Path) p.add_argument('--build-dir', type=Path) a = p.parse_args() expected = a.archive.with_name(a.archive.name + '.sha256').read_text().split()[0] assert hashlib.sha256(a.archive.read_bytes()).hexdigest() == expected with tempfile.TemporaryDirectory(prefix='xtc-package-test-') as temporary: root = Path(temporary) with tarfile.open(a.archive) as tar: members = tar.getmembers() assert members and all(m.isfile() for m in members) assert len({m.name for m in members}) == len(members) assert all(not Path(m.name).is_absolute() and '..' not in Path(m.name).parts for m in members) tar.extractall(root, filter='data') prefix = root / members[0].name.split('/')[0] / 'usr' manifest_path = prefix / 'share/doc/xtc/BINARY_MANIFEST.json' manifest = json.loads(manifest_path.read_text()) assert manifest['schema'] == 1 and manifest['needed'] expected_files = {f['path'] for f in manifest['files']} | {'usr/share/doc/xtc/BINARY_MANIFEST.json'} assert expected_files == {str(p.relative_to(prefix.parent)) for p in prefix.rglob('*') if p.is_file()} for f in manifest['files']: content = (prefix.parent / f['path']).read_bytes() assert len(content) == f['size'] and hashlib.sha256(content).hexdigest() == f['sha256'] env = dict(os.environ, DISPLAY='', WAYLAND_DISPLAY='', PKG_CONFIG_PATH=str(prefix / 'lib/pkgconfig')) for name in ('xtc-check', 'xtc'): binary = prefix / 'bin' / name if binary.exists(): for option in ('--version', '--help', '--diagnose'): subprocess.run([str(binary), option], env=env, check=True) flags = subprocess.check_output(['pkg-config', '--cflags', '--libs', '--static', 'xtc'], env=env, text=True) assert str(prefix / 'include') in flags or str(prefix / 'lib/pkgconfig/../../include') in flags assert (prefix / 'share/doc/xtc/USER_MANUAL.md').exists() assert (prefix / 'share/doc/xtc/RELEASE_NOTES.md').exists() subprocess.run([str(prefix / 'bin/xtc-check'), '--inspect', str(prefix / 'share/xtc/examples/midi-demo.xtc')], check=True) for name in ('project-performance-baseline.json', 'graph-performance-phase29.json'): assert (prefix / 'share/doc/xtc' / name).is_file() if a.build_dir: again = root / 'repacked.tar.gz' command = [sys.executable, 'tools/package.py', '--build-dir', str(a.build_dir), '--output', str(again)] if (prefix / 'bin/xtc').exists(): command.append('--gui') result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True) assert result.returncode == 0, result.stdout assert hashlib.sha256(again.read_bytes()).hexdigest() == expected, 'Binary repack differs' print('Binary archive hashes, manifest, relocation, headless diagnostics and documentation passed.') if __name__ == '__main__': main()