#!/usr/bin/env python3 """Refresh dependency packages that Decman must ignore to guarantee no removal.""" from __future__ import annotations import subprocess from pathlib import Path import pyalpm ROOT = Path(__file__).resolve().parents[1] OUTPUT = ROOT / "packages" / "ignored" def repository_names(handle: pyalpm.Handle) -> set[str]: return { package.name for database in handle.get_syncdbs() for package in database.pkgcache } def deep_orphans(handle: pyalpm.Handle, predicate) -> set[str]: local = {package.name: package for package in handle.get_localdb().pkgcache} candidates = { package.name for package in local.values() if package.reason == pyalpm.PKG_REASON_DEPEND and predicate(package.name) } while True: retained = { name for name in candidates if not (set(local[name].compute_requiredby()) - candidates) } if retained == candidates: return retained candidates = retained def write(name: str, values: set[str]) -> None: (OUTPUT / name).write_text("\n".join(sorted(values)) + "\n", encoding="utf-8") def main() -> None: handle = pyalpm.Handle("/", "/var/lib/pacman") repositories = subprocess.run( ["pacman-conf", "--repo-list"], check=True, text=True, stdout=subprocess.PIPE ).stdout.split() for repository in repositories: handle.register_syncdb(repository, 0) native = repository_names(handle) write("repo-dependencies.txt", deep_orphans(handle, lambda name: name in native)) write("aur-dependencies.txt", deep_orphans(handle, lambda name: name not in native)) if __name__ == "__main__": main()