1
0
Fork 0
forked from hanez/xtc

Phase 30: complete configurable installation and release qualification

This commit is contained in:
Johannes Findeisen 2026-10-27 17:13:09 +01:00
commit 90eac33a71
18 changed files with 399 additions and 59 deletions

View file

@ -1,26 +1,19 @@
#!/usr/bin/env python3
"""Remove only this source version's installed files; never recurse directories."""
"""Remove only this source version's inventory; never recurse directories."""
import argparse
from pathlib import Path
import stat
from install_layout import arguments, inventory, layout, staged
def owned_files(source):
files = ['lib/libxtc.a', 'lib/pkgconfig/xtc.pc', 'bin/xtc-check', 'bin/xtc',
'share/applications/xtc.desktop', 'share/licenses/xtc/LICENSE',
'share/doc/xtc/README.md', 'share/doc/xtc/performance-baseline.json',
'share/doc/xtc/BINARY_MANIFEST.json']
files += ['include/xtc/' + p.name for p in sorted((source / 'include/xtc').glob('*.h'))]
files += ['share/doc/xtc/' + p.name for p in sorted((source / 'docs').glob('*.md'))]
files += ['share/doc/xtc/decisions/' + p.name for p in sorted((source / 'docs/decisions').glob('*.md'))]
return files
def uninstall(root, source):
if not root.is_absolute() or root == Path('/'):
raise ValueError('Installation root must be absolute and not /')
files = [root / name for name in owned_files(source)]
# Preflight before changing anything; never unlink a directory at a file path.
def main():
parser = argparse.ArgumentParser(description=__doc__)
arguments(parser)
parser.add_argument('--root', help='legacy alias for --prefix')
args = parser.parse_args()
if args.root:
args.prefix = args.root
files = [staged(path, args.destdir) for path, _ in inventory(Path(__file__).resolve().parent.parent, layout(args))]
for path in files:
try:
mode = path.lstat().st_mode
@ -30,16 +23,14 @@ def uninstall(root, source):
raise ValueError(f'Refusing non-file: {path}')
for path in files:
path.unlink(missing_ok=True)
parents = {parent for path in files for parent in path.parents if parent == root or root in parent.parents}
# Only try the immediate owned directories, never walk up to / or DESTDIR.
parents = {p.parent for p in files}
for parent in sorted(parents, key=lambda p: len(p.parts), reverse=True):
try:
parent.rmdir()
except (FileNotFoundError, OSError):
pass # Shared/nonempty directories remain untouched.
except OSError:
pass
if __name__ == '__main__':
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--root', type=Path, required=True)
args = parser.parse_args()
uninstall(args.root, Path(__file__).resolve().parent.parent)
main()