Codebase list debian-goodies / debian/0.64 which-pkg-broke
debian/0.64

Tree @debian/0.64 (Download .tar.gz)

which-pkg-broke @debian/0.64

d4335bb
 
 
 
 
 
20cc60a
d4335bb
 
 
 
 
20cc60a
 
 
 
 
d4335bb
20cc60a
d4335bb
 
 
 
154a0c8
2f846bf
d4335bb
20cc60a
 
d4335bb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c248760
 
 
 
 
98ec55c
 
 
c248760
 
 
 
 
 
 
 
 
 
 
 
 
 
98ec55c
c248760
 
 
98ec55c
c248760
98ec55c
 
 
217caba
98ec55c
 
 
 
 
 
217caba
98ec55c
 
 
d4335bb
 
 
 
 
 
 
 
c248760
 
d4335bb
 
c248760
d4335bb
 
 
 
 
 
 
0c5e846
d4335bb
 
 
 
#! /usr/bin/python
#  which-pkg-broke: help find offending packages when something breaks
#  Placed in the public domain by Bill Gribble <grib@billgribble.com>

import sys
import os
import subprocess
import time
from string import *
from stat import *

def pkgdeps(pkg):
    apt_cache = subprocess.Popen(
        ['apt-cache', 'depends', pkg],
        stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
        env={} # force POSIX locale
    )
    deps = []
    myline = apt_cache.stdout.readline()
    while(myline != ''):
        elts = map(strip, myline.split(':'))
        if len(elts) == 2:
            how, pkg = elts
            how = how.replace('|', '')
            if how in ('Depends', 'PreDepends'):
                deps.append(pkg)
        myline = apt_cache.stdout.readline()
    apt_cache.wait()
    return deps

def alldeps(pkg, ignore):
    deps = {}
    imm_deps = pkgdeps(pkg)
    for i in imm_deps:
        if ignore.get(i) is None:
            deps[i] = 1
            ignore[i] = 1
            childeps = alldeps(i, ignore)
            for c in childeps:
                deps[c] = 1
                ignore[i] = 1

    dlist = deps.keys()
    return dlist


def localarchitectures():
    architectures = []
    dpkg_arch = subprocess.Popen(
        ['dpkg', '--print-architecture'],
        stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
        env={} # force POSIX locale
    )
    for arch in dpkg_arch.stdout.readlines():
        architectures.append(arch.rstrip())

    try:
        dpkg_archs = subprocess.Popen(
            ['dpkg', '--print-foreign-architecture'],
            stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
            env={} # force POSIX locale
            )
        for arch in dpkg_archs.stdout.readlines():
            architectures.append(arch.rstrip())

    except OSError:
        pass # non-multiarchy dpkg, which is ok

    return architectures

def pkginstalltime(pkg, architectures):
    times = []
    for arch in architectures:
        listfile = '/var/lib/dpkg/info/' + pkg + ':' + arch + '.list'
        try:
            times.append([pkg + ':' + arch, os.stat(listfile)[ST_MTIME]])
        except OSError:
            pass

    if not times:
        listfile = '/var/lib/dpkg/info/' + pkg + '.list'
        try:
            times.append([pkg, os.stat(listfile)[ST_MTIME]])
        except OSError:
            print "Package", pkg, "has no install time info"

    return times

def what_broke(pname):
    def sortfun(a, b):
        return cmp(a[1], b[1])

    pkgs = [ pname ]
    pkgs.extend(alldeps(sys.argv[1], {}))

    architectures = localarchitectures()

    itimes = []
    for p in pkgs:
        itimes.extend(pkginstalltime(p, architectures))
    itimes.sort(sortfun)
    for i in itimes:
        p, t = i
        if t is not None:
            print ljust(p, 54), time.asctime(time.localtime(float(t)))

if (len(sys.argv) != 2 or sys.argv[1][0] == '-'):
    print "Usage: which-pkg-broke <pkg-name>"
    sys.exit(-1)
else:
    what_broke(sys.argv[1])
    sys.exit(0)