* Add python-launchpad-bugs support to requestsync and update the manpage.

This commit is contained in:
Michael Bienia 2008-01-19 15:40:28 +01:00
parent 2ae02070a3
commit cd7ea02ceb
3 changed files with 238 additions and 138 deletions

11
debian/changelog vendored
View File

@ -1,8 +1,13 @@
ubuntu-dev-tools (0.25) UNRELEASED; urgency=low ubuntu-dev-tools (0.25) UNRELEASED; urgency=low
[ Michael Bienia ] [ Michael Bienia ]
* Add work-around for a bug in Debian's madison.php not returning only the * requestsync:
'source' line (LP: #183346). + Add work-around for a bug in Debian's madison.php not returning only the
'source' line (LP: #183346).
+ Add support to file sync requests with python-launchpad-bugs (--lp)
(LP: #147994).
* doc/requestsync.1:
+ Document new requestsync options.
[ Siegfried-Angel Gevatter Pujals (RainCT) ] [ Siegfried-Angel Gevatter Pujals (RainCT) ]
* what-patch: * what-patch:
@ -24,7 +29,7 @@ ubuntu-dev-tools (0.25) UNRELEASED; urgency=low
* Remove duplicated ubuntu-dev-tools recommends (it's already a * Remove duplicated ubuntu-dev-tools recommends (it's already a
dependency). dependency).
-- Siegfried-Angel Gevatter Pujals (RainCT) <rainct@ubuntu.com> Thu, 17 Jan 2008 19:17:43 +0100 -- Michael Bienia <geser@ubuntu.com> Sat, 19 Jan 2008 15:27:14 +0100
ubuntu-dev-tools (0.24) hardy; urgency=low ubuntu-dev-tools (0.24) hardy; urgency=low

View File

@ -1,20 +1,30 @@
.TH REQUESTSYNC "1" "22 November 2007" "ubuntu-dev-tools" .TH REQUESTSYNC "1" "19 January 2008" "ubuntu-dev-tools"
.SH NAME .SH NAME
requestsync \- helper to file sync requests for Ubuntu requestsync \- helper to file sync requests for Ubuntu
.SH SYNOPSIS .SH SYNOPSIS
.B requestsync\fR [\fB\-ns\fR] [\fB-k \fIkeyid\fR] <\fBsource package\fR> <\fBtarget release\fR> [\fIbase version\fR] .B requestsync\fR [\fB\-ns\fR] [\fB\-k \fIkeyid\fR] <\fBsource package\fR> <\fBtarget release\fR> [\fIbase version\fR]
.B requestsync \-\-lp\fR [\fB\-ns\fR] <\fBsource package\fR> <\fBtarget release\fR> [\fIbase version\fR]
.B requestsync \-h
.SH DESCRIPTION .SH DESCRIPTION
.PP .PP
\fBrequestsync\fR looks at the versions of <source package> in Debian and \fBrequestsync\fR looks at the versions of <source package> in Debian and
Ubuntu and prompts for an explanation of why the Ubuntu changes (if there Ubuntu and prompts for an explanation of why the Ubuntu changes (if there
are any) should be dropped. are any) should be dropped.
The changelog entry is then downloaded from packages.debian.org, followed by The changelog entry is then downloaded from packages.debian.org. If the sync
a prompt for your GPG passphrase so that it can sign the mail and send it request is being filed per email (default), a prompt for your GPG passphrase
off, to file a sync request in the form of a bug report in Launchpad. follows so that it can sign the mail and send it off to Launchpad.
Alternatively a sync request can be filed directly using the launchpadbugs
python module (option \fB\-\-lp\fR). \fBrequestsync\fR falls back to mail
the sync request if submitting using the launchpadbugs module fails.
.SH OPTIONS .SH OPTIONS
.PP .PP
Listed below are the command line options for requestsync: Listed below are the command line options for requestsync:
.TP .TP
.B \-h
Display a help message and exit.
.TP
.B \-n .B \-n
Specifies that the package is a new package, and requestsync should not Specifies that the package is a new package, and requestsync should not
attempt to look it up in Ubuntu since it will not exist. attempt to look it up in Ubuntu since it will not exist.
@ -25,9 +35,14 @@ You need this option if you are not a member of ubuntu-dev for universe or
multiverse, or ubuntu-core-dev for main or restricted. multiverse, or ubuntu-core-dev for main or restricted.
.TP .TP
.B \-k \fI<keyid>\fR .B \-k \fI<keyid>\fR
Specifies your GPC key. Specifies your GPG key.
Can also be set with the line `\fIexport GPGKEY=<keyid>\fR' in Can also be set with the line `\fIexport GPGKEY=<keyid>\fR' in
.IR $HOME/.bashrc . .IR $HOME/.bashrc .
This is only used if the sync request is mailed to Launchpad.
.TP
.B \-\-lp
Use the launchpadbugs python module (packaged as python-launchpad-bugs) to
file the sync request in Launchpad.
.TP .TP
.B <source package> .B <source package>
This is the source package that you would like to be synced from Debian. This is the source package that you would like to be synced from Debian.
@ -45,7 +60,8 @@ Specify this option in this case.
.PP .PP
This manual page was pieced together by Steve Kowalik. This manual page was pieced together by Steve Kowalik.
It was then updated by Ryan Kavanagh to reflect additional features. It was then updated by Ryan Kavanagh and Michael Bienia to reflect
additional features.
.SH SEE ALSO .SH SEE ALSO
.PP .PP
.BR rmadison (1) .BR rmadison (1)

View File

@ -5,16 +5,16 @@
# Authors: # Authors:
# Martin Pitt <martin.pitt@ubuntu.com> # Martin Pitt <martin.pitt@ubuntu.com>
# Steve Kowalik <stevenk@ubuntu.com> # Steve Kowalik <stevenk@ubuntu.com>
# Michael Bienia <geser@ubuntu.com> (python-launchpad-bugs support)
#
# License: GPLv2, see /usr/share/common-licenses/GPL # License: GPLv2, see /usr/share/common-licenses/GPL
import os, os.path, sys, urllib, subprocess, smtplib, getopt import os, sys, urllib, subprocess, getopt
changelog = 1
def cur_version_component(sourcepkg, release): def cur_version_component(sourcepkg, release):
'''Determine current package version in ubuntu.'''
madison = subprocess.Popen(['rmadison', '-u', 'ubuntu', '-a', 'source', \ madison = subprocess.Popen(['rmadison', '-u', 'ubuntu', '-a', 'source', \
'-s', release, sourcepkg], \ '-s', release, sourcepkg], stdout=subprocess.PIPE)
stdout=subprocess.PIPE)
out = madison.communicate()[0] out = madison.communicate()[0]
assert (madison.returncode == 0) assert (madison.returncode == 0)
@ -29,7 +29,7 @@ def cur_version_component(sourcepkg, release):
sys.exit(1) sys.exit(1)
def cur_deb_version(sourcepkg): def cur_deb_version(sourcepkg):
''' Return the current debian version of a package in unstable ''' '''Return the current debian version of a package in unstable.'''
madison = subprocess.Popen(['rmadison', '-u', 'debian', '-a', 'source', \ madison = subprocess.Popen(['rmadison', '-u', 'debian', '-a', 'source', \
'-s', 'unstable', sourcepkg], \ '-s', 'unstable', sourcepkg], \
stdout=subprocess.PIPE) stdout=subprocess.PIPE)
@ -50,8 +50,6 @@ def cur_deb_version(sourcepkg):
return out.split('|')[1].rstrip('[]''').strip() return out.split('|')[1].rstrip('[]''').strip()
sys.exit(1)
def debian_changelog(sourcepkg, component, version): def debian_changelog(sourcepkg, component, version):
'''Return the Debian changelog from the latest up to the given version '''Return the Debian changelog from the latest up to the given version
(exclusive).''' (exclusive).'''
@ -86,80 +84,214 @@ def debian_component(sourcepkg):
return component return component
def usage(): def usage():
print """Usage: requestsync [-n|-s|-k <keyid>] <source package> <target release> [basever] print '''Usage: requestsync [-h|-n|-s|-k <keyid>|--lp] <source package> <target release> [basever]
In some cases, the base version (fork point from Debian) cannot be determined In some cases, the base version (fork point from Debian) cannot be determined
automatically, and you'll get a complete Debian changelog. Specify the correct automatically, and you'll get a complete Debian changelog. Specify the correct
base version of the package in Ubuntu.""" base version of the package in Ubuntu.
Options:
-h print this help
-n new source package (doesn't exist yet in Ubuntu)
-s request sponsoring (through ubuntu-{main,universe}-sponsors)
-k <keyid> sign email with <keyid> (only used when submitting per email)
--lp use python-launchpad-bugs instead of email for bug submitting
'''
sys.exit(1) sys.exit(1)
def mail_bug(source_package, subscribe, status, bugtitle, bugtext, keyid = None):
'''Submit the sync request per email.
Return True if email successfully send, otherwise False.'''
import smtplib
to = 'new@bugs.launchpad.net'
myemailaddr = os.getenv('DEBEMAIL')
if not myemailaddr:
print >> sys.stderr, 'The environment variable DEBEMAIL needs to be set to make use of this script.'
return False
mailbody = ''
if source_package:
mailbody += ' affects ubuntu/%s\n' % source_package
else:
mailbody += ' affects ubuntu\n'
mailbody = mailbody + ' status %s\n importance wishlist\n subscribe %s\n\n%s' % (status, subscribe, bugtext)
# sign it
sign_command = 'gpg'
for cmd in ('gpg2', 'gnome-gpg'):
if os.access('/usr/bin/%s' % cmd, os.X_OK):
sign_command = cmd
gpg_command = [sign_command, '--clearsign']
if keyid:
gpg_command.extend(('-u', keyid))
gpg = subprocess.Popen(gpg_command, stdin = subprocess.PIPE, stdout = subprocess.PIPE)
signed_report = gpg.communicate(mailbody)[0]
assert gpg.returncode == 0
# generate email
mail = 'From: %s\nTo: %s\nSubject: %s\n\n%s' % (myemailaddr, to, bugtitle, signed_report)
print mail
print 'Press enter to file this bug, Control-C to abort.'
try:
sys.stdin.readline()
except KeyboardInterrupt:
print 'Abort requested. No sync request filed.'
sys.exit(1)
# get server address
mailserver = os.getenv('DEBSMTP')
if mailserver:
print 'Using custom SMTP server:', mailserver
else:
mailserver = 'fiordland.ubuntu.com'
# get server port
mailserver_port = os.getenv('DEBSMTP_PORT')
if mailserver_port:
print 'Using custom SMTP port:', mailserver_port
else:
mailserver_port = 25
# connect to the server
s = smtplib.SMTP(mailserver, mailserver_port)
# authenticate to the server
mailserver_user = os.getenv('DEBSMTP_USER')
mailserver_pass = os.getenv('DEBSMTP_PASS')
if mailserver_user and mailserver_pass:
try:
s.login(mailserver_user, mailserver_pass)
except smtplib.SMTPAuthenticationError:
print 'Error authenticating to the server: invalid username and password.'
s.quit()
return False
except:
print 'Unknown SMTP error.'
s.quit()
return False
s.sendmail(myemailaddr, to, mail)
s.quit()
print 'Sync request mailed.'
return True
def post_bug(source_package, subscibe, status, bugtitle, bugtext):
'''Use python-launchpad-bugs to submit the sync request.
Return True if email successfully send, otherwise False.'''
import glob, os.path
try:
import launchpadbugs.connector
except ImportError:
print >> sys.stderr, 'Importing launchpadbugs failed. Is python-launchpad-bugs installed?'
print >> sys.stderr, 'Falling back to submitting per email.'
return False
# Search cookiefile (for authentication to lp)
try:
cookiefile = glob.glob(os.path.expanduser('~/.mozilla/*/*/cookies.txt'))[0]
except IndexError:
print >> sys.stderr, 'Could not find Firefox cookie file'
return False
if source_package:
product = {'name': source_package, 'target': 'ubuntu'}
else:
# new source package
product = {'name': 'ubuntu'}
print 'Summary:\n%s\n\nDescription:\n%s' % (bugtitle, bugtext)
print 'Press enter to file this bug, Control-C to abort.'
try:
sys.stdin.readline()
except KeyboardInterrupt:
print 'Abort requested. No sync request filed.'
sys.exit(1)
# Create bug
Bug = launchpadbugs.connector.ConnectBug()
Bug.authentication = cookiefile
bug = Bug.New(product = product, summary = bugtitle, description = bugtext)
bug.importance = 'Wishlist'
bug.status = status
bug.subscriptions.add(subscribe)
bug.commit()
print 'Sync request filed as bug #%i: https://launchpad.net/bugs/%i' % (bug.bugnumber, bug.bugnumber)
return True
# #
# entry point # entry point
# #
newsource = False if __name__ == '__main__':
sponsorship = False newsource = False
keyid = None sponsorship = False
try: keyid = None
opts, args = getopt.getopt(sys.argv[1:], 'nsk:') use_lp_bugs = False
except getopt.GetoptError:
usage()
for o, a in opts:
if o == "-n":
newsource = True
if o == "-s":
sponsorship = True
if o == "-k":
keyid = a
if len(args) not in (2, 3): try:
usage() opts, args = getopt.gnu_getopt(sys.argv[1:], 'hnsk:', ('lp'))
except getopt.GetoptError:
usage()
for o, a in opts:
if o == '-h': usage()
if o == '-n': newsource = True
if o == '-s': sponsorship = True
if o == '-k': keyid = a
if o == '--lp': use_lp_bugs = True
(srcpkg, release) = args[:2] if len(args) not in (2, 3):
force_base_ver = None usage()
if len(args) == 3:
force_base_ver = args[2]
(cur_ver, component) = ('0', 'universe') # Let's assume universe
if not newsource:
(cur_ver, component) = cur_version_component(srcpkg, release)
debiancomponent = debian_component(srcpkg) (srcpkg, release) = args[:2]
force_base_ver = None
if len(args) == 3:
force_base_ver = args[2]
(cur_ver, component) = ('0', 'universe') # Let's assume universe
if not newsource:
(cur_ver, component) = cur_version_component(srcpkg, release)
# generate bug report debiancomponent = debian_component(srcpkg)
status = "confirmed" deb_version = cur_deb_version(srcpkg)
subscribe = "ubuntu-archive"
deb_version = cur_deb_version(srcpkg)
if sponsorship:
status = "new"
if component in ['main', 'restricted']:
subscribe = "ubuntu-main-sponsors"
else:
subscribe = "ubuntu-universe-sponsors"
affects = '/%s' % srcpkg # generate bug report
if newsource: subscribe = 'ubuntu-archive'
affects = '' status = 'confirmed'
if sponsorship:
status = 'new'
if component in ['main', 'restricted']:
subscribe = 'ubuntu-main-sponsors'
else:
subscribe = 'ubuntu-universe-sponsors'
report = ''' affects ubuntu%s report = '''Please sync %s %s (%s) from Debian unstable (%s).
status %s ''' % (srcpkg, deb_version, component, debiancomponent)
importance wishlist title = report[:-2]
subscribe %s
base_ver = cur_ver
uidx = base_ver.find('ubuntu')
if uidx > 0:
base_ver = base_ver[:uidx]
Please sync %s %s (%s) from Debian unstable (%s). print 'Explanation of the Ubuntu delta and why it can be dropped:'
''' % (affects, status, subscribe, srcpkg, deb_version, component, debiancomponent) explanation = '\nExplanation of the Ubuntu delta and why it can be dropped:\n'
while (explanation[-2:] != '\n\n'):
explanation += sys.stdin.readline()
report += explanation
base_ver = cur_ver
uidx = base_ver.find('ubuntu')
if uidx > 0:
base_ver = base_ver[:uidx]
print 'Explanation of the Ubuntu delta and why it can be dropped:'
explanation = '\nExplanation of the Ubuntu delta and why it can be dropped:\n'
while (explanation[-2:] != '\n\n'):
explanation += sys.stdin.readline()
report += explanation
if changelog:
uidx = base_ver.find('build') uidx = base_ver.find('build')
if uidx > 0: if uidx > 0:
base_ver = base_ver[:uidx] base_ver = base_ver[:uidx]
@ -170,69 +302,16 @@ if changelog:
report += 'Changelog since current %s version %s:\n\n' % (release, cur_ver) report += 'Changelog since current %s version %s:\n\n' % (release, cur_ver)
report += debian_changelog(srcpkg, debiancomponent, base_ver) + '\n' report += debian_changelog(srcpkg, debiancomponent, base_ver) + '\n'
# sign it # mail or post the sync request
sign_command = 'gpg' srcpkg = not newsource and srcpkg or None
for cmd in ('gpg2', 'gnome-gpg'): if use_lp_bugs:
if os.access('/usr/bin/%s' % cmd, os.X_OK): # Map status to the values expected by lp-bugs
sign_command = cmd mapping = {'new': 'New', 'confirmed': 'Confirmed'}
if post_bug(srcpkg, subscribe, mapping[status], title, report):
sys.exit(0)
gpg_command = [sign_command, '--clearsign'] if mail_bug(srcpkg, subscribe, status, title, report, keyid):
if keyid: sys.exit(0)
gpg_command.extend(('-u', keyid))
gpg = subprocess.Popen(gpg_command, stdin=subprocess.PIPE, stdout=subprocess.PIPE) print 'Something went wrong. No sync request filed.'
signed_report = gpg.communicate(report)[0]
assert gpg.returncode == 0
# generate email
myemailaddr = os.getenv('DEBEMAIL')
if not myemailaddr:
print "The environment variable DEBEMAIL needs to be set to make use of this script."
sys.exit(1) sys.exit(1)
to = 'new@bugs.launchpad.net'
mail = '''From: %s
To: %s
Subject: Please sync %s %s (%s) from Debian unstable (%s)
%s''' % (myemailaddr, to, srcpkg, deb_version, component, debiancomponent, signed_report)
print mail
print 'Press enter to file this bug, Control-C to abort'
sys.stdin.readline()
# get server address
mailserver = os.getenv('DEBSMTP')
if mailserver:
print 'Using custom SMTP server:', mailserver
else :
mailserver = 'fiordland.ubuntu.com'
# get server port
mailserver_port = os.getenv('DEBSMTP_PORT')
if mailserver_port:
print 'Using custom SMTP port:', mailserver_port
else:
mailserver_port = 25
# connect to the server
s = smtplib.SMTP(mailserver, mailserver_port)
# authenticate to the server
mailserver_user = os.getenv('DEBSMTP_USER')
mailserver_pass = os.getenv('DEBSMTP_PASS')
if mailserver_user and mailserver_pass:
try:
s.login(mailserver_user, mailserver_pass)
except smtplib.SMTPAuthenticationError:
print 'Error authenticating to the server: invalid username and password.'
s.quit(); sys.exit(1)
except:
print 'Unknown SMTP error.'
s.quit(); sys.exit(1)
s.sendmail(myemailaddr, to, mail)
s.quit()