diff -Nru ubuntu-dev-tools-0.173~ubuntu18.04.1~ppa1/debian/changelog ubuntu-dev-tools-0.174~ubuntu18.04.1~ppa1/debian/changelog --- ubuntu-dev-tools-0.173~ubuntu18.04.1~ppa1/debian/changelog 2019-09-11 11:48:24.000000000 +0000 +++ ubuntu-dev-tools-0.174~ubuntu18.04.1~ppa1/debian/changelog 2019-10-03 16:13:55.000000000 +0000 @@ -1,8 +1,32 @@ -ubuntu-dev-tools (0.173~ubuntu18.04.1~ppa1) bionic; urgency=medium +ubuntu-dev-tools (0.174~ubuntu18.04.1~ppa1) bionic; urgency=medium * No-change backport to bionic - -- Gianfranco Costamagna Wed, 11 Sep 2019 13:48:24 +0200 + -- Gianfranco Costamagna Thu, 03 Oct 2019 18:13:55 +0200 + +ubuntu-dev-tools (0.174) unstable; urgency=medium + + [ Stefano Rivera ] + * reverse-depends: + + Support reverse test dependencies as well. LP: #1843614 + * ubuntutools.misc: + + Replace Popen() calls with check_output(). Closes: #940040 + + Use a context manager to open file, to be sure to close them. + + [ Dan Streetman ] + * Update setup.py to also use python3. + * reverse-depends: + + Move from optparse to argparse. + + Rename the typoed --recursive-deph to --recursive-depth. + + Use list comprehensions to simplify del-during-iteration functions. + * import-bug-from-debian: + + Migrate to argparge. + + Add --verbose option. + + Actually make --dry-run do a dry run. + + Handle multiple bug numbers in the command line. + + Correctly get the bug summary. + + -- Mattia Rizzolo Thu, 26 Sep 2019 11:05:53 +0200 ubuntu-dev-tools (0.173) unstable; urgency=medium diff -Nru ubuntu-dev-tools-0.173~ubuntu18.04.1~ppa1/import-bug-from-debian ubuntu-dev-tools-0.174~ubuntu18.04.1~ppa1/import-bug-from-debian --- ubuntu-dev-tools-0.173~ubuntu18.04.1~ppa1/import-bug-from-debian 2019-09-10 12:14:20.000000000 +0000 +++ ubuntu-dev-tools-0.174~ubuntu18.04.1~ppa1/import-bug-from-debian 2019-09-26 08:55:37.000000000 +0000 @@ -1,5 +1,4 @@ #!/usr/bin/python3 -# -*- coding: UTF-8 -*- # Copyright © 2009 James Westby , # 2010, 2011 Stefano Rivera @@ -22,7 +21,8 @@ # # ################################################################## -from optparse import OptionParser, SUPPRESS_HELP +import argparse +import logging import re import sys import webbrowser @@ -42,31 +42,35 @@ def main(): bug_re = re.compile(r"bug=(\d+)") - parser = OptionParser(usage="%prog [option] bug ...") - parser.add_option("-b", "--browserless", - help="Don't open the bug in the browser at the end", - dest="browserless", action="store_true") - parser.add_option("-l", "--lpinstance", metavar="INSTANCE", - help="Launchpad instance to connect to " - "(default: production)", - dest="lpinstance", default=None) - parser.add_option("-n", "--dry-run", - help=SUPPRESS_HELP, - dest="lpinstance", action="store_const", const="staging") - parser.add_option("-p", "--package", metavar="PACKAGE", - help="Launchpad package to file bug against " - "(default: Same as Debian)", - dest="package", default=None) - parser.add_option("--no-conf", dest="no_conf", default=False, - help="Don't read config files or environment variables.", - action="store_true") - (options, args) = parser.parse_args() + parser = argparse.ArgumentParser() + parser.add_argument("-b", "--browserless", action="store_true", + help="Don't open the bug in the browser at the end") + parser.add_argument("-l", "--lpinstance", metavar="INSTANCE", + help="LP instance to connect to (default: production)") + parser.add_argument("-v", "--verbose", action="store_true", + help="Print info about the bug being imported") + parser.add_argument("-n", "--dry-run", action="store_true", + help="Don't actually open a bug (also sets verbose)") + parser.add_argument("-p", "--package", + help="Launchpad package to file bug against " + "(default: Same as Debian)") + parser.add_argument("--no-conf", action="store_true", + help="Don't read config files or environment variables.") + parser.add_argument("bugs", nargs="+", help="Bug number(s) or URL(s)") + options = parser.parse_args() config = UDTConfig(options.no_conf) if options.lpinstance is None: options.lpinstance = config.get_value("LPINSTANCE") - launchpad = Launchpad.login_with("ubuntu-dev-tools", options.lpinstance) + if options.dry_run: + launchpad = Launchpad.login_anonymously("ubuntu-dev-tools") + options.verbose = True + else: + launchpad = Launchpad.login_with("ubuntu-dev-tools", options.lpinstance) + + if options.verbose: + Logger.setLevel(logging.DEBUG) debian = launchpad.distributions['debian'] ubuntu = launchpad.distributions['ubuntu'] @@ -74,7 +78,7 @@ bug_nums = [] - for bug_num in args: + for bug_num in options.bugs: if bug_num.startswith("http"): # bug URL match = bug_re.search(bug_num) @@ -88,33 +92,41 @@ bugs = debianbts.get_status(*bug_nums) - if len(bug_nums) > 1: - bugs = bugs[0] - if not bugs: Logger.error("Cannot find any of the listed bugs") sys.exit(1) + err = False for bug in bugs: ubupackage = package = bug.source if options.package: ubupackage = options.package bug_num = bug.bug_num subject = bug.subject - summary = bug.summary log = debianbts.get_bug_log(bug_num) - summary = log[0]['body'] + summary = log[0]['message'].get_payload() target = ubuntu.getSourcePackage(name=ubupackage) if target is None: Logger.error("Source package '%s' is not in Ubuntu. Please specify " "the destination source package with --package", ubupackage) - sys.exit(1) + err = True + continue + + description = ('Imported from Debian bug http://bugs.debian.org/%d:\n\n%s' % + (bug_num, summary)) - u_bug = launchpad.bugs.createBug( - target=target, title=subject, - description='Imported from Debian bug http://bugs.debian.org/%d:\n\n%s' % - (bug_num, summary)) + Logger.debug('Target: %s' % target) + Logger.debug('Subject: %s' % subject) + Logger.debug('Description: ') + Logger.debug(description) + + if options.dry_run: + Logger.info('Dry-Run: not creating Ubuntu bug.') + continue + + u_bug = launchpad.bugs.createBug(target=target, title=subject, + description=description) d_sp = debian.getSourcePackage(name=package) if d_sp is None and options.package: d_sp = debian.getSourcePackage(name=options.package) @@ -126,6 +138,9 @@ if not options.browserless: webbrowser.open(u_bug.web_link) + if err: + sys.exit(1) + if __name__ == '__main__': main() diff -Nru ubuntu-dev-tools-0.173~ubuntu18.04.1~ppa1/reverse-depends ubuntu-dev-tools-0.174~ubuntu18.04.1~ppa1/reverse-depends --- ubuntu-dev-tools-0.173~ubuntu18.04.1~ppa1/reverse-depends 2019-09-10 12:14:20.000000000 +0000 +++ ubuntu-dev-tools-0.174~ubuntu18.04.1~ppa1/reverse-depends 2019-09-12 12:38:12.000000000 +0000 @@ -14,7 +14,7 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -import optparse +import argparse import sys from distro_info import DistroDataOutdated @@ -35,52 +35,42 @@ Logger.warn(e) default_release = 'unstable' - parser = optparse.OptionParser( - '%prog [options] package', - description="List reverse-dependencies of package. " - "If the package name is prefixed with src: then the " - "reverse-dependencies of all the binary packages that " - "the specified source package builds will be listed.") - parser.add_option('-r', '--release', metavar='RELEASE', - default=default_release, - help='Query dependencies in RELEASE. ' - 'Default: %s' % default_release) - parser.add_option('-R', '--without-recommends', - action='store_false', dest='recommends', default=True, - help='Only consider Depends relationships, ' - 'not Recommends') - parser.add_option('-s', '--with-suggests', - action='store_true', dest='suggests', default=False, - help='Also consider Suggests relationships') - parser.add_option('-b', '--build-depends', - action='store_const', dest='arch', const='source', - help='Query build dependencies (synonym for --arch=source)') - parser.add_option('-a', '--arch', metavar='ARCH', default='any', - help='Query dependencies in ARCH. ' - 'Default: any') - parser.add_option('-c', '--component', metavar='COMPONENT', - action='append', - help='Only consider reverse-dependencies in COMPONENT. ' - 'Can be specified multiple times. Default: all') - parser.add_option('-l', '--list', - action='store_true', default=False, - help='Display a simple, machine-readable list') - parser.add_option('-u', '--service-url', metavar='URL', - dest='server', default=None, - help='Reverse Dependencies webservice URL. ' - 'Default: UbuntuWire') - parser.add_option('-x', '--recursive', - action='store_true', dest='recursive', default=False, - help='Consider to find reverse dependencies recursively.') - parser.add_option('-d', '--recursive-deph', type="int", - metavar='RECURSIVE_DEPTH', dest='recursive_depth', default=DEFAULT_MAX_DEPTH, - help='If recusive, you can specify the depth.') - - options, args = parser.parse_args() - - if len(args) != 1: - parser.error("One (and only one) package must be specified") - package = args[0] + description = ("List reverse-dependencies of package. " + "If the package name is prefixed with src: then the " + "reverse-dependencies of all the binary packages that " + "the specified source package builds will be listed.") + + parser = argparse.ArgumentParser(description=description) + parser.add_argument('-r', '--release', default=default_release, + help='Query dependencies in RELEASE. ' + 'Default: %s' % default_release) + parser.add_argument('-R', '--without-recommends', action='store_false', + dest='recommends', + help='Only consider Depends relationships, ' + 'not Recommends') + parser.add_argument('-s', '--with-suggests', action='store_true', + help='Also consider Suggests relationships') + parser.add_argument('-b', '--build-depends', action='store_true', + help='Query build dependencies (synonym for --arch=source)') + parser.add_argument('-a', '--arch', default='any', + help='Query dependencies in ARCH. Default: any') + parser.add_argument('-c', '--component', action='append', + help='Only consider reverse-dependencies in COMPONENT. ' + 'Can be specified multiple times. Default: all') + parser.add_argument('-l', '--list', action='store_true', + help='Display a simple, machine-readable list') + parser.add_argument('-u', '--service-url', metavar='URL', + dest='server', default=None, + help='Reverse Dependencies webservice URL. ' + 'Default: UbuntuWire') + parser.add_argument('-x', '--recursive', action='store_true', + help='Consider to find reverse dependencies recursively.') + parser.add_argument('-d', '--recursive-depth', type=int, + default=DEFAULT_MAX_DEPTH, + help='If recusive, you can specify the depth.') + parser.add_argument('package') + + options = parser.parse_args() opts = {} if options.server is not None: @@ -98,47 +88,41 @@ # We already printed a warning pass - def query(package): - try: - return query_rdepends(package, options.release, options.arch, **opts) - except RDependsException as e: - Logger.error(str(e)) - sys.exit(1) - - def filter_out_fiels(data, fields): - for field in list(data.keys()): - if field not in fields: - del data[field] - - def filter_out_component(data, component): - for field, rdeps in list(data.items()): - filtered = [rdep for rdep in rdeps - if rdep['Component'] in component] - if not filtered: - del data[field] - else: - data[field] = filtered + if options.build_depends: + options.arch = 'source' if options.arch == 'source': - fields = ['Reverse-Build-Depends', 'Reverse-Build-Depends-Indep'] + fields = [ + 'Reverse-Build-Depends', + 'Reverse-Build-Depends-Indep', + 'Reverse-Build-Depends-Arch', + 'Reverse-Testsuite-Triggers', + ] else: fields = ['Reverse-Depends'] if options.recommends: fields.append('Reverse-Recommends') - if options.suggests: + if options.with_suggests: fields.append('Reverse-Suggests') def build_results(package, result, fields, component, recursive): - data = query(package) + try: + data = query_rdepends(package, options.release, options.arch, **opts) + except RDependsException as e: + Logger.error(str(e)) + sys.exit(1) if not data: return - result[package] = data - if fields: - filter_out_fiels(result[package], fields) + data = {k: v for k, v in data.items() if k in fields} if component: - filter_out_component(result[package], component) + data = {k: [rdep for rdep in v + if rdep['Component'] in component] + for k, v in data.items()} + data = {k: v for k, v in data.items() if v} + + result[package] = data if recursive > 0: for rdeps in result[package].values(): @@ -148,13 +132,13 @@ result = {} build_results( - package, result, fields, options.component, + options.package, result, fields, options.component, options.recursive and options.recursive_depth or 0) if options.list: display_consise(result) else: - display_verbose(package, result) + display_verbose(options.package, result) def display_verbose(package, values): diff -Nru ubuntu-dev-tools-0.173~ubuntu18.04.1~ppa1/setup.py ubuntu-dev-tools-0.174~ubuntu18.04.1~ppa1/setup.py --- ubuntu-dev-tools-0.173~ubuntu18.04.1~ppa1/setup.py 2019-09-10 12:14:20.000000000 +0000 +++ ubuntu-dev-tools-0.174~ubuntu18.04.1~ppa1/setup.py 2019-09-12 12:35:37.000000000 +0000 @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 from setuptools import setup import glob diff -Nru ubuntu-dev-tools-0.173~ubuntu18.04.1~ppa1/ubuntutools/misc.py ubuntu-dev-tools-0.174~ubuntu18.04.1~ppa1/ubuntutools/misc.py --- ubuntu-dev-tools-0.173~ubuntu18.04.1~ppa1/ubuntutools/misc.py 2019-09-10 12:14:20.000000000 +0000 +++ ubuntu-dev-tools-0.174~ubuntu18.04.1~ppa1/ubuntutools/misc.py 2019-09-26 09:05:05.000000000 +0000 @@ -23,10 +23,10 @@ # ################################################################## # Modules. -from subprocess import Popen, PIPE import locale import os import sys +from subprocess import check_output, CalledProcessError import distro_info @@ -47,29 +47,22 @@ global _system_distribution_chain if len(_system_distribution_chain) == 0: try: - p = Popen(('dpkg-vendor', '--query', 'Vendor'), - stdout=PIPE, encoding='utf-8') - _system_distribution_chain.append(p.communicate()[0].strip()) - except OSError: + vendor = check_output(('dpkg-vendor', '--query', 'Vendor'), + encoding='utf-8').strip() + _system_distribution_chain.append(vendor) + except CalledProcessError: print('Error: Could not determine what distribution you are running.') return [] while True: try: - p = Popen(('dpkg-vendor', - '--vendor', _system_distribution_chain[-1], - '--query', 'Parent'), - stdout=PIPE, encoding='utf-8') - parent = p.communicate()[0].strip() - # Don't check return code, because if a vendor has no - # parent, dpkg-vendor returns 1 - if not parent: - break - _system_distribution_chain.append(parent) - except Exception: - print(('Error: Could not determine the parent of the ' - 'distribution %s' % _system_distribution_chain[-1])) - return [] + parent = check_output(( + 'dpkg-vendor', '--vendor', _system_distribution_chain[-1], + '--query', 'Parent'), encoding='utf-8').strip() + except CalledProcessError: + # Vendor has no parent + break + _system_distribution_chain.append(parent) return _system_distribution_chain @@ -91,14 +84,18 @@ architecture can't be determined, print an error message and return None. """ - arch = Popen(['dpkg', '--print-architecture'], stdout=PIPE, - stderr=PIPE).communicate()[0].split() - - if not arch or 'not found' in arch[0]: - print('Error: Not running on a Debian based system; could not detect its architecture.') + try: + arch = check_output(('dpkg', '--print-architecture'), + encoding='utf-8').strip() + except CalledProcessError: + arch = None + + if not arch or 'not found' in arch: + print('Error: Not running on a Debian based system; ' + 'could not detect its architecture.') return None - return arch[0] + return arch def readlist(filename, uniq=True): @@ -112,7 +109,8 @@ print('File "%s" does not exist.' % filename) return False - content = open(filename).read().replace('\n', ' ').replace(',', ' ') + with open(filename) as f: + content = f.read().replace('\n', ' ').replace(',', ' ') if not content.strip(): print('File "%s" is empty.' % filename)