#!/usr/bin/python2.7 # Copyright (C) 2012 Canonical, Ltd. # Author: Brian Murray # 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 of the License. # # 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, see . # given a release find all the packages published in proposed and # search each package for bug tasks about the package reported # since the date the package was uploaded to proposed for apport and release # tagged bugs that contain the version of the package from -proposed from __future__ import print_function import optparse from launchpadlib.launchpad import Launchpad try: from urllib.request import urlopen except ImportError: from urllib import urlopen def bugs_from_changes(change_url): '''Return (bug_list, cve_list) from a .changes file URL''' changelog = urlopen(change_url) refs = [] bugs = set() for l in changelog: if l.startswith('Launchpad-Bugs-Fixed: '): refs = l.split()[1:] break for b in refs: try: lpbug = lp.bugs[int(b)] except KeyError: continue bugs.add(lpbug) return sorted(bugs) if __name__ == '__main__': APPORT_TAGS = ( 'apport-package', 'apport-bug', 'apport-crash', 'apport-kerneloops', ) lp = Launchpad.login_with( 'ubuntu-archive-tools', 'production', version='devel') ubuntu = lp.distributions['ubuntu'] archive = ubuntu.getArchive(name='primary') parser = optparse.OptionParser(usage="usage: %prog --release RELEASE") parser.add_option('--release', help='', dest='release') (opt, args) = parser.parse_args() releases = {} if not opt.release: for series in ubuntu.series: if not series.supported: continue if series.active: releases[series.name] = series else: series = ubuntu.getSeries(name_or_version=opt.release) releases[series.name] = series for release in sorted(releases): print('Release: %s' % release) for spph in archive.getPublishedSources( pocket='Proposed', status='Published', distro_series=releases[release]): package_name = spph.source_package_name # for langpack updates, only keep -en as a representative # cargo-culted from sru-report if (package_name.startswith('language-pack-') and package_name not in ('language-pack-en', 'language-pack-en-base')): continue date_pub = spph.date_published version = spph.source_package_version change_url = spph.changesFileUrl() if not change_url: print("Package %s has no changes file url") continue package = ubuntu.getSourcePackage(name=package_name) tasks = [] # search for bugs reported by apport for tag in APPORT_TAGS: for task in package.searchTasks( tags=[tag, release], created_since=date_pub, tags_combinator='All'): tasks.append(task) # also search for ones tagged regression-proposed for task in package.searchTasks( tags=['regression-proposed', release], created_since=date_pub, tags_combinator='All'): tasks.append(task) for task in tasks: if version not in task.bug.description: continue sru_bugs = bugs_from_changes(change_url) # check to see if any of the sru bugs are already tagged # verification-failed v_failed = False for sru_bug in sru_bugs: if 'verification-failed' in sru_bug.tags: print(' The SRU for package %s already has a ' 'verification-failed bug in LP: #%s' % (package_name, sru_bug.id)) v_failed = True bug = task.bug if not v_failed and set(APPORT_TAGS).intersection(bug.tags): print(' LP: #%s is regarding %s from -proposed' % (bug.id, package_name)) elif not v_failed: print(' LP: #%s is regarding %s from -proposed and ' 'tagged regression-proposed' % (bug.id, package_name))