#!/usr/bin/python3 # # Check components of build dependencies and warn about universe/multiverse # ones, for a package destined for main/restricted # # Copyright (C) 2011 Canonical # # Authors: # Martin Pitt # # 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; version 3. # # 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. # # You should have received a copy of the GNU General Public License along with # this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA import sys import optparse import os.path import apt def check_support(apt_cache, pkgname, alt=False): '''Check if pkgname is in main or restricted. This prints messages if a package is not in main/restricted, or only partially (i. e. source in main, but binary in universe). ''' if alt: prefix = ' ... alternative ' + pkgname else: prefix = ' * ' + pkgname try: pkg = apt_cache[pkgname] except KeyError: print(prefix, 'does not exist (pure virtual?)', file=sys.stderr) return False section = pkg.candidate.section if section.startswith('universe') or section.startswith('multiverse'): # check if the source package is in main and thus will only need binary # promotion source_records = apt.apt_pkg.SourceRecords() if not source_records.lookup(pkg.candidate.source_name): print('ERROR: Cannot lookup source package for', pkg.name, file=sys.stderr) print(prefix, 'package is in', section.split('/')[0]) return False src = apt.apt_pkg.TagSection(source_records.record) if (src['Section'].startswith('universe') or src['Section'].startswith('multiverse')): print(prefix, 'binary and source package is in', section.split('/')[0]) return False else: print(prefix, 'is in', section.split('/')[0] + ', but its source', pkg.candidate.source_name, 'is already in main; file an ubuntu-archive bug for ' 'promoting the current preferred alternative') return True if alt: print(prefix, 'is already in main; consider preferring it') return True def check_build_dependencies(apt_cache, control): print('Checking support status of build dependencies...') any_unsupported = False for field in ('Build-Depends', 'Build-Depends-Indep'): if field not in control.section: continue for or_group in apt.apt_pkg.parse_src_depends(control.section[field]): pkgname = or_group[0][0] if not check_support(apt_cache, pkgname): # check non-preferred alternatives for altpkg in or_group[1:]: if check_support(apt_cache, altpkg[0], alt=True): break else: any_unsupported = True return any_unsupported def check_binary_dependencies(apt_cache, control): any_unsupported = False print('\nChecking support status of binary dependencies...') while True: try: next(control) except StopIteration: break for field in ('Depends', 'Pre-Depends', 'Recommends'): if field not in control.section: continue for or_group in apt.apt_pkg.parse_src_depends( control.section[field]): pkgname = or_group[0][0] if pkgname.startswith('$'): continue if not check_support(apt_cache, pkgname): # check non-preferred alternatives for altpkg in or_group[1:]: if check_support(apt_cache, altpkg[0], alt=True): break else: any_unsupported = True return any_unsupported def main(): description = "Check if any of a package's build or binary " + \ "dependencies are in universe or multiverse. " + \ "Run this inside an unpacked source package" parser = optparse.OptionParser(description=description) parser.parse_args() apt_cache = apt.Cache() if not os.path.exists('debian/control'): print('debian/control not found. You need to run this tool in a ' 'source package directory', file=sys.stderr) sys.exit(1) # get build dependencies from debian/control control = apt.apt_pkg.TagFile(open('debian/control')) next(control) unsupported_build_deps = check_build_dependencies(apt_cache, control) unsupported_binary_deps = check_binary_dependencies(apt_cache, control) if unsupported_build_deps or unsupported_binary_deps: print('\nPlease check https://wiki.ubuntu.com/MainInclusionProcess if ' 'this source package needs to get into in main/restricted, or ' 'reconsider if the package really needs above dependencies.') else: print('All dependencies are supported in main or restricted.') if __name__ == '__main__': main()