-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathwhich-pkg-broke
executable file
·112 lines (95 loc) · 2.97 KB
/
which-pkg-broke
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#! /usr/bin/python
# which-pkg-broke: help find offending packages when something breaks
# Placed in the public domain by Bill Gribble <[email protected]>
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)