44 lines
1.8 KiB
Python
44 lines
1.8 KiB
Python
|
|
#!/usr/bin/env python3
|
||
|
|
"""Remove only this source version's installed files; never recurse directories."""
|
||
|
|
import argparse
|
||
|
|
from pathlib import Path
|
||
|
|
import stat
|
||
|
|
|
||
|
|
|
||
|
|
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']
|
||
|
|
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.
|
||
|
|
for path in files:
|
||
|
|
try:
|
||
|
|
mode = path.lstat().st_mode
|
||
|
|
except FileNotFoundError:
|
||
|
|
continue
|
||
|
|
if not (stat.S_ISREG(mode) or stat.S_ISLNK(mode)):
|
||
|
|
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}
|
||
|
|
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.
|
||
|
|
|
||
|
|
|
||
|
|
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)
|