| Line | Revision | Contents |
| 1 | 18.1.39 | #!/usr/bin/python |
| 2 | 22.1.5 | # -*- coding: utf-8 -*- |
| 3 | 96 | # |
| 4 | 41 | # (C) 2007 Canonical Ltd., Steve Kowalik |
| 5 | 18.1.39 | # Authors: |
| 6 | 96 | # Martin Pitt <martin.pitt@ubuntu.com> |
| 7 | # Steve Kowalik <stevenk@ubuntu.com> |
|
| 8 | 471.1.9 | # Michael Bienia <geser@ubuntu.com> |
| 9 | 96 | # Daniel Hahler <ubuntu@thequod.de> |
| 10 | 333 | # Iain Lane <laney@ubuntu.com> |
| 11 | 242 | # Jonathan Davies <jpds@ubuntu.com> |
| 12 | 267 | # Markus Korn <thekorn@gmx.de> (python-launchpadlib support) |
| 13 | 55 | # |
| 14 | 135 | # ################################################################## |
| 15 | # |
|
| 16 | # This program is free software; you can redistribute it and/or |
|
| 17 | # modify it under the terms of the GNU General Public License |
|
| 18 | # as published by the Free Software Foundation; version 2. |
|
| 19 | # |
|
| 20 | # This program is distributed in the hope that it will be useful, |
|
| 21 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 22 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 23 | # GNU General Public License for more details. |
|
| 24 | # |
|
| 25 | # See file /usr/share/common-licenses/GPL-2 for more details. |
|
| 26 | # |
|
| 27 | # ################################################################## |
|
| 28 | 18.1.39 | |
| 29 | 146 | import sys |
| 30 | 471.3.20 | from optparse import OptionParser |
| 31 | 63.1.10 | from debian_bundle.changelog import Version |
| 32 | 249 | |
| 33 | 471.3.20 | # ubuntu-dev-tools modules |
| 34 | from ubuntutools.lp import udtexceptions |
|
| 35 | from ubuntutools.requestsync.common import * |
|
| 36 | 326 | # https_proxy fix |
| 37 | import ubuntutools.common |
|
| 38 | ||
| 39 | 18.1.39 | # |
| 40 | # entry point |
|
| 41 | # |
|
| 42 | ||
| 43 | 55 | if __name__ == '__main__': |
| 44 | 471.3.20 | # Our usage options. |
| 45 | usage = 'Usage: %prog [-d distro] [-k keyid] [-n] [--lp] [-s] [-e] ' \ |
|
| 46 | '<source package> [<target release> [base version]]' |
|
| 47 | optParser = OptionParser(usage) |
|
| 48 | ||
| 49 | optParser.add_option('-d', type = 'string', |
|
| 50 | 517 | dest = 'dist', default = 'testing', |
| 51 | 471.3.20 | help = 'Debian distribution to sync from.') |
| 52 | optParser.add_option('-k', type = 'string', |
|
| 53 | dest = 'keyid', default = None, |
|
| 54 | help = 'GnuPG key ID to use for signing report (only used when emailing the sync request).') |
|
| 55 | optParser.add_option('-n', action = 'store_true', |
|
| 56 | dest = 'newpkg', default = False, |
|
| 57 | help = 'Whether package to sync is a new package in Ubuntu.') |
|
| 58 | optParser.add_option('--lp', action = 'store_true', |
|
| 59 | dest = 'lpapi', default = False, |
|
| 60 | 471.3.21 | help = 'Specify whether to use the LP API for filing the sync request (recommended).') |
| 61 | 471.3.20 | optParser.add_option('-s', action = 'store_true', |
| 62 | 471.3.21 | dest = 'sponsorship', default = False, |
| 63 | 471.3.20 | help = 'Force sponsorship') |
| 64 | optParser.add_option('-e', action = 'store_true', |
|
| 65 | dest = 'ffe', default = False, |
|
| 66 | help = 'Use this after FeatureFreeze for non-bug fix syncs, changes ' \ |
|
| 67 | 'default subscription to the appropriate release team.') |
|
| 68 | ||
| 69 | (options, args) = optParser.parse_args() |
|
| 70 | ||
| 71 | if not len(args): |
|
| 72 | optParser.print_help() |
|
| 73 | sys.exit(1) |
|
| 74 | ||
| 75 | # import the needed requestsync module |
|
| 76 | if options.lpapi: |
|
| 77 | from ubuntutools.requestsync.lp import * |
|
| 78 | 471.3.21 | from ubuntutools.lp.lpapicache import Distribution, PersonTeam |
| 79 | 522 | # See if we have LP credentials and exit if we don't - cannot continue in this case |
| 80 | try: |
|
| 81 | Launchpad.login() |
|
| 82 | except IOError: |
|
| 83 | sys.exit(1) |
|
| 84 | 471.3.20 | else: |
| 85 | from ubuntutools.requestsync.mail import * |
|
| 86 | if not getEmailAddress(): |
|
| 87 | sys.exit(1) |
|
| 88 | ||
| 89 | newsource = options.newpkg |
|
| 90 | 471.3.21 | sponsorship = options.sponsorship |
| 91 | distro = options.dist |
|
| 92 | ffe = options.ffe |
|
| 93 | 471.3.20 | lpapi = options.lpapi |
| 94 | need_interaction = False |
|
| 95 | 471.3.21 | force_base_version = None |
| 96 | srcpkg = args[0] |
|
| 97 | 471.3.20 | |
| 98 | 471.3.21 | if len(args) == 1: |
| 99 | if lpapi: |
|
| 100 | 471.3.20 | release = Distribution('ubuntu').getDevelopmentSeries().name |
| 101 | print >> sys.stderr, 'W: Target release missing - assuming %s' % release |
|
| 102 | else: |
|
| 103 | print >> sys.stderr, 'E: Source package or target release missing. Exiting.' |
|
| 104 | sys.exit(1) |
|
| 105 | 471.3.21 | elif len(args) == 2: |
| 106 | release = args[1] |
|
| 107 | elif len(args) == 3: |
|
| 108 | release = args[1] |
|
| 109 | force_base_version = Version(args[2]) |
|
| 110 | 471.3.20 | else: |
| 111 | 471.3.21 | print >> sys.stderr, 'E: Too many arguments.' |
| 112 | optParser.print_help() |
|
| 113 | sys.exit(1) |
|
| 114 | ||
| 115 | # Get the current Ubuntu source package |
|
| 116 | 471.3.16 | try: |
| 117 | 471.3.21 | ubuntu_srcpkg = getUbuntuSrcPkg(srcpkg, release) |
| 118 | ubuntu_version = Version(ubuntu_srcpkg.getVersion()) |
|
| 119 | ubuntu_component = ubuntu_srcpkg.getComponent() |
|
| 120 | newsource = False # override the -n flag |
|
| 121 | 471.3.16 | except udtexceptions.PackageNotFoundException: |
| 122 | 471.3.21 | ubuntu_srcpkg = None |
| 123 | ubuntu_version = Version(0) |
|
| 124 | ubuntu_component = 'universe' # let's assume universe |
|
| 125 | 471.3.16 | if not newsource: |
| 126 | print "'%s' doesn't exist in 'Ubuntu %s'.\nDo you want to sync a new package?" % \ |
|
| 127 | (srcpkg, release) |
|
| 128 | raw_input_exit_on_ctrlc('Press [Enter] to continue or [Ctrl-C] to abort. ') |
|
| 129 | 471.3.21 | newsource = True |
| 130 | ||
| 131 | # Get the requested Debian source package |
|
| 132 | 471.3.22 | try: |
| 133 | debian_srcpkg = getDebianSrcPkg(srcpkg, distro) |
|
| 134 | debian_version = Version(debian_srcpkg.getVersion()) |
|
| 135 | debian_component = debian_srcpkg.getComponent() |
|
| 136 | except udtexceptions.PackageNotFoundException, e: |
|
| 137 | print >> sys.stderr, "E: %s" % e |
|
| 138 | sys.exit(1) |
|
| 139 | 471.3.21 | |
| 140 | # Debian and Ubuntu versions are the same - stop |
|
| 141 | if ubuntu_version == debian_version: |
|
| 142 | print >> sys.stderr, \ |
|
| 143 | 'E: The versions in Debian and Ubuntu are the same already (%s). Aborting.' % ubuntu_version |
|
| 144 | 471.3.20 | sys.exit(1) |
| 145 | ||
| 146 | 471.3.21 | # -s flag not specified - check if we do need sponsorship |
| 147 | if not sponsorship: |
|
| 148 | 471.3.22 | sponsorship = needSponsorship(srcpkg, ubuntu_component) |
| 149 | 471.3.21 | |
| 150 | # Check for existing package reports |
|
| 151 | if not newsource: |
|
| 152 | checkExistingReports(srcpkg) |
|
| 153 | ||
| 154 | # Generate bug report |
|
| 155 | pkg_to_sync = '%s %s (%s) from Debian %s (%s)' % \ |
|
| 156 | (srcpkg, debian_version, ubuntu_component, distro, debian_component) |
|
| 157 | 471.3.20 | title = "Sync %s" % pkg_to_sync |
| 158 | 471.3.21 | if ffe: |
| 159 | 471.3.20 | title = "FFe: " + title |
| 160 | report = "Please sync %s\n\n" % pkg_to_sync |
|
| 161 | ||
| 162 | 471.3.21 | if 'ubuntu' in str(ubuntu_version): |
| 163 | need_interaction = True |
|
| 164 | ||
| 165 | print 'Changes have been made to the package in Ubuntu.\n' \ |
|
| 166 | 'Please edit the report and give an explanation.\n' \ |
|
| 167 | 'Not saving the report file will abort the request.' |
|
| 168 | report += 'Explanation of the Ubuntu delta and why it can be dropped:\n' \ |
|
| 169 | '>>> ENTER_EXPLANATION_HERE <<<\n\n' |
|
| 170 | ||
| 171 | if ffe: |
|
| 172 | need_interaction = True |
|
| 173 | ||
| 174 | print 'To approve FeatureFreeze exception, you need to state\n' \ |
|
| 175 | 'the reason why you feel it is necessary.\n' \ |
|
| 176 | 'Not saving the report file will abort the request.' |
|
| 177 | report += 'Explanation of FeatureFreeze exception:\n' \ |
|
| 178 | '>>> ENTER_EXPLANATION_HERE <<<\n\n' |
|
| 179 | ||
| 180 | if need_interaction: |
|
| 181 | raw_input_exit_on_ctrlc('Press [Enter] to continue. Press [Ctrl-C] to abort now. ') |
|
| 182 | 471.3.20 | |
| 183 | # Check if they have a per-package upload permission. |
|
| 184 | 471.3.21 | if lpapi: |
| 185 | ubuntu_archive = Distribution('ubuntu').getArchive() |
|
| 186 | if PersonTeam.getMe().isPerPackageUploader(ubuntu_archive, srcpkg): |
|
| 187 | report += 'Note that I have per-package upload permissions for %s.\n\n' % srcpkg |
|
| 188 | ||
| 189 | base_version = force_base_version or ubuntu_version |
|
| 190 | ||
| 191 | if newsource: |
|
| 192 | report += 'All changelog entries:\n\n' |
|
| 193 | else: |
|
| 194 | report += 'Changelog entries since current %s version %s:\n\n' % (release, ubuntu_version) |
|
| 195 | changelog = getDebianChangelog(debian_srcpkg, base_version) |
|
| 196 | 471.3.20 | if not changelog: |
| 197 | 499 | print >> sys.stderr, "E: Did not retrieve any changelog entries. Was the package recently uploaded? (check http://packages.debian.org/changelogs/)" |
| 198 | 471.3.20 | sys.exit(1) |
| 199 | 471.3.21 | report += changelog |
| 200 | 471.3.20 | |
| 201 | (title, report) = edit_report(title, report, changes_required = need_interaction) |
|
| 202 | ||
| 203 | 471.3.21 | # bug status and bug subscriber |
| 204 | status = 'confirmed' |
|
| 205 | subscribe = 'ubuntu-archive' |
|
| 206 | if sponsorship: |
|
| 207 | status = 'new' |
|
| 208 | if ubuntu_component in ('main', 'restricted'): |
|
| 209 | subscribe = 'ubuntu-main-sponsors' |
|
| 210 | else: |
|
| 211 | subscribe = 'ubuntu-universe-sponsors' |
|
| 212 | if ffe: |
|
| 213 | status = 'new' |
|
| 214 | if ubuntu_component in ('main', 'restricted'): |
|
| 215 | subscribe = 'ubuntu-release' |
|
| 216 | else: |
|
| 217 | subscribe = 'motu-release' |
|
| 218 | ||
| 219 | 471.3.20 | srcpkg = not newsource and srcpkg or None |
| 220 | 471.3.21 | if lpapi: |
| 221 | # Map status to the values expected by LP API |
|
| 222 | 471.3.20 | mapping = {'new': 'New', 'confirmed': 'Confirmed'} |
| 223 | 471.3.21 | # Post sync request using LP API |
| 224 | 471.3.20 | postBug(srcpkg, subscribe, mapping[status], title, report) |
| 225 | else: |
|
| 226 | 471.3.21 | # Mail sync request |
| 227 | mailBug(srcpkg, subscribe, status, title, report, options.keyid) |
Loggerhead 1.10 is a web-based interface for Bazaar branches