diff options
Diffstat (limited to 'debian/compute_pkgset.py')
-rwxr-xr-x | debian/compute_pkgset.py | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/debian/compute_pkgset.py b/debian/compute_pkgset.py new file mode 100755 index 0000000..3404cb0 --- /dev/null +++ b/debian/compute_pkgset.py @@ -0,0 +1,147 @@ +#!/usr/bin/env python3 + +import tempfile +import pathlib +import subprocess +import debian.deb822 +from collections import defaultdict + + +def main(): + pkglist = defaultdict(lambda: defaultdict(set)) + apttrusted = subprocess.check_output( + "eval $(apt-config shell v Dir::Etc::Trusted/f); printf $v", shell=True + ).decode() + apttrustedparts = subprocess.check_output( + "eval $(apt-config shell v Dir::Etc::TrustedParts/f); printf $v", shell=True + ).decode() + debci_arches = set( + ["amd64", "arm64", "armel", "armhf", "i386", "ppc64el", "riscv64", "s390x"] + ) + # debci_arches = set(["amd64", "i386"]) + for arch in list(debci_arches): + with tempfile.TemporaryDirectory() as tmpdir: + tmpdir = pathlib.Path(tmpdir) + (tmpdir / "etc" / "apt").mkdir(parents=True) + (tmpdir / "var" / "cache").mkdir(parents=True) + (tmpdir / "var" / "lib").mkdir(parents=True) + (tmpdir / "apt.conf").write_text( + f""" + Apt::Architecture "{arch}"; + Apt::Architectures "{arch}"; + Dir "{tmpdir}"; + Dir::Etc::Trusted "{apttrusted}"; + Dir::Etc::TrustedParts "{apttrustedparts}"; + """ + ) + (tmpdir / "etc" / "apt" / "sources.list").write_text( + "deb http://deb.debian.org/debian/ unstable main" + ) + subprocess.check_call( + ["apt-get", "update"], env={"APT_CONFIG": tmpdir / "apt.conf"} + ) + indextargets = subprocess.check_output( + [ + "apt-get", + "indextargets", + "--format", + "$(FILENAME)", + "Created-By: Packages", + f"Architecture: {arch}", + ], + env={"APT_CONFIG": tmpdir / "apt.conf"}, + ).decode() + if not indextargets.strip(): + print(f"skipping {arch}") + debci_arches.remove(arch) + continue + (tmpdir / "Packages").write_bytes( + subprocess.check_output( + ["/usr/lib/apt/apt-helper", "cat-file", *indextargets.splitlines()] + ) + ) + pkgset = ( + subprocess.check_output( + [ + "grep-dctrl", + "--no-field-names", + "--show-field=Package", + "--exact-match", + "(", + "--field=Essential", + "yes", + "--or", + "--field=Priority", + "required", + "--or", + "--field=Priority", + "important", + "--or", + "--field=Priority", + "standard", + ")", + (tmpdir / "Packages"), + ] + ) + .decode() + .splitlines() + ) + pkgset.extend( + [ + "build-essential", + "busybox", + "gpg", + "eatmydata", + "usr-is-merged", + "usrmerge", + ] + ) + ceve = subprocess.check_output( + [ + "dose-ceve", + f"--deb-native-arch={arch}", + "-c", + ",".join(pkgset), + "-t", + "deb", + "-G", + "pkg", + "-T", + "deb", + (tmpdir / "Packages"), + ] + ) + for pkg in debian.deb822.Packages.iter_paragraphs(ceve): + src = pkg.get("Source") + if src is None: + src = pkg["Package"] + elif " " in src: + src = src.split()[0] + pkglist[src][pkg["Package"]].add(arch) + result = [] + for src in pkglist: + srcarches = set() + for pkg in pkglist[src]: + srcarches |= pkglist[src][pkg] + representers = [pkg for pkg in pkglist[src] if pkglist[src][pkg] == srcarches] + if not representers: + print(f"nothing represents {src}:", pkglist[src]) + continue + pkg = sorted(representers)[0] + if pkglist[src][pkg] == debci_arches: + result.append(pkg) + else: + result.append(f"{pkg} [{' '.join(sorted(pkglist[src][pkg]))}]") + line = "Depends: " + for dep in sorted(result): + newline = line + f"{dep}, " + if len(newline) > 79: + print(line.removesuffix(" ")) + line = f" {dep}, " + else: + line = newline + print(line.removesuffix(", ")) + + +if __name__ == "__main__": + main() |