requestsync:

- Fix --lp for Firefox 3: it now tries ~/.lpcookie.txt,
    ~/.mozilla/*/*/cookies.sqlite and ~/.mozilla/*/*/cookies.txt to find
    a Launchpad cookie file
  - Added confirm loops, which displays the message to be send/posted and
    either allows to edit (or forces to, in case of Ubuntu changes).
    (LP: #194613, #194615)
    This adds a convient edit_report method, which gets used both from the
    Launchpad and mail code path.
  - Do not fallback to submitting by email, if posting to Launchpad failed.
    This hasn't been requested and therefore should not get done.
This commit is contained in:
Daniel Hahler 2008-04-16 02:05:58 +02:00
parent 4600ff8981
commit 6eba68a20d
2 changed files with 148 additions and 66 deletions

20
debian/changelog vendored
View File

@ -1,3 +1,21 @@
ubuntu-dev-tools (0.31) hardy; urgency=low
* requestsync:
- Use debian_bundle.changelog.Version for version comparison in
debian_changelog.
- Fix --lp for Firefox 3: it now tries ~/.lpcookie.txt,
~/.mozilla/*/*/cookies.sqlite and ~/.mozilla/*/*/cookies.txt to find
a Launchpad cookie file
- Added confirm loops, which displays the message to be send/posted and
either allows to edit (or forces to, in case of Ubuntu changes).
(LP: #194613, #194615)
This adds a convient edit_report method, which gets used both from the
Launchpad and mail code path.
- Do not fallback to submitting by email, if posting to Launchpad failed.
This hasn't been requested and therefore should not get done.
-- Daniel Hahler <ubuntu@thequod.de> Wed, 16 Apr 2008 01:57:41 +0200
ubuntu-dev-tools (0.26) UNRELEASED; urgency=low
[ Stephan Hermann ]
@ -11,8 +29,6 @@ ubuntu-dev-tools (0.26) UNRELEASED; urgency=low
When interaction is not required, ask the user if she wants to edit.
(LP: #190351)
* Exit, if versions in Ubuntu and Debian are the same already.
* Use debian_bundle.changelog.Version for version comparison in
debian_changelog.
-- Daniel Hahler <ubuntu@thequod.de> Sat, 09 Feb 2008 18:27:06 +0100

View File

@ -12,6 +12,15 @@
import os, sys, urllib, subprocess, getopt
from debian_bundle.changelog import Version
# Set this to the path of your Launchpad cookie file, when using
# python-launchpad-bugs support (--lp).
# The following will be tried automatically, if unset (first match gets used):
# 1. ~/.lpcookie.txt
# 2. ~/.mozilla/*/*/cookies.sqlite
# 3. ~/.mozilla/*/*/cookies.txt
launchpad_cookiefile = None
def cur_version_component(sourcepkg, release):
'''Determine current package version in ubuntu.'''
madison = subprocess.Popen(['rmadison', '-u', 'ubuntu', '-a', 'source', \
@ -88,10 +97,10 @@ def debian_component(sourcepkg):
component = raw_comp[1].strip()
return component
def wait_for_enter_or_exit():
"""Helper function to wait for ENTER and catch Control-C for abortion."""
def raw_input_exit_on_ctrlc(*args, **kwargs):
"""A wrapper around raw_input() to exit with a normalized message on Control-C"""
try:
raw_input()
return raw_input(*args, **kwargs)
except KeyboardInterrupt:
print 'Abort requested. No sync request filed.'
sys.exit(1)
@ -125,6 +134,7 @@ def mail_bug(source_package, subscribe, status, bugtitle, bugtext, keyid = None)
print >> sys.stderr, 'The environment variable DEBEMAIL needs to be set to make use of this script.'
return False
# generate initial mailbody:
mailbody = ''
if source_package:
mailbody += ' affects ubuntu/%s\n' % source_package
@ -132,7 +142,7 @@ def mail_bug(source_package, subscribe, status, bugtitle, bugtext, keyid = None)
mailbody += ' affects ubuntu\n'
mailbody = mailbody + ' status %s\n importance wishlist\n subscribe %s\n\n%s' % (status, subscribe, bugtext)
# sign it
# prepare sign_command:
sign_command = 'gpg'
for cmd in ('gpg2', 'gnome-gpg'):
if os.access('/usr/bin/%s' % cmd, os.X_OK):
@ -142,17 +152,29 @@ def mail_bug(source_package, subscribe, status, bugtitle, bugtext, keyid = None)
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
in_confirm_loop = True
while in_confirm_loop:
# sign it
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)
# 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.'
wait_for_enter_or_exit()
# ask for confirmation and allow to edit:
print mail
print 'Do you want to edit the report before sending [y/N]? Press Control-C to abort.'
while 1:
val = raw_input_exit_on_ctrlc()
if val.lower() in ('y', 'yes'):
(bugtitle, mailbody) = edit_report(bugtitle, mailbody)
break
elif val.lower() in ('n', 'no', ''):
in_confirm_loop = False
break
else:
print "Invalid answer"
# get server address
mailserver = os.getenv('DEBSMTP')
@ -194,23 +216,33 @@ def mail_bug(source_package, subscribe, status, bugtitle, bugtext, keyid = None)
def post_bug(source_package, subscribe, status, bugtitle, bugtext):
'''Use python-launchpad-bugs to submit the sync request.
Return True if email successfully send, otherwise False.'''
Return True if successfully posted, otherwise False.'''
import glob, os.path
global launchpad_cookiefile
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 launchpad_cookiefile == None:
try_globs = ('~/.lpcookie.txt', '~/.mozilla/*/*/cookies.sqlite', '~/.mozilla/*/*/cookies.txt')
for try_glob in try_globs:
try:
cookiefile = glob.glob(os.path.expanduser(try_glob))[0]
except IndexError:
continue
# Found:
launchpad_cookiefile = cookiefile
print "Using cookie file at %s" % launchpad_cookiefile
break
if launchpad_cookiefile == None:
print >> sys.stderr, 'Could not find cookie file for Launchpad (looked in %s)' % ", ".join(try_globs)
return False
if source_package:
product = {'name': source_package, 'target': 'ubuntu'}
@ -218,14 +250,26 @@ def post_bug(source_package, subscribe, status, bugtitle, bugtext):
# new source package
product = {'name': 'ubuntu'}
print 'Summary:\n%s\n\nDescription:\n%s' % (bugtitle, bugtext)
in_confirm_loop = True
while in_confirm_loop:
print 'Summary:\n%s\n\nDescription:\n%s' % (bugtitle, bugtext)
print 'Press ENTER to file this bug, Control-C to abort.'
wait_for_enter_or_exit()
# ask for confirmation and allow to edit:
print 'Do you want to edit the report before sending [y/N]? Press Control-C to abort.'
while 1:
val = raw_input_exit_on_ctrlc()
if val.lower() in ('y', 'yes'):
(bugtitle, bugtext) = edit_report(bugtitle, bugtext)
break
elif val.lower() in ('n', 'no', ''):
in_confirm_loop = False
break
else:
print "Invalid answer"
# Create bug
Bug = launchpadbugs.connector.ConnectBug()
Bug.authentication = cookiefile
Bug.authentication = launchpad_cookiefile
bug = Bug.New(product = product, summary = bugtitle, description = bugtext)
bug.importance = 'Wishlist'
@ -237,6 +281,54 @@ def post_bug(source_package, subscribe, status, bugtitle, bugtext):
return True
def edit_report(subject, body, changes_required=False):
"""Edit a report (consisting of subject and body) in sensible-editor.
subject and body get decorated, before they are written to the temporary
file and undecorated after editing again.
If changes_required is True and the file has not been edited
(according to its mtime), an error is written to STDERR and the
program exits.
Returns (new_subject, new_body).
"""
import re, string
report = "Summary (one line):\n%s\n\nDescription:\n%s" % (subject, body)
# Create tempfile and remember mtime
import tempfile
report_file = tempfile.NamedTemporaryFile( prefix='requestsync_' )
report_file.file.write(report)
report_file.file.flush()
mtime_before = os.stat( report_file.name ).st_mtime
# Launch editor
try:
editor = subprocess.check_call( ['sensible-editor', report_file.name] )
except subprocess.CalledProcessError, e:
print >> sys.stderr, 'Error calling sensible-editor: %s\nAborting.' % (e,)
sys.exit(1)
# Check if the tempfile has been changed
if changes_required:
report_file_info = os.stat( report_file.name )
if mtime_before == os.stat( report_file.name ).st_mtime:
print >> sys.stderr, 'The temporary file %s has not been changed, but you have\nto explain why the Ubuntu changes can be dropped. Aborting. [Press ENTER]' % (report_file.name,)
raw_input()
sys.exit(1)
report_file.file.seek(0)
report = report_file.file.read()
report_file.file.close()
# Undecorate report again:
(new_subject, new_body) = report.split("\nDescription:\n", 1)
# Remove prefix and whitespace for subject:
new_subject = string.rstrip( re.sub("\n", " ", re.sub("^Summary \(one line\):\s*", "", new_subject, 1)) )
return (new_subject, new_body)
#
# entry point
#
@ -247,7 +339,6 @@ if __name__ == '__main__':
keyid = None
use_lp_bugs = False
need_interaction = False
edit_report = False
try:
opts, args = getopt.gnu_getopt(sys.argv[1:], 'hnsk:', ('lp'))
@ -288,8 +379,8 @@ if __name__ == '__main__':
else:
subscribe = 'ubuntu-universe-sponsors'
report = 'Please sync %s %s (%s) from Debian unstable (%s).\n' % (srcpkg, deb_version, component, debiancomponent)
title = report[:-1]
report = 'Please sync %s %s (%s) from Debian unstable (%s).\n\n' % (srcpkg, deb_version, component, debiancomponent)
title = report[:-2]
base_ver = cur_ver
uidx = base_ver.find('ubuntu')
@ -297,12 +388,13 @@ if __name__ == '__main__':
base_ver = base_ver[:uidx]
need_interaction = True
print 'There have been changes made in Ubuntu.'
print 'Changes have been made to the package in Ubuntu.'
print 'Please edit the report and give an explanation.'
print 'Press ENTER to start your editor. Press Control-C to abort now. Not saving the report file will abort the request, too.'
wait_for_enter_or_exit()
report += '\nExplanation of the Ubuntu delta and why it can be dropped:\n' + \
'>>> ENTER_EXPLANATION_HERE <<<\n\n\n'
print 'Press ENTER to start your editor. Press Control-C to abort now.'
print 'Not saving the report file will abort the request, too.'
raw_input_exit_on_ctrlc()
report += 'Explanation of the Ubuntu delta and why it can be dropped:\n' + \
'>>> ENTER_EXPLANATION_HERE <<<\n\n'
uidx = base_ver.find('build')
if uidx > 0:
@ -314,47 +406,21 @@ if __name__ == '__main__':
report += 'Changelog since current %s version %s:\n\n' % (release, cur_ver)
report += debian_changelog(srcpkg, debiancomponent, base_ver) + '\n'
# Do we want to edit the report?
if need_interaction:
edit_report = True
else:
val = raw_input('Do you want to edit the report [y/N]? ')
if val.lower() in ('y', 'yes'):
edit_report = True
report = edit_report(title, report, changes_required=True)
if edit_report:
# Create tempfile and remember mtime
import tempfile
report_file = tempfile.NamedTemporaryFile( prefix='requestsync_' )
report_file.file.write(report)
report_file.file.flush()
mtime_before = os.stat( report_file.name ).st_mtime
# Launch editor
try:
editor = subprocess.check_call( ['sensible-editor', report_file.name] )
except subprocess.CalledProcessError, e:
print >> sys.stderr, 'Error calling sensible-editor: %s\nAborting.' % (e,)
sys.exit(1)
# Check if the tempfile has been changed
report_file_info = os.stat( report_file.name )
if mtime_before == os.stat( report_file.name ).st_mtime:
print >> sys.stderr, 'The temporary file %s has not been changed. Aborting. [Press ENTER]' % (report_file.name,)
raw_input()
sys.exit(1)
report_file.file.seek(0)
report = report_file.file.read()
report_file.file.close()
# mail or post the sync request
# Post sync request using Launchpad interface:
srcpkg = not newsource and srcpkg or None
if use_lp_bugs:
# Map status to the values expected by lp-bugs
mapping = {'new': 'New', 'confirmed': 'Confirmed'}
if post_bug(srcpkg, subscribe, mapping[status], title, report):
sys.exit(0)
# Abort on error:
print 'Something went wrong. No sync request filed.'
sys.exit(1)
# Mail sync request:
if mail_bug(srcpkg, subscribe, status, title, report, keyid):
sys.exit(0)