HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Finding unique/obsolete binary Debian packages

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
uniqueobsoletedebianbinaryfindingpackages

Problem

I have a script I use to prune packages that have gone stale from my custom Debian repository (i.e. they no longer exists on any of the official repositories):

import apt_pkg
import gzip
import subprocess

CUSTOM_REPO = ("/home/tshepang/.custom_repo/dists/tshepang/main/"
               "binary-amd64/Packages.gz")
TEMPLATE = ("/var/lib/apt/lists/http.debian.net_debian_dists_{}_{}_"
            "binary-amd64_Packages")
CODENAMES = 'jessie sid experimental'.split()
ARCHIVE_AREAS = "main contrib non-free".split()

def main():
    custom_repo = apt_pkg.TagFile(gzip.open(CUSTOM_REPO))
    wheezy_packages = list()
    for codename in CODENAMES:
        for archive_area in ARCHIVE_AREAS:
            repo = TEMPLATE.format(codename, archive_area)
            repo = apt_pkg.TagFile(gzip.open(repo, "rb"))
            wheezy_packages.extend([pkg["Package"] for pkg in repo])
    for package in custom_repo:
        package_name = package["Package"]
        if package_name not in wheezy_packages:
            cmd = "apt-cache policy " + package_name
            subprocess.call(cmd.split())
            choice = raw_input("remove from cache [Y/n]? ")
            if not choice or choice.lower().startswith("y"):
                cmd = ("reprepro -vv --basedir /home/tshepang/.custom_repo/ "
                       "remove tshepang " + package_name)
                subprocess.call(cmd.split())

if __name__ == "__main__":
    main()


I strongly suspect the code can be better.

As a sidenote, here is sample UI:

apache2.2-common:
Installed: (none)
Candidate: 2.2.22-13
Version table:
2.2.22-13 0
500 file:/home/tshepang/.custom_repo/ tshepang/main amd64 Packages
remove from cache [Y/n]?
removing 'apache2.2-common' from 'tshepang|main|amd64'...
Exporting indices...
Deleting files no longer referenced...
deleting and forgetting pool/main/a/apache2/apache2.2-common_2.2.22-13_amd64.deb

Solution

Your code looks very good, so I'll just propose some minor (and subjective) improvements:

-
Imports: PEP8 has some recommendations about grouping imports that sound pretty reasonable.

-
("s1" "s2"): I don't know what the orthodoxy says, but I prefer an explicit + in between.

-
list(): Why not []?

-
wheezy_packages.extend([pkg["Package"] for pkg in repo]) -> wheezy_packages.extend(pkg["Package"] for pkg in repo).

-
repo = a, then repo = f(repo). IMHO this is as common a pattern as is undesirable. Different values deserve different variable names (key point of functional programming).

-
Function too long: I'd split the code in at least two auxiliary functions, one to get wheezy_packages and another to run the commands.

Context

StackExchange Code Review Q#29318, answer score: 2

Revisions (0)

No revisions yet.