~andrewsomething/ubuntu-dev-tools/665202

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# (C) 2007 Canonical Ltd., Steve Kowalik
# Authors:
#  Martin Pitt <martin.pitt@ubuntu.com>
#  Steve Kowalik <stevenk@ubuntu.com>
#  Michael Bienia <geser@ubuntu.com>
#  Daniel Hahler <ubuntu@thequod.de>
#  Iain Lane <laney@ubuntu.com>
#  Jonathan Davies <jpds@ubuntu.com>
#  Markus Korn <thekorn@gmx.de> (python-launchpadlib support)
#
# ##################################################################
#
# 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 2.
# 
# 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.
#
# See file /usr/share/common-licenses/GPL-2 for more details.
#
# ##################################################################

import sys
from optparse import OptionParser
from debian.changelog import Version

# ubuntu-dev-tools modules
from ubuntutools.lp import udtexceptions
from ubuntutools.requestsync.common import (edit_report, getDebianChangelog,
                                            raw_input_exit_on_ctrlc)
# https_proxy fix
import ubuntutools.common

#
# entry point
#

if __name__ == '__main__':
	# Our usage options.
	usage = 'Usage: %prog [-d distro] [-k keyid] [-n] [--lp] [-s] [-e] ' \
		'<source package> [<target release> [base version]]'
	optParser = OptionParser(usage)

	optParser.add_option('-d', type = 'string',
		dest = 'dist', default = 'unstable',
		help = 'Debian distribution to sync from.')
	optParser.add_option('-k', type = 'string',
		dest = 'keyid', default = None,
		help = 'GnuPG key ID to use for signing report (only used when emailing the sync request).')
	optParser.add_option('-n', action = 'store_true',
		dest = 'newpkg', default = False,
		help = 'Whether package to sync is a new package in Ubuntu.')
	optParser.add_option('--lp', action = 'store_true',
		dest = 'lpapi', default = False,
		help = 'Specify whether to use the LP API for filing the sync request (recommended).')
	optParser.add_option('-s', action = 'store_true',
		dest = 'sponsorship', default = False,
		help = 'Force sponsorship')
	optParser.add_option('-C', action = 'store_true',
		dest = 'missing_changelog_ok', default = False,
		help = 'Allow changelog to be manually filled in when missing')
	optParser.add_option('-e', action = 'store_true',
		dest = 'ffe', default = False,
		help = 'Use this after FeatureFreeze for non-bug fix syncs, changes ' \
			'default subscription to the appropriate release team.')

	(options, args) = optParser.parse_args()

	if not len(args):
		optParser.print_help()
		sys.exit(1)

	# import the needed requestsync module
	if options.lpapi:
		from ubuntutools.requestsync.lp import (checkExistingReports,
		                                        getDebianSrcPkg,
		                                        getUbuntuSrcPkg,
		                                        needSponsorship, postBug)
		from ubuntutools.lp.lpapicache import Distribution, Launchpad
		# See if we have LP credentials and exit if we don't - cannot continue in this case

		try:
			Launchpad.login()
		except IOError:
			sys.exit(1)
	else:
		from ubuntutools.requestsync.mail import (checkExistingReports,
		                                          getDebianSrcPkg,
		                                          getEmailAddress,
		                                          getUbuntuSrcPkg,
		                                          mailBug, needSponsorship)
		if not getEmailAddress():
			sys.exit(1)

	newsource = options.newpkg
	sponsorship = options.sponsorship
	distro = options.dist
	ffe = options.ffe
	lpapi = options.lpapi
	need_interaction = False
	force_base_version = None
	srcpkg = args[0]

	if len(args) == 1:
		if lpapi:
			release = Distribution('ubuntu').getDevelopmentSeries().name
		else:
			release = 'natty'
		print >> sys.stderr, 'W: Target release missing - assuming %s' % release
	elif len(args) == 2:
		release = args[1]
	elif len(args) == 3:
		release = args[1]
		force_base_version = Version(args[2])
	else:
		print >> sys.stderr, 'E: Too many arguments.'
		optParser.print_help()
		sys.exit(1)

	# Get the current Ubuntu source package
	try:
		ubuntu_srcpkg = getUbuntuSrcPkg(srcpkg, release)
		ubuntu_version = Version(ubuntu_srcpkg.getVersion())
		ubuntu_component = ubuntu_srcpkg.getComponent()
		newsource = False # override the -n flag
	except udtexceptions.PackageNotFoundException:
		ubuntu_srcpkg = None
		ubuntu_version = Version('~')
		ubuntu_component = 'universe' # let's assume universe
		if not newsource:
			print "'%s' doesn't exist in 'Ubuntu %s'.\nDo you want to sync a new package?" % \
				(srcpkg, release)
			raw_input_exit_on_ctrlc('Press [Enter] to continue or [Ctrl-C] to abort. ')
			newsource = True

	# Get the requested Debian source package
	try:
		debian_srcpkg = getDebianSrcPkg(srcpkg, distro)
		debian_version = Version(debian_srcpkg.getVersion())
		debian_component = debian_srcpkg.getComponent()
	except udtexceptions.PackageNotFoundException, e:
		print >> sys.stderr, "E: %s" % e
		sys.exit(1)

        # Stop if Ubuntu has already the version from Debian or a newer version
	if (ubuntu_version >= debian_version) and options.lpapi:
		# try rmadison
		import ubuntutools.requestsync.mail
		try:
			debian_srcpkg = ubuntutools.requestsync.mail.getDebianSrcPkg(srcpkg, distro)
			debian_version = Version(debian_srcpkg.getVersion())
			debian_component = debian_srcpkg.getComponent()
		except udtexceptions.PackageNotFoundException, e:
			print >> sys.stderr, "E: %s" % e
			sys.exit(1)

	if ubuntu_version == debian_version:
		print  >> sys.stderr, \
			'E: The versions in Debian and Ubuntu are the same already (%s). Aborting.' % ubuntu_version
		sys.exit(1)
        if ubuntu_version > debian_version:
            print >> sys.stderr, \
                'E: The version in Ubuntu (%s) is newer than the version in Debian (%s). Aborting.' % (ubuntu_version, debian_version)
            sys.exit(1)

	# -s flag not specified - check if we do need sponsorship
	if not sponsorship:
		sponsorship = needSponsorship(srcpkg, ubuntu_component, release)

	# Check for existing package reports
	if not newsource:
		checkExistingReports(srcpkg)

	# Generate bug report
	pkg_to_sync = '%s %s (%s) from Debian %s (%s)' % \
		(srcpkg, debian_version, ubuntu_component, distro, debian_component)
	title = "Sync %s" % pkg_to_sync
	if ffe:
		title = "FFe: " + title
	report = "Please sync %s\n\n" % pkg_to_sync

	if 'ubuntu' in str(ubuntu_version):
		need_interaction = True

		print 'Changes have been made to the package in Ubuntu.\n' \
			'Please edit the report and give an explanation.\n' \
			'Not saving the report file will abort the request.'
		report += 'Explanation of the Ubuntu delta and why it can be dropped:\n' \
			'>>> ENTER_EXPLANATION_HERE <<<\n\n'

	if ffe:
		need_interaction = True

		print 'To approve FeatureFreeze exception, you need to state\n' \
			'the reason why you feel it is necessary.\n' \
			'Not saving the report file will abort the request.'
		report += 'Explanation of FeatureFreeze exception:\n' \
			'>>> ENTER_EXPLANATION_HERE <<<\n\n'

	if need_interaction:
		raw_input_exit_on_ctrlc('Press [Enter] to continue. Press [Ctrl-C] to abort now. ')

	base_version = force_base_version or ubuntu_version

	if newsource:
		report += 'All changelog entries:\n\n'
	else:
		report += 'Changelog entries since current %s version %s:\n\n' % (release, ubuntu_version)
	changelog = getDebianChangelog(debian_srcpkg, base_version)
	if not changelog:
		if not options.missing_changelog_ok:
			print >> sys.stderr, "E: Did not retrieve any changelog entries. Do you need to specify '-C'? Was the package recently uploaded? (check http://packages.debian.org/changelogs/)"
			sys.exit(1)
		else:
			need_interaction = True
			changelog = "XXX FIXME: add changelog here XXX"
	report += changelog

	(title, report) = edit_report(title, report, changes_required = need_interaction)
	if 'XXX FIXME' in report:
		print >> sys.stderr, "E: changelog boilerplate found in report, please manually add changelog when using '-C'"
		sys.exit(1)

	# bug status and bug subscriber
	status = 'confirmed'
	subscribe = 'ubuntu-archive'
	if sponsorship:
		status = 'new'
		subscribe = 'ubuntu-sponsors'
	if ffe:
		status = 'new'
		subscribe = 'ubuntu-release'

	srcpkg = not newsource and srcpkg or None
	if lpapi:
		# Map status to the values expected by LP API
		mapping = {'new': 'New', 'confirmed': 'Confirmed'}
		# Post sync request using LP API
		postBug(srcpkg, subscribe, mapping[status], title, report)
	else:
		# Mail sync request
		mailBug(srcpkg, subscribe, status, title, report, options.keyid)