#!/usr/bin/env python3 """Install the explicit owned inventory; replace files without following symlinks.""" import argparse import os from pathlib import Path import shutil import tempfile from install_layout import arguments, inventory, layout, staged parser = argparse.ArgumentParser(description=__doc__) arguments(parser) parser.add_argument('--build-dir', type=Path, required=True) parser.add_argument('--gui', action='store_true') args = parser.parse_args() source = Path(__file__).resolve().parent.parent entries = [] for destination, original in inventory(source, layout(args)): name = destination.name if name == 'BINARY_MANIFEST.json' or (not args.gui and name in ('xtc', 'xtc.desktop')): continue if original is None: original = args.build_dir / name destination = staged(destination, args.destdir) if not original.is_file(): raise ValueError(f'Missing install input: {original}') if destination.exists() and not (destination.is_file() or destination.is_symlink()): raise ValueError(f'Refusing non-file destination: {destination}') entries.append((destination, original)) for destination, original in entries: destination.parent.mkdir(parents=True, exist_ok=True) fd, pending = tempfile.mkstemp(prefix='.xtc-install-', dir=destination.parent) try: with os.fdopen(fd, 'wb') as output, original.open('rb') as input_file: shutil.copyfileobj(input_file, output) os.fchmod(output.fileno(), 0o755 if destination.name in ('xtc', 'xtc-check') else 0o644) os.replace(pending, destination) finally: Path(pending).unlink(missing_ok=True)