OLD | NEW |
| (Empty) |
1 #!/usr/bin/env python | |
2 | |
3 # Copyright (c) 2009 The Chromium OS Authors. All rights reserved. | |
4 # Use of this source code is governed by a BSD-style license that can be | |
5 # found in the LICENSE file. | |
6 | |
7 from sets import Set | |
8 import subprocess | |
9 import sys | |
10 import time | |
11 | |
12 preferred_virtual_pkg_providers = { | |
13 '<debconf-2.0>': 'debconf', | |
14 '<libgl1>': 'libgl1-mesa-glx', | |
15 '<modutils>': 'module-init-tools', | |
16 '<x-terminal-emulator>': 'xvt', | |
17 '<xserver-xorg-input-4>': 'xserver-xorg-input-kbd', | |
18 '<xserver-xorg-video-5>': 'xserver-xorg-video-dummy' | |
19 } | |
20 | |
21 # if we have a set of packages to choose from, we see if any packages we | |
22 # can choose from are in this list (starting from element 0). if we find a | |
23 # match, we use that, otherwise the script just picks one from the set | |
24 preferred_packages = [ | |
25 'debconf', | |
26 'debconf-english', | |
27 'ttf-bitstream-vera', | |
28 'libgl1-mesa-glx', | |
29 'module-init-tools', | |
30 '<x-terminal-emulator>', | |
31 'xserver-xorg-input-kbd', | |
32 'xserver-xorg-video-dummy', | |
33 '<xserver-xorg-input-4>', | |
34 '<xserver-xorg-video-5>', | |
35 'udev' | |
36 ] | |
37 | |
38 def isVirtualPackage(packagename): | |
39 return packagename.startswith('<') and packagename.endswith('>') | |
40 | |
41 def providerForVirtualPkg(packagename): | |
42 # check for any pre-chosen packages | |
43 if packagename in preferred_virtual_pkg_providers: | |
44 return preferred_virtual_pkg_providers[packagename] | |
45 | |
46 name = packagename.strip('<>') | |
47 lines = subprocess.Popen(['apt-cache', 'showpkg', name], | |
48 stdout=subprocess.PIPE).communicate()[0].split('\n') | |
49 if len(lines) < 2: | |
50 print 'too few lines!', packagename | |
51 sys.exit(1) | |
52 got_reverse_provides_line = False | |
53 for line in lines: | |
54 if got_reverse_provides_line: | |
55 # just take the first one | |
56 provider = line.split(' ')[0] | |
57 if provider == '': | |
58 print 'no provider for', packagename | |
59 sys.exit(1) | |
60 print '"' + provider + '" provides "' + packagename + '"' | |
61 return provider | |
62 got_reverse_provides_line = line.startswith('Reverse Provides:') | |
63 print 'didn\'t find a provider for', packagename | |
64 sys.exit(1) | |
65 | |
66 def getDepsFor(packagename): | |
67 results = subprocess.Popen(['apt-cache', 'depends', packagename], | |
68 stdout=subprocess.PIPE).communicate()[0] | |
69 lines = results.split('\n') | |
70 if len(lines) < 2: | |
71 print 'too few lines!', packagename | |
72 sys.exit(1) | |
73 ret = Set() | |
74 prefix = ' Depends: ' | |
75 # If a package depends on any in a set of packages then each possible package | |
76 # in the set, except for the last one, will have a pipe before Depends. | |
77 # For example: | |
78 # Depends: foo | |
79 # Depends: bar | |
80 # |Depends: baz | |
81 # |Depends: bat | |
82 # |Depends: flower | |
83 # Depends: candle | |
84 # Depends: trunk | |
85 # means this package depends on foo, bar, trunk, and any one of baz, bat, | |
86 # flower, and candle. | |
87 # I couldn't find this documented anywhere. | |
88 set_prefix = ' |Depends: ' | |
89 dep_set = Set() | |
90 for line in lines: | |
91 if line.startswith(set_prefix): | |
92 dep_set.add(line[len(set_prefix):]) | |
93 continue | |
94 if not line.startswith(prefix): | |
95 dep_set.clear() | |
96 continue | |
97 pkgname = line[len(prefix):] | |
98 if len(dep_set) > 0: | |
99 dep_set.add(pkgname) | |
100 # we need to pick one from dep_set | |
101 found_pref = False | |
102 for pref in preferred_packages: | |
103 if pref in dep_set: | |
104 print 'using pref to choose "' + pref + '" from set ' + str(dep_set) | |
105 pkgname = pref | |
106 found_pref = True | |
107 break | |
108 if not found_pref: | |
109 print 'chose "' + pkgname + '" from set ' + str(dep_set) | |
110 dep_set.clear() | |
111 ret.add(pkgname) | |
112 print packagename + ' has deps: ' + str(ret) | |
113 return ret | |
114 | |
115 def main(argv): | |
116 checked = Set() | |
117 unchecked = Set() | |
118 for arg in argv[1:]: | |
119 unchecked.add(arg) | |
120 while True: | |
121 directdeps = Set() | |
122 for pkg in unchecked: | |
123 if isVirtualPackage(pkg): | |
124 pkg = providerForVirtualPkg(pkg) | |
125 directdeps = directdeps.union(getDepsFor(pkg)) | |
126 checked.add(pkg) | |
127 directdeps = directdeps.difference(checked) | |
128 unchecked = directdeps | |
129 if len(unchecked) == 0: | |
130 print 'done' | |
131 checked_list = list(checked) | |
132 checked_list.sort() | |
133 print 'all:', checked_list | |
134 print 'total of ' + str(len(checked_list)) + ' items' | |
135 sys.exit(0) | |
136 | |
137 | |
138 if __name__ == '__main__': | |
139 main(sys.argv) | |
OLD | NEW |