]>
Commit | Line | Data |
---|---|---|
dfff8bd5 MM |
1 | # vi: encoding=utf-8 ts=8 sts=4 sw=4 et |
2 | ||
b03a96bc MM |
3 | import string |
4 | from chroot import * | |
5 | from util import * | |
6 | ||
7 | __all__ = ['compute_deps', 'remove_list'] | |
8 | ||
9 | def compute_deps(): | |
dfff8bd5 | 10 | """Compute dependenecies between RPM installed on system. |
b03a96bc | 11 | |
dfff8bd5 MM |
12 | Return dictionary from name of package to list of packages required by it. |
13 | Produce some warnings and progress information to stderr. | |
14 | """ | |
15 | # pkg-name -> list of stuff returned by rpm -qR | |
16 | rpm_req = {} | |
17 | # --whatprovides ... | |
18 | rpm_prov = {} | |
19 | # list of required files | |
20 | req_files = {} | |
e6376553 | 21 | |
dfff8bd5 MM |
22 | def get_req(): |
23 | msg("rpm-req... ") | |
24 | f = chr_popen("rpm -qa --qf '@\n%{NAME}\n[%{REQUIRENAME}\n]'") | |
25 | cur_pkg = None | |
26 | while 1: | |
27 | l = f.readline() | |
28 | if l == "": break | |
29 | l = string.strip(l) | |
30 | if l == "@": | |
31 | cur_pkg = string.strip(f.readline()) | |
32 | rpm_req[cur_pkg] = [] | |
33 | continue | |
34 | rpm_req[cur_pkg].append(l) | |
35 | if l[0] == '/': | |
36 | req_files[l] = 1 | |
37 | f.close() | |
38 | msg("done\n") | |
b03a96bc | 39 | |
dfff8bd5 MM |
40 | def add_provides(pkg, what): |
41 | if rpm_prov.has_key(what): | |
42 | msg("[%s: %s, %s] " % (what, rpm_prov[what], pkg)) | |
b03a96bc | 43 | else: |
dfff8bd5 | 44 | rpm_prov[what] = pkg |
e6376553 | 45 | |
dfff8bd5 MM |
46 | def get_prov(): |
47 | msg("rpm-prov... ") | |
48 | f = chr_popen("rpm -qa --qf '@\n%{NAME}\n[%{PROVIDENAME}\n]'") | |
49 | cur_pkg = None | |
50 | while 1: | |
51 | l = f.readline() | |
52 | if l == "": break | |
53 | l = string.strip(l) | |
54 | if l == "@": | |
55 | cur_pkg = string.strip(f.readline()) | |
56 | continue | |
57 | add_provides(cur_pkg, l) | |
58 | if l[0] == '/': | |
59 | # already provided | |
60 | del req_files[l] | |
61 | f.close() | |
62 | msg("done\n") | |
e6376553 | 63 | |
dfff8bd5 MM |
64 | def get_prov_files(): |
65 | msg("rpm-files... ") | |
66 | f = chr_popen("rpm -qa --qf '@\n%{NAME}\n[%{FILENAMES}\n]'") | |
67 | cur_pkg = None | |
68 | while 1: | |
69 | l = f.readline() | |
70 | if l == "": break | |
71 | l = string.strip(l) | |
72 | if l == "@": | |
73 | cur_pkg = string.strip(f.readline()) | |
74 | continue | |
75 | if req_files.has_key(l): | |
76 | add_provides(cur_pkg, l) | |
77 | f.close() | |
78 | msg("done\n") | |
79 | ||
80 | def compute(): | |
81 | msg("computing deps... ") | |
82 | for pkg, reqs in rpm_req.items(): | |
83 | pkg_reqs = [] | |
84 | for req in reqs: | |
85 | if req[0:7] == "rpmlib(": continue | |
86 | if rpm_prov.has_key(req): | |
87 | if rpm_prov[req] not in pkg_reqs: | |
88 | pkg_reqs.append(rpm_prov[req]) | |
89 | else: | |
90 | msg("[%s: %s] " % (pkg, req)) | |
91 | requires[pkg] = pkg_reqs | |
92 | msg("done\n") | |
e6376553 | 93 | |
dfff8bd5 MM |
94 | # map from pkg-name to list of pkg-names required by it |
95 | # this is result | |
96 | requires = {} | |
b03a96bc | 97 | |
dfff8bd5 MM |
98 | get_req() |
99 | get_prov() | |
100 | get_prov_files() | |
101 | compute() | |
102 | return requires | |
b03a96bc MM |
103 | |
104 | def remove_list(req, need): | |
dfff8bd5 | 105 | """List of packages scheduled for removal. |
e6376553 | 106 | |
dfff8bd5 MM |
107 | Given dependency information and list of needed packages compute list |
108 | of packages that don't need to be present. | |
109 | """ | |
110 | need_m = {} | |
111 | def close(n): | |
112 | if need_m.has_key(n): return | |
113 | need_m[n] = 1 | |
114 | if not req.has_key(n): return | |
115 | for k in req[n]: | |
116 | close(k) | |
117 | for n in need: close(n) | |
118 | rm = [] | |
119 | for p in req.keys(): | |
120 | if not need_m.has_key(p): rm.append(p) | |
121 | return rm |