#!/usr/bin/python # -*- coding: utf-8 -*- # # Copyright 2006-2007 (C) Pete Savage <petesavage@ubuntu.com> # Copyright 2007 (C) Siegfried-A. Gevatter <rainct@ubuntu.com> # Copyright 2009 (C) Canonical Ltd. (by Colin Watson <cjwatson@ubuntu.com>) # # ################################################################## # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # See file /usr/share/common-licenses/GPL for more details. # # ################################################################## # # This script is used to check if a package and all its build # dependencies are in main or not. import sys import apt_pkg import apt from ubuntutools import subprocess def process_deps(cache, deps): """Takes a list of (build) dependencies and processes it.""" for basedep in [d.or_dependencies[0] for d in deps]: if not packages.has_key(basedep.name) and basedep.name != '': # Check the (build) dependencies recursively find_main(cache, basedep.name) def get_package_version(cache, distro, pack): if pack not in cache: return None for version in (cache[pack].candidate, cache[pack].installed): if not version: continue for origin in version.origins: if origin.archive == distro: return version return None # Cache::CompTypeDeb isn't exposed via python-apt def comp_type_deb(op): ops = ("", "<=", ">=", "<<", ">>", "=", "!=") if (op & 15) < 7: return ops[op & 15] return "" def find_main(cache, pack): """Searches the dependencies and build dependencies of a package recursively to determine if they are all in the 'main' component or not.""" global packages if pack in packages: return # Retrieve information about the package version = get_package_version(cache, distro, pack) if not version: packages[pack] = False return elif [origin for origin in version.origins if origin.component == 'main']: packages[pack] = True return else: if not packages.has_key(pack): packages[pack] = False # Retrieve package dependencies process_deps(cache, version.dependencies) # Retrieve package build dependencies. There's no handy # attribute on version for this, so unfortunately we have to # do a lot of messing about with apt. deps = [] src_records = apt_pkg.SourceRecords() got_src = False while src_records.lookup(version.source_name): if pack in src_records.binaries: got_src = True break if got_src: # pylint: disable=E1101 for _, all_deps in src_records.build_depends.iteritems(): # pylint: enable=E1101 for or_deps in all_deps: base_deps = [] for (name, ver, op) in or_deps: base_deps.append(apt.package.BaseDependency(name, op, ver, False)) deps.append(apt.package.Dependency(base_deps)) process_deps(cache, deps) def usage(exit_code): print 'Usage: %s <package name> [<distribution>]' % sys.argv[0] sys.exit(exit_code) def main(): global packages, distro # Check if the amount of arguments is correct if len(sys.argv) > 1 and sys.argv[1] in ('help', '-h', '--help'): usage(0) if len(sys.argv) < 2 or len(sys.argv) > 3: usage(1) cache = apt.cache.Cache() if len(sys.argv) == 3 and sys.argv[2]: distro = sys.argv[2] if not get_package_version(cache, distro, 'bash'): print '«%s» is not a valid distribution.' % distro print ('Remember that for 404main to work with a certain ' 'distribution it must be in your /etc/apt/sources.list ' 'file.') sys.exit(1) else: cmd = ['lsb_release', '-cs'] process = subprocess.Popen(cmd, stdout=subprocess.PIPE) distro = process.stdout.read().strip('\n') if not get_package_version(cache, distro, sys.argv[1]): print 'Can\'t find package «%s» in distribution «%s».' % \ (sys.argv[1], distro) sys.exit(1) print 'Checking package «%s» in distribution «%s»...' % \ (sys.argv[1], distro) find_main(cache, sys.argv[1]) # True if everything checked until the point is in main all_in_main = True for package in packages: if not packages[package]: if all_in_main: print 'The following packages aren\'t in main:' all_in_main = False print ' ', package if all_in_main: print ('Package «%s» and all its dependencies and build dependencies ' 'are in main.') % sys.argv[1] if __name__ == '__main__': # Global variable to hold the status of all packages packages = {} # Global variable to hold the target distribution distro = '' try: main() except KeyboardInterrupt: print 'Aborted.' sys.exit(1)