| 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 |