From 26d68da79132d873573c76d06d2af427c28ba81b Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Wed, 24 Aug 2011 17:46:23 +0200 Subject: [PATCH 1/7] Detect bugs to be closed (but don't do anything with the list yet) --- syncpackage | 55 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 12 deletions(-) diff --git a/syncpackage b/syncpackage index dafaf81..e3a6687 100755 --- a/syncpackage +++ b/syncpackage @@ -36,11 +36,13 @@ from lazr.restfulclient.errors import HTTPError from ubuntutools.archive import (DebianSourcePackage, UbuntuSourcePackage, DownloadError) from ubuntutools.config import UDTConfig, ubu_email +from ubuntutools.requestsync.common import getDebianChangelog from ubuntutools.requestsync.mail import (getDebianSrcPkg as requestsync_mail_getDebianSrcPkg) from ubuntutools.requestsync.lp import getDebianSrcPkg, getUbuntuSrcPkg from ubuntutools.lp import udtexceptions -from ubuntutools.lp.lpapicache import Distribution, Launchpad +from ubuntutools.lp.lpapicache import (Distribution, Launchpad, + SourcePackagePublishingHistory) from ubuntutools.misc import split_release_pocket from ubuntutools.question import YesNoQuestion from ubuntutools import subprocess @@ -101,7 +103,7 @@ def add_fixed_bugs(changes, bugs): changes = [l for l in changes.split("\n") if l.strip() != ""] # Remove duplicates - bugs = set(bugs) + bugs = set(str(bug) for bug in bugs) for i in xrange(len(changes)): if changes[i].startswith("Launchpad-Bugs-Fixed:"): @@ -309,7 +311,7 @@ def fetch_source_pkg(package, dist, version, component, ubuntu_release, mirror): return DebianSourcePackage(package, version.full_version, component, mirrors=mirrors) -def copy(src_pkg, release, simulate=False, force=False): +def copy(src_pkg, release, bugs, simulate=False, force=False): """Copy a source package from Debian to Ubuntu using the Launchpad API.""" ubuntu = Distribution('ubuntu') debian_archive = Distribution('debian').getArchive() @@ -322,10 +324,12 @@ def copy(src_pkg, release, simulate=False, force=False): # Ensure that the provided Debian version actually exists. try: - debian_archive.getPublishedSources( - source_name=src_pkg.source, - version=src_pkg.version.full_version, - exact_match=True)[0] + debian_spph = SourcePackagePublishingHistory( + debian_archive.getPublishedSources( + source_name=src_pkg.source, + version=src_pkg.version.full_version, + exact_match=True)[0] + ) except IndexError: Logger.error('Debian version %s does not exist!', src_pkg.version) sys.exit(1) @@ -343,6 +347,7 @@ def copy(src_pkg, release, simulate=False, force=False): ubuntu_pkg.version, src_pkg.version) ubuntu_version = Version(ubuntu_pkg.version.full_version) + base_version = ubuntu_version.get_related_debian_version() if not force and ubuntu_version.is_modified_in_ubuntu(): Logger.error('--force is required to discard Ubuntu changes.') sys.exit(1) @@ -355,9 +360,23 @@ def copy(src_pkg, release, simulate=False, force=False): 'mismatch. A fake sync using --no-lp is required.') sys.exit(1) except udtexceptions.PackageNotFoundException: + base_version = None Logger.normal('Source %s -> %s/%s: not in Ubuntu, new version %s', src_pkg.source, ubuntu_series, ubuntu_pocket, src_pkg.version) + + changes = getDebianChangelog(debian_spph, base_version).strip() + if changes: + Logger.normal("New Changes:\n%s", changes) + bugs += bugs_from_changes(changes) + bugs = sorted(set(bugs)) + else: + Logger.error("Unable to determine changes, Launchpad bugs closed in " + "the changelog will not be closed. ") + Logger.error("To close them manually, use the --bug option") + Logger.normal("LP Bugs to be closed: %s", + ', '.join(str(bug) for bug in bugs)) + if simulate: return @@ -407,6 +426,17 @@ def is_blacklisted(query): applicable_comments.append(comment) return False +def bugs_from_changes(changes): + """Return a list of all LP bugs closed by changes""" + # From sync-source.py: + re_lp_closes = re.compile(r"lp:\s+\#\d+(?:,\s*\#\d+)*", re.I) + re_bug_numbers = re.compile(r"\#?\s?(\d+)") + closes = [] + for match in re_lp_closes.finditer(changes): + bug_match = re_bug_numbers.findall(match.group(0)) + closes.extend(map(int, bug_match)) + return closes + def main(): usage = "%prog [options] <.dsc URL/path or package name>" epilog = "See %s(1) for more info." % os.path.basename(sys.argv[0]) @@ -483,10 +513,10 @@ def main(): parser.error('Multiple .dsc URLs/paths or package names specified: ' + ', '.join(args)) - invalid_bug_numbers = [bug for bug in options.bugs if not bug.isdigit()] - if len(invalid_bug_numbers) > 0: - parser.error('Invalid bug number(s) specified: ' - + ', '.join(invalid_bug_numbers)) + try: + options.bugs = map(int, options.bugs) + except TypeError, e: + parser.error('Invalid bug number(s) specified') if options.component not in (None, "main", "contrib", "non-free"): parser.error('%s is not a valid Debian component. ' @@ -539,7 +569,8 @@ def main(): sys.exit(1) if options.lp: - copy(src_pkg, options.release, options.simulate, options.force) + copy(src_pkg, options.release, options.bugs, options.simulate, + options.force) else: os.environ['DEB_VENDOR'] = 'Ubuntu' sync_dsc(src_pkg, options.dist, options.release, options.uploader_name, From ed6962c41311275e8e2d79ff5f50edba7755b92b Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Wed, 24 Aug 2011 19:38:16 +0200 Subject: [PATCH 2/7] Close bugs after syncing --- syncpackage | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/syncpackage b/syncpackage index e3a6687..3a05b95 100755 --- a/syncpackage +++ b/syncpackage @@ -360,7 +360,7 @@ def copy(src_pkg, release, bugs, simulate=False, force=False): 'mismatch. A fake sync using --no-lp is required.') sys.exit(1) except udtexceptions.PackageNotFoundException: - base_version = None + base_version = Version('~') Logger.normal('Source %s -> %s/%s: not in Ubuntu, new version %s', src_pkg.source, ubuntu_series, ubuntu_pocket, src_pkg.version) @@ -400,6 +400,11 @@ def copy(src_pkg, release, bugs, simulate=False, force=False): Logger.normal('Request succeeded; you should get an e-mail once it is ' 'processed.') + Logger.normal('Please wait for the sync to be successuful before ' + 'closing bugs') + answer = YesNoQuestion().ask("Close bugs?", "yes") + if answer == "yes": + close_bugs(bugs, src_pkg.source, src_pkg.version.full_version, changes) def is_blacklisted(query): """"Determine if package "query" is in the sync blacklist @@ -437,6 +442,30 @@ def bugs_from_changes(changes): closes.extend(map(int, bug_match)) return closes +def close_bugs(bugs, package, version, changes): + """Close the correct task on all bugs, with changes""" + ubuntu = Launchpad.distributions['ubuntu'] + message = ("This bug was fixed in the package %s - %s" + "\n\n---------------\n%s" % ( + package, version, changes)) + for bug in bugs: + bug = Launchpad.bugs[bug] + if bug.duplicate_of is not None: + bug = bug.duplicate_of + for task in bug.bug_tasks: + target = task.target + if getattr(target, 'distribution', None) != ubuntu: + continue + if target == ubuntu or target.name == package: + if task.status != 'Fix Released': + Logger.normal("Closed bug %s", task.web_link) + task.status = 'Fix Released' + task.lp_save() + bug.newMessage(content=message) + break + else: + Logger.error(u"Cannot find any tasks on LP: #%i to close", bug.id) + def main(): usage = "%prog [options] <.dsc URL/path or package name>" epilog = "See %s(1) for more info." % os.path.basename(sys.argv[0]) @@ -515,7 +544,7 @@ def main(): try: options.bugs = map(int, options.bugs) - except TypeError, e: + except TypeError: parser.error('Invalid bug number(s) specified') if options.component not in (None, "main", "contrib", "non-free"): From 165279fae992c971cb49d7d83b233f40d41f0517 Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Wed, 24 Aug 2011 23:48:48 +0200 Subject: [PATCH 3/7] TODO note on getDebianChangelog --- ubuntutools/requestsync/common.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ubuntutools/requestsync/common.py b/ubuntutools/requestsync/common.py index e9f7c12..8ea450b 100644 --- a/ubuntutools/requestsync/common.py +++ b/ubuntutools/requestsync/common.py @@ -38,9 +38,11 @@ def raw_input_exit_on_ctrlc(*args, **kwargs): print '\nAbort requested. No sync request filed.' sys.exit(1) +# TODO: Move this into requestsync.mail, and implement an LP version +# when LP: #833384 is fixed def getDebianChangelog(srcpkg, version): ''' - Return the new changelog entries upto 'version'. + Return the new changelog entries since 'version'. ''' pkgname = srcpkg.getPackageName() pkgversion = srcpkg.getVersion() From 59b69d3767c385fffe7643f1c0d92a6c4d194352 Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Thu, 25 Aug 2011 18:41:57 +0200 Subject: [PATCH 4/7] Correcly handle NEW package bug closing (the task dosen't have a distribuiton attribute) --- syncpackage | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/syncpackage b/syncpackage index 3a05b95..a5049d9 100755 --- a/syncpackage +++ b/syncpackage @@ -454,9 +454,9 @@ def close_bugs(bugs, package, version, changes): bug = bug.duplicate_of for task in bug.bug_tasks: target = task.target - if getattr(target, 'distribution', None) != ubuntu: - continue - if target == ubuntu or target.name == package: + if (target.name == package + and getattr(target, 'distribution', None) == ubuntu + ) or target == ubuntu: if task.status != 'Fix Released': Logger.normal("Closed bug %s", task.web_link) task.status = 'Fix Released' From 2b074fb5816b0e0144ef0d2daffdb3c941e8b97c Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Sat, 3 Sep 2011 20:49:35 +0200 Subject: [PATCH 5/7] Don't look for bugs closed in Debian changes, only close bugs mentioned on the command line --- syncpackage | 33 +++++++++------------------------ 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/syncpackage b/syncpackage index a5049d9..dc060ae 100755 --- a/syncpackage +++ b/syncpackage @@ -368,14 +368,6 @@ def copy(src_pkg, release, bugs, simulate=False, force=False): changes = getDebianChangelog(debian_spph, base_version).strip() if changes: Logger.normal("New Changes:\n%s", changes) - bugs += bugs_from_changes(changes) - bugs = sorted(set(bugs)) - else: - Logger.error("Unable to determine changes, Launchpad bugs closed in " - "the changelog will not be closed. ") - Logger.error("To close them manually, use the --bug option") - Logger.normal("LP Bugs to be closed: %s", - ', '.join(str(bug) for bug in bugs)) if simulate: return @@ -400,11 +392,15 @@ def copy(src_pkg, release, bugs, simulate=False, force=False): Logger.normal('Request succeeded; you should get an e-mail once it is ' 'processed.') - Logger.normal('Please wait for the sync to be successuful before ' - 'closing bugs') - answer = YesNoQuestion().ask("Close bugs?", "yes") - if answer == "yes": - close_bugs(bugs, src_pkg.source, src_pkg.version.full_version, changes) + bugs = sorted(set(bugs)) + if bugs: + Logger.normal("LP Bugs to be closed: %s", + ', '.join(str(bug) for bug in bugs)) + Logger.normal('Please wait for the sync to be successuful before ' + 'closing bugs') + answer = YesNoQuestion().ask("Close bugs?", "yes") + if answer == "yes": + close_bugs(bugs, src_pkg.source, src_pkg.version.full_version, changes) def is_blacklisted(query): """"Determine if package "query" is in the sync blacklist @@ -431,17 +427,6 @@ def is_blacklisted(query): applicable_comments.append(comment) return False -def bugs_from_changes(changes): - """Return a list of all LP bugs closed by changes""" - # From sync-source.py: - re_lp_closes = re.compile(r"lp:\s+\#\d+(?:,\s*\#\d+)*", re.I) - re_bug_numbers = re.compile(r"\#?\s?(\d+)") - closes = [] - for match in re_lp_closes.finditer(changes): - bug_match = re_bug_numbers.findall(match.group(0)) - closes.extend(map(int, bug_match)) - return closes - def close_bugs(bugs, package, version, changes): """Close the correct task on all bugs, with changes""" ubuntu = Launchpad.distributions['ubuntu'] From d889f5af5a1b4716b28ed89a5dd33f62580c2b64 Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Sat, 3 Sep 2011 21:08:02 +0200 Subject: [PATCH 6/7] Changelog entry --- debian/changelog | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 8a77a29..b9a52e6 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,10 +1,16 @@ -ubuntu-dev-tools (0.129) UNRELEASED; urgency=low +ubuntu-dev-tools (0.129) oneiric; urgency=low + [ Colin Watson ] * syncpackage: Convert to new LP API, with --no-lp available for the old style of operation. * syncpackage: Require -f/--force option to overwrite Ubuntu changes. - -- Colin Watson Tue, 16 Aug 2011 16:40:22 +0100 + [ Stefano Rivera ] + * syncpackage: Show changes to be synced when performing native syncs. + * syncpackage: Support --bug (extra bugs to be closed by the sync) with + native syncs. (Bugs are closed one individually, via the API, post-sync) + + -- Stefano Rivera Sat, 03 Sep 2011 21:04:38 +0200 ubuntu-dev-tools (0.128) unstable; urgency=low From 8b273361cb4360456708281aa6ee329162e453c3 Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Sat, 3 Sep 2011 22:04:36 +0200 Subject: [PATCH 7/7] Changelog back to UNRELEASED --- debian/changelog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 22d5288..f6442d3 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -ubuntu-dev-tools (0.129) oneiric; urgency=low +ubuntu-dev-tools (0.129) UNRELEASED; urgency=low [ Colin Watson ] * syncpackage: Convert to new LP API, with --no-lp available for the old