Make pylint happier.

This commit is contained in:
Benjamin Drung 2010-12-27 21:54:31 +01:00
parent b05b4aa5ce
commit b09ddfee2f
12 changed files with 346 additions and 322 deletions

View File

@ -29,16 +29,17 @@ from ubuntutools.lp.libsupport import get_launchpad
USAGE = "grab-attachments <bug numbers>" USAGE = "grab-attachments <bug numbers>"
def main(): def main():
p = OptionParser('Usage: %prog [options] <bug numbers>') parser = OptionParser('Usage: %prog [options] <bug numbers>')
p.add_option('-l', '--lpinstance', metavar='INSTANCE', parser.add_option('-l', '--lpinstance', metavar='INSTANCE',
dest='lpinstance', default=None, dest='lpinstance', default=None,
help='Launchpad instance to connect to (default: production)') help='Launchpad instance to connect to '
p.add_option('--no-conf', '(default: production)')
dest='no_conf', default=False, action='store_true', parser.add_option('--no-conf',
help="Don't read config files or environment variables") dest='no_conf', default=False, action='store_true',
opts, args = p.parse_args() help="Don't read config files or environment variables")
opts, args = parser.parse_args()
if len(args) < 1: if len(args) < 1:
p.error('No bug numbers provided') parser.error('No bug numbers provided')
config = UDTConfig(opts.no_conf) config = UDTConfig(opts.no_conf)
if opts.lpinstance is None: if opts.lpinstance is None:
opts.lpinstance = config.get_value('LPINSTANCE') opts.lpinstance = config.get_value('LPINSTANCE')
@ -49,13 +50,13 @@ def main():
for arg in args: for arg in args:
try: try:
number = int(arg) number = int(arg)
except: except ValueError:
p.error("'%s' is not a valid bug number." % arg) parser.error("'%s' is not a valid bug number." % arg)
b = launchpad.bugs[number] bug = launchpad.bugs[number]
for a in b.attachments: for attachment in bug.attachments:
f = a.data.open() f = attachment.data.open()
filename = os.path.join(os.getcwd(), f.filename) filename = os.path.join(os.getcwd(), f.filename)
local_file = open(filename, "w") local_file = open(filename, "w")
local_file.write(f.read()) local_file.write(f.read())
@ -63,10 +64,9 @@ def main():
local_file.close() local_file.close()
# no LP credentials # no LP credentials
except IOError, e: except IOError, error:
print e print error
sys.exit(1) sys.exit(1)
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@ -23,24 +23,28 @@ import sys
import urllib2 import urllib2
import json import json
if len(sys.argv) > 1: def main():
match = sys.argv[1] if len(sys.argv) > 1:
else: match = sys.argv[1]
match = None else:
match = None
for component in ('main', 'main-manual', for component in ('main', 'main-manual',
'restricted', 'restricted-manual', 'restricted', 'restricted-manual',
'universe', 'universe-manual', 'universe', 'universe-manual',
'multiverse', 'multiverse-manual'): 'multiverse', 'multiverse-manual'):
page = urllib2.urlopen('http://merges.ubuntu.com/%s.json' % component) page = urllib2.urlopen('http://merges.ubuntu.com/%s.json' % component)
for merge in json.load(page): for merge in json.load(page):
package = merge['source_package'] package = merge['source_package']
author, uploader = '', '' author, uploader = '', ''
if 'user' in merge: if 'user' in merge:
author = merge['user'] author = merge['user']
if 'uploader' in merge: if 'uploader' in merge:
uploader = '(%s)' % merge['uploader'] uploader = '(%s)' % merge['uploader']
pretty_uploader = ' '.join((author, uploader)).strip() pretty_uploader = ' '.join((author, uploader)).strip()
if (match is None or if (match is None or
match in package or match in author or match in uploader): match in package or match in author or match in uploader):
print '%s\t%s' % (package, pretty_uploader) print '%s\t%s' % (package, pretty_uploader)
if __name__ == '__main__':
main()

View File

@ -41,15 +41,14 @@ def check_args():
# Our usage options. # Our usage options.
usage = "usage: %prog [-n <number>] launchpad-buglist-url" usage = "usage: %prog [-n <number>] launchpad-buglist-url"
optParser = OptionParser(usage) opt_parser = OptionParser(usage)
argsParsed = 0
# Options - namely just the number of bugs to output. # Options - namely just the number of bugs to output.
optParser.add_option("-n", "--number", type = "int", opt_parser.add_option("-n", "--number", type="int",
dest = "number", help = "Number of entries to output.") dest="number", help="Number of entries to output.")
# Parse arguments. # Parse arguments.
(options, args) = optParser.parse_args() (options, args) = opt_parser.parse_args()
# Check if we want a number other than the default. # Check if we want a number other than the default.
howmany = options.number howmany = options.number
@ -58,10 +57,10 @@ def check_args():
if not args: if not args:
print >> sys.stderr, "An URL pointing to a Launchpad bug list is " \ print >> sys.stderr, "An URL pointing to a Launchpad bug list is " \
"required." "required."
optParser.print_help() opt_parser.print_help()
sys.exit(1) sys.exit(1)
else: else:
url = args[argsParsed] url = args[0]
return (howmany, url) return (howmany, url)
@ -90,31 +89,29 @@ def main():
launchpad = None launchpad = None
try: try:
launchpad = get_launchpad("ubuntu-dev-tools") launchpad = get_launchpad("ubuntu-dev-tools")
except IOError, e: except IOError, error:
print e print error
sys.exit(1) sys.exit(1)
api_url = translate_web_api(url, launchpad) api_url = translate_web_api(url, launchpad)
try: try:
product = launchpad.load(api_url) product = launchpad.load(api_url)
except Exception, e: except Exception, error:
x = getattr(e, "response", {}) response = getattr(error, "response", {})
if x.get("status", None) == "404": if response.get("status", None) == "404":
print >> sys.stderr, ("The URL at '%s' does not appear to be a " print >> sys.stderr, ("The URL at '%s' does not appear to be a "
"valid url to a product") % url "valid url to a product") % url
sys.exit(1) sys.exit(1)
else: else:
raise raise
bl = product.searchTasks() bug_list = [b for b in product.searchTasks() if filter_unsolved(b)]
l = filter(filter_unsolved, bl) if not bug_list:
if not l:
print "Bug list of %s is empty." % url print "Bug list of %s is empty." % url
sys.exit(0) sys.exit(0)
if howmany == -1: if howmany == -1:
howmany = len(l) howmany = len(bug_list)
print """ print """
## ||<rowbgcolor="#CCFFCC"> This task is done || somebody || || ## ||<rowbgcolor="#CCFFCC"> This task is done || somebody || ||
@ -124,7 +121,7 @@ def main():
|| Bug || Subject || Triager ||""" || Bug || Subject || Triager ||"""
for i in list(l)[:howmany]: for i in list(bug_list)[:howmany]:
bug = i.bug bug = i.bug
print '||<rowbgcolor="#FFEBBB"> [%s %s] || %s || ||' % \ print '||<rowbgcolor="#FFEBBB"> [%s %s] || %s || ||' % \
(translate_api_web(bug.self_link), bug.id, bug.title) (translate_api_web(bug.self_link), bug.id, bug.title)

View File

@ -32,84 +32,89 @@ import SOAPpy
from ubuntutools.config import UDTConfig from ubuntutools.config import UDTConfig
from ubuntutools.lp.libsupport import get_launchpad, translate_api_web from ubuntutools.lp.libsupport import get_launchpad, translate_api_web
bug_re = re.compile(r"bug=(\d+)") def main():
bug_re = re.compile(r"bug=(\d+)")
url = 'http://bugs.debian.org/cgi-bin/soap.cgi' url = 'http://bugs.debian.org/cgi-bin/soap.cgi'
namespace = 'Debbugs/SOAP' namespace = 'Debbugs/SOAP'
debbugs = SOAPpy.SOAPProxy(url, namespace) debbugs = SOAPpy.SOAPProxy(url, namespace)
# debug # debug
#debbugs.config.dumpSOAPOut = 1 #debbugs.config.dumpSOAPOut = 1
#debbugs.config.dumpSOAPIn = 1 #debbugs.config.dumpSOAPIn = 1
parser = OptionParser(usage="%prog [option] bug ...") parser = OptionParser(usage="%prog [option] bug ...")
parser.add_option("-b", "--browserless", parser.add_option("-b", "--browserless",
help="Don't open the bug in the browser at the end", help="Don't open the bug in the browser at the end",
dest="browserless", action="store_true") dest="browserless", action="store_true")
parser.add_option("-l", "--lpinstance", metavar="INSTANCE", parser.add_option("-l", "--lpinstance", metavar="INSTANCE",
help="Launchpad instance to connect to (default: production)", help="Launchpad instance to connect to "
dest="lpinstance", default=None) "(default: production)",
parser.add_option("-n", "--dry-run", dest="lpinstance", default=None)
help=SUPPRESS_HELP, parser.add_option("-n", "--dry-run",
dest="lpinstance", action="store_const", const="staging") help=SUPPRESS_HELP,
parser.add_option("--no-conf", dest="no_conf", default=False, dest="lpinstance", action="store_const", const="staging")
help="Don't read config files or environment variables.", parser.add_option("--no-conf", dest="no_conf", default=False,
action="store_true") help="Don't read config files or environment variables.",
(options, args) = parser.parse_args() action="store_true")
(options, args) = parser.parse_args()
config = UDTConfig(options.no_conf) config = UDTConfig(options.no_conf)
if options.lpinstance is None: if options.lpinstance is None:
options.lpinstance = config.get_value("LPINSTANCE") options.lpinstance = config.get_value("LPINSTANCE")
try: try:
lp = get_launchpad("ubuntu-dev-tools", options.lpinstance) launchpad = get_launchpad("ubuntu-dev-tools", options.lpinstance)
except IOError, msg: except IOError, msg:
print msg print msg
print "No credentials, can't continue" print "No credentials, can't continue"
sys.exit(1) sys.exit(1)
debian = lp.distributions['debian'] debian = launchpad.distributions['debian']
ubuntu = lp.distributions['ubuntu'] ubuntu = launchpad.distributions['ubuntu']
lp_debbugs = lp.bug_trackers.getByName(name='debbugs') lp_debbugs = launchpad.bug_trackers.getByName(name='debbugs')
bug_nums = [] bug_nums = []
for bug_num in args: for bug_num in args:
if bug_num.startswith("http"): if bug_num.startswith("http"):
# bug URL # bug URL
match = bug_re.search(bug_num) match = bug_re.search(bug_num)
if match is None: if match is None:
raise ValueError("Can't determine bug number from %s" % bug_num) raise ValueError("Can't determine bug number from %s" % bug_num)
bug_num = match.groups()[0] bug_num = match.groups()[0]
bug_num = bug_num.lstrip("#") bug_num = bug_num.lstrip("#")
bug_num = int(bug_num) bug_num = int(bug_num)
bug_nums.append(bug_num) bug_nums.append(bug_num)
bugs = debbugs.get_status(*bug_nums) bugs = debbugs.get_status(*bug_nums)
if len(bug_nums) > 1: if len(bug_nums) > 1:
bugs = bugs[0] bugs = bugs[0]
#import pdb; pdb.set_trace() #import pdb; pdb.set_trace()
for bug in bugs: for bug in bugs:
bug = bug.value bug = bug.value
package = bug.package package = bug.package
bug_num = bug.bug_num bug_num = bug.bug_num
subject = bug.subject subject = bug.subject
log = debbugs.get_bug_log(bug_num) log = debbugs.get_bug_log(bug_num)
summary = log[0][0] summary = log[0][0]
target = ubuntu.getSourcePackage(name=package) target = ubuntu.getSourcePackage(name=package)
u_bug = lp.bugs.createBug(target=target, title=subject, u_bug = launchpad.bugs.createBug(target=target, title=subject,
description="Imported from Debian bug %d:\n\n%s" description="Imported from Debian bug %d:\n\n%s"
% (bug_num, summary)) % (bug_num, summary))
d_task = u_bug.addTask(target=debian.getSourcePackage(name=package)) d_task = u_bug.addTask(target=debian.getSourcePackage(name=package))
d_watch = u_bug.addWatch(remote_bug=bug_num, bug_tracker=lp_debbugs) d_watch = u_bug.addWatch(remote_bug=bug_num, bug_tracker=lp_debbugs)
d_task.bug_watch = d_watch d_task.bug_watch = d_watch
d_task.lp_save() d_task.lp_save()
web_url = translate_api_web(u_bug.self_link) web_url = translate_api_web(u_bug.self_link)
print "Opened %s" % web_url print "Opened %s" % web_url
if not options.browserless: if not options.browserless:
subprocess.call(["xdg-open", web_url]) subprocess.call(["xdg-open", web_url])
if __name__ == '__main__':
main()
#def get_status(*args): #def get_status(*args):
# result = server.get_status(*args) # result = server.get_status(*args)

View File

@ -29,33 +29,36 @@ from optparse import OptionParser
from ubuntutools.lp.libsupport import get_launchpad from ubuntutools.lp.libsupport import get_launchpad
from launchpadlib.errors import HTTPError from launchpadlib.errors import HTTPError
if __name__ == '__main__': def main():
usage = "Usage: %prog <bug> [...]" usage = "Usage: %prog <bug> [...]"
parser = OptionParser(usage) parser = OptionParser(usage)
options, args = parser.parse_args() args = parser.parse_args()[1]
if len(args) < 1: if len(args) < 1:
parser.error("Need at least one bug number") parser.error("Need at least one bug number")
try: try:
lp = get_launchpad('ubuntu-dev-tools') launchpad = get_launchpad('ubuntu-dev-tools')
except Exception, e: except Exception, error:
print >> sys.stderr, 'Could not connect to Launchpad:', str(e) print >> sys.stderr, 'Could not connect to Launchpad:', str(error)
sys.exit(2) sys.exit(2)
for bugnum in args: for bugnum in args:
try: try:
bug = lp.bugs[bugnum] bug = launchpad.bugs[bugnum]
print "Bug %s: %s" % (bugnum, bug.title) print "Bug %s: %s" % (bugnum, bug.title)
for task in bug.bug_tasks: for task in bug.bug_tasks:
print " %s: %s" % (task.bug_target_name, task.status) print " %s: %s" % (task.bug_target_name, task.status)
except HTTPError, e: except HTTPError, error:
if e.response.status == 401: if error.response.status == 401:
print >> sys.stderr, \ print >> sys.stderr, \
("E: Don't have enough permissions to access bug %s" % ("E: Don't have enough permissions to access bug %s" %
bugnum) bugnum)
print >> sys.stderr, e.content print >> sys.stderr, error.content
continue continue
elif e.response.status == 404: elif error.response.status == 404:
print >> sys.stderr, "E: Bug %s not found" % bugnum print >> sys.stderr, "E: Bug %s not found" % bugnum
else: else:
raise raise
if __name__ == '__main__':
main()

View File

@ -18,7 +18,11 @@
'''Upload a release tarball to a Launchpad project.''' '''Upload a release tarball to a Launchpad project.'''
import sys, datetime, os.path, subprocess, tempfile, os import datetime
import os
import subprocess
import sys
import tempfile
from ubuntutools.lp.libsupport import get_launchpad from ubuntutools.lp.libsupport import get_launchpad
from launchpadlib.errors import HTTPError from launchpadlib.errors import HTTPError
@ -32,19 +36,19 @@ def create_release(project, version):
if answer.startswith('n'): if answer.startswith('n'):
sys.exit(0) sys.exit(0)
n_series = len(proj.series) n_series = len(project.series)
if n_series == 1: if n_series == 1:
series = proj.series[0] series = project.series[0]
elif n_series > 1: elif n_series > 1:
msg = 'More than one series exist. Which one would you like to ' \ msg = 'More than one series exist. Which one would you like to ' \
'upload to? Possible series are (listed as index, name):' 'upload to? Possible series are (listed as index, name):'
print msg print msg
for idx, serie in enumerate(proj.series): for idx, serie in enumerate(project.series):
print '\t%i - %s' % (idx, serie.name) print '\t%i - %s' % (idx, serie.name)
print 'Enter series index: ' print 'Enter series index: '
answer = sys.stdin.readline().strip() answer = sys.stdin.readline().strip()
try: try:
series = proj.series[int(answer)] series = project.series[int(answer)]
except (ValueError, IndexError): except (ValueError, IndexError):
print >> sys.stderr, 'The series index is invalid (%s).' % answer print >> sys.stderr, 'The series index is invalid (%s).' % answer
sys.exit(3) sys.exit(3)
@ -67,75 +71,74 @@ def edit_file(prefix, description):
os.close(fd) os.close(fd)
subprocess.call(['sensible-editor', f]) subprocess.call(['sensible-editor', f])
content = '' content = ''
for l in open(f): for line in open(f):
if l.startswith('#'): if line.startswith('#'):
continue continue
content += l content += line
return content.strip() return content.strip()
# def main():
# main if len(sys.argv) != 4:
# print >> sys.stderr, '''Upload a release tarball to a Launchpad project.
if len(sys.argv) != 4: Usage: %s <project name> <version> <tarball>''' % sys.argv[0]
print >> sys.stderr, '''Upload a release tarball to a Launchpad project. sys.exit(1)
Usage: %s <project name> <version> <tarball>''' % sys.argv[0] (project, version, tarball) = sys.argv[1:]
sys.exit(1)
(project, version, tarball) = sys.argv[1:] try:
launchpad = get_launchpad('ubuntu-dev-tools')
except Exception, error:
print >> sys.stderr, 'Could not connect to Launchpad:', str(error)
sys.exit(2)
try: try:
lp = get_launchpad('ubuntu-dev-tools') # Look up the project using the Launchpad instance.
except Exception, e: proj = launchpad.projects[project]
print >> sys.stderr, 'Could not connect to Launchpad:', str(e) # Find the release in the project's releases collection.
sys.exit(2) release = None
for rel in proj.releases:
if rel.version == version:
release = rel
break
if not release:
release = create_release(proj, version)
try: # Get the file contents.
# Look up the project using the Launchpad instance. file_content = open(tarball, 'r').read()
proj = lp.projects[project] # Get the signature, if available.
# Find the release in the project's releases collection. signature = tarball + '.asc'
release = None if not os.path.exists(signature):
for rel in proj.releases: print 'Calling GPG to create tarball signature...'
if rel.version == version: cmd = ['gpg', '--armor', '--sign', '--detach-sig', tarball]
release = rel if subprocess.call(cmd) != 0:
break print >> sys.stderr, 'gpg failed, aborting'
if not release:
release = create_release(proj, version)
# Get the file contents. if os.path.exists(signature):
file_content = open(tarball, 'r').read() signature_content = open(signature, 'r').read()
# Get the signature, if available. else:
signature = tarball + '.asc' signature_content = None
if not os.path.exists(signature):
print 'Calling GPG to create tarball signature...'
cmd = ['gpg', '--armor', '--sign', '--detach-sig', tarball]
if subprocess.call(cmd) != 0:
print >> sys.stderr, 'gpg failed, aborting'
if os.path.exists(signature): # Create a new product release file.
signature_content = open(signature, 'r').read() filename = os.path.basename(tarball)
else: release.add_file(filename=filename, description='release tarball',
signature_content = None file_content=file_content, content_type='appplication/x-gzip',
file_type='Code Release Tarball', signature_filename=signature,
signature_content=signature_content)
# Create a new product release file. changelog = edit_file('changelog', 'changelog')
filename = os.path.basename(tarball) if changelog:
release.add_file(filename=filename, description='release tarball', release.changelog = changelog
file_content=file_content, content_type='appplication/x-gzip', release_notes = edit_file('releasenotes', 'release notes')
file_type='Code Release Tarball', signature_filename=signature, if release_notes:
signature_content=signature_content) release.release_notes = release_notes
changelog = edit_file('changelog', 'changelog') release.lp_save()
if changelog:
release.changelog = changelog
release_notes = edit_file('releasenotes', 'release notes')
if release_notes:
release.release_notes = release_notes
release.lp_save() except HTTPError, error:
print 'An error happened in the upload:', error.content
except HTTPError, e: sys.exit(1)
print 'An error happened in the upload:', e.content
sys.exit(1)
if __name__ == '__main__':
main()

View File

@ -84,15 +84,15 @@ def main():
raise raise
new_main_dup_of = new_main_bug.duplicate_of new_main_dup_of = new_main_bug.duplicate_of
if new_main_dup_of is not None: if new_main_dup_of is not None:
s = None answer = None
try: try:
s = raw_input("Bug %s is a duplicate of %s; would you like to use " answer = raw_input("Bug %s is a duplicate of %s; would you like to "
"%s as the new main bug instead? [y/N]" % \ "use %s as the new main bug instead? [y/N]" % \
(new_main_bug.id, new_main_dup_of.id, (new_main_bug.id, new_main_dup_of.id,
new_main_dup_of.id)) new_main_dup_of.id))
except: except:
die("Aborted") die("Aborted")
if s.lower() not in ("y", "yes"): if answer.lower() not in ("y", "yes"):
die("User aborted") die("User aborted")
new_main_bug = new_main_dup_of new_main_bug = new_main_dup_of
@ -121,12 +121,12 @@ def main():
(new_main_bug.id, " ".join([str(b.id) for b in bugs_to_process])) (new_main_bug.id, " ".join([str(b.id) for b in bugs_to_process]))
if not options.force: if not options.force:
s = None answer = None
try: try:
s = raw_input("Proceed? [y/N]") answer = raw_input("Proceed? [y/N]")
except: except:
die("Aborted") die("Aborted")
if s.lower() not in ("y", "yes"): if answer.lower() not in ("y", "yes"):
die("User aborted") die("User aborted")
for bug in bugs_to_process: for bug in bugs_to_process:

104
lp-shell
View File

@ -23,60 +23,64 @@ from optparse import OptionParser
from launchpadlib.launchpad import Launchpad from launchpadlib.launchpad import Launchpad
from launchpadlib.uris import lookup_service_root from launchpadlib.uris import lookup_service_root
instance = 'production' def main():
valid_api_versions = ('beta', '1.0', 'devel') instance = 'production'
api_version = '1.0' valid_api_versions = ('beta', '1.0', 'devel')
api_version = '1.0'
usage = 'Usage: %prog [-a] [instance] [LP API version]' usage = 'Usage: %prog [-a] [instance] [LP API version]'
optParser = OptionParser(usage) opt_parser = OptionParser(usage)
optParser.add_option('-a', action='store_true', opt_parser.add_option('-a', action='store_true',
dest='anonymous', default=False, dest='anonymous', default=False,
help='Login anonymously into LP.') help='Login anonymously into LP.')
(options, args) = optParser.parse_args() (options, args) = opt_parser.parse_args()
if len(args) >= 1: if len(args) >= 1:
try:
instance = lookup_service_root(args[0])
except ValueError, err:
print 'E: %s' % (err)
print 'I: Falling back to "production".'
if len(args) >= 2:
if args[1] in valid_api_versions:
api_version = args[1]
else:
print 'E: "%s" is not a valid LP API version.' % (args[1])
print 'I: Falling back to "1.0".'
if options.anonymous:
lp = Launchpad.login_anonymously('udt-lp-shell', instance,
version=api_version)
banner = 'Connected anonymously to LP service "%s" with API version "%s":' \
% (instance, api_version)
else:
lp = Launchpad.login_with('udt-lp-shell', instance, version=api_version)
banner = 'Connected to LP service "%s" with API version "%s":' % \
(instance, api_version)
banner += '\nNote: LP can be accessed through the "lp" object.'
class CompleterConsole(code.InteractiveConsole):
def __init__(self):
local = {'lp': lp}
code.InteractiveConsole.__init__(self,
locals=local)
try: try:
import readline instance = lookup_service_root(args[0])
except ImportError: except ValueError, err:
print 'I: readline module not available.' print 'E: %s' % (err)
print 'I: Falling back to "production".'
if len(args) >= 2:
if args[1] in valid_api_versions:
api_version = args[1]
else: else:
import rlcompleter print 'E: "%s" is not a valid LP API version.' % (args[1])
readline.parse_and_bind("tab: complete") print 'I: Falling back to "1.0".'
# Disable default apport hook, as lp-shell is intended for interactive use if options.anonymous:
# and thus exceptions often bubble up to the top level. launchpad = Launchpad.login_anonymously('udt-lp-shell', instance,
sys.excepthook = sys.__excepthook__ version=api_version)
banner = ('Connected anonymously to LP service "%s" with API version '
'"%s":' % (instance, api_version))
else:
launchpad = Launchpad.login_with('udt-lp-shell', instance,
version=api_version)
banner = 'Connected to LP service "%s" with API version "%s":' % \
(instance, api_version)
console = CompleterConsole() banner += '\nNote: LP can be accessed through the "lp" object.'
console.interact(banner)
class CompleterConsole(code.InteractiveConsole):
def __init__(self):
local = {'lp': launchpad}
code.InteractiveConsole.__init__(self, locals=local)
try:
import readline
except ImportError:
print 'I: readline module not available.'
else:
import rlcompleter
readline.parse_and_bind("tab: complete")
# Disable default apport hook, as lp-shell is intended for interactive use
# and thus exceptions often bubble up to the top level.
sys.excepthook = sys.__excepthook__
console = CompleterConsole()
console.interact(banner)
if __name__ == '__main__':
main()

View File

@ -96,12 +96,13 @@ def create_credentials(options):
if options.output: if options.output:
filepath = options.output filepath = options.output
else: else:
credentialsDir = os.path.expanduser("~/.cache/lp_credentials") credentials_dir = os.path.expanduser("~/.cache/lp_credentials")
if not os.path.isdir(credentialsDir): if not os.path.isdir(credentials_dir):
os.makedirs(credentialsDir) os.makedirs(credentials_dir)
os.chmod(credentialsDir, 0700) os.chmod(credentials_dir, 0700)
filepath = os.path.expanduser("%s/%s-%s.txt" % \ filepath = os.path.expanduser("%s/%s-%s.txt" %
(credentialsDir, options.consumer, str(options.level).lower())) (credentials_dir, options.consumer,
str(options.level).lower()))
f = open(filepath, "w") f = open(filepath, "w")
# Make credentials file non-world readable. # Make credentials file non-world readable.

View File

@ -88,16 +88,16 @@ def file_bug(config, launchpad):
product_url = "%subuntu/+source/%s" % \ product_url = "%subuntu/+source/%s" % \
(launchpad._root_uri, config["sourcepackage"]) (launchpad._root_uri, config["sourcepackage"])
tags = filter(None, map(lambda t: t.strip("\n").strip(), tags = [t for t in [t.strip("\n").strip() for t in
config["tags"].split(","))) config["tags"].split(",")] if t]
bug = launchpad.bugs.createBug(description=description, title=summary, bug = launchpad.bugs.createBug(description=description, title=summary,
target=product_url, tags=tags) target=product_url, tags=tags)
print "Successfully filed bug %i: %s" % \ print "Successfully filed bug %i: %s" % \
(bug.id, translate_api_web(bug.self_link)) (bug.id, translate_api_web(bug.self_link))
subscribers = filter(None, map(lambda t: t.strip("\n").strip(), subscribers = [s for s in [s.strip("\n").strip() for s in
config["subscribers"].split(","))) config["subscribers"].split(",")] if s]
for sub in subscribers: for sub in subscribers:
subscribe_url = "%s~%s" % (launchpad._root_uri, sub) subscribe_url = "%s~%s" % (launchpad._root_uri, sub)
bug.subscribe(person=subscribe_url) bug.subscribe(person=subscribe_url)
@ -145,18 +145,19 @@ def read_buglist(url, launchpad):
return packages return packages
def main(): def main():
p = optparse.OptionParser(description= description = ('Files bugs against multiple packages in Ubuntu. '
'Files bugs against multiple packages in Ubuntu. ' 'Reads the bug from "instructions" and files them against '
'Reads the bug from "instructions" and files them against ' 'packages listed in "list". '
'packages listed in "list". ' "If these files aren't preset they are created.")
"If these files aren't preset they are created.") parser = optparse.OptionParser(description=description)
p.add_option('-l', '--lpinstance', metavar='INSTANCE', parser.add_option('-l', '--lpinstance', metavar='INSTANCE',
dest='lpinstance', default=None, dest='lpinstance', default=None,
help='Launchpad instance to connect to (default: production)') help='Launchpad instance to connect to '
p.add_option('--no-conf', '(default: production)')
dest='no_conf', default=False, action='store_true', parser.add_option('--no-conf',
help="Don't read config files or environment variables") dest='no_conf', default=False, action='store_true',
options, args = p.parse_args() help="Don't read config files or environment variables")
options = parser.parse_args()[0]
udtconfig = UDTConfig(options.no_conf) udtconfig = UDTConfig(options.no_conf)
if options.lpinstance is None: if options.lpinstance is None:
options.lpinstance = udtconfig.get_value('LPINSTANCE') options.lpinstance = udtconfig.get_value('LPINSTANCE')

View File

@ -18,9 +18,10 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import sys, re import re
import sys
def usage(exit=1): def usage(exit_code=1):
print '''Usage: merge-changelog <left changelog> <right changelog> print '''Usage: merge-changelog <left changelog> <right changelog>
merge-changelog takes two changelogs that once shared a common source, merge-changelog takes two changelogs that once shared a common source,
@ -28,7 +29,7 @@ merges them back together, and prints the merged result to stdout. This
is useful if you need to manually merge a ubuntu package with a new is useful if you need to manually merge a ubuntu package with a new
Debian release of the package. Debian release of the package.
''' '''
sys.exit(exit) sys.exit(exit_code)
######################################################################## ########################################################################
# Changelog Management # Changelog Management
@ -54,7 +55,7 @@ def merge_changelog(left_changelog, right_changelog):
print right_text print right_text
for left_ver, left_text in left_cl: for _, left_text in left_cl:
print left_text print left_text
return False return False
@ -63,10 +64,10 @@ def read_changelog(filename):
"""Return a parsed changelog file.""" """Return a parsed changelog file."""
entries = [] entries = []
cl = open(filename) changelog_file = open(filename)
try: try:
(ver, text) = (None, "") (ver, text) = (None, "")
for line in cl: for line in changelog_file:
match = CL_RE.search(line) match = CL_RE.search(line)
if match: if match:
try: try:
@ -85,7 +86,7 @@ def read_changelog(filename):
elif len(line.strip()) or ver is not None: elif len(line.strip()) or ver is not None:
text += line text += line
finally: finally:
cl.close() changelog_file.close()
if len(text): if len(text):
entries.append((ver, text)) entries.append((ver, text))
@ -96,12 +97,12 @@ def read_changelog(filename):
# Version parsing code # Version parsing code
######################################################################## ########################################################################
# Regular expressions make validating things easy # Regular expressions make validating things easy
valid_epoch = re.compile(r'^[0-9]+$') VALID_EPOCH = re.compile(r'^[0-9]+$')
valid_upstream = re.compile(r'^[A-Za-z0-9+:.~-]*$') VALID_UPSTREAM = re.compile(r'^[A-Za-z0-9+:.~-]*$')
valid_revision = re.compile(r'^[A-Za-z0-9+.~]+$') VALID_REVISION = re.compile(r'^[A-Za-z0-9+.~]+$')
# Character comparison table for upstream and revision components # Character comparison table for upstream and revision components
cmp_table = "~ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+-.:" CMP_TABLE = "~ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+-.:"
class Version(object): class Version(object):
@ -137,7 +138,7 @@ class Version(object):
self.epoch = ver[:idx] self.epoch = ver[:idx]
if not len(self.epoch): if not len(self.epoch):
raise ValueError raise ValueError
if not valid_epoch.search(self.epoch): if not VALID_EPOCH.search(self.epoch):
raise ValueError raise ValueError
ver = ver[idx+1:] ver = ver[idx+1:]
@ -147,7 +148,7 @@ class Version(object):
self.revision = ver[idx+1:] self.revision = ver[idx+1:]
if not len(self.revision): if not len(self.revision):
raise ValueError raise ValueError
if not valid_revision.search(self.revision): if not VALID_REVISION.search(self.revision):
raise ValueError raise ValueError
ver = ver[:idx] ver = ver[:idx]
@ -155,29 +156,29 @@ class Version(object):
self.upstream = ver self.upstream = ver
if not len(self.upstream): if not len(self.upstream):
raise ValueError raise ValueError
if not valid_upstream.search(self.upstream): if not VALID_UPSTREAM.search(self.upstream):
raise ValueError raise ValueError
self.epoch = int(self.epoch) self.epoch = int(self.epoch)
def getWithoutEpoch(self): def get_without_epoch(self):
"""Return the version without the epoch.""" """Return the version without the epoch."""
str = self.upstream string = self.upstream
if self.revision is not None: if self.revision is not None:
str += "-%s" % (self.revision,) string += "-%s" % (self.revision,)
return str return string
without_epoch = property(getWithoutEpoch) without_epoch = property(get_without_epoch)
def __str__(self): def __str__(self):
"""Return the class as a string for printing.""" """Return the class as a string for printing."""
str = "" string = ""
if self.epoch > 0: if self.epoch > 0:
str += "%d:" % (self.epoch,) string += "%d:" % (self.epoch,)
str += self.upstream string += self.upstream
if self.revision is not None: if self.revision is not None:
str += "-%s" % (self.revision,) string += "-%s" % (self.revision,)
return str return string
def __repr__(self): def __repr__(self):
"""Return a debugging representation of the object.""" """Return a debugging representation of the object."""
@ -190,34 +191,37 @@ class Version(object):
other = Version(other) other = Version(other)
result = cmp(self.epoch, other.epoch) result = cmp(self.epoch, other.epoch)
if result != 0: return result if result != 0:
return result
result = deb_cmp(self.upstream, other.upstream) result = deb_cmp(self.upstream, other.upstream)
if result != 0: return result if result != 0:
return result
result = deb_cmp(self.revision or "", other.revision or "") result = deb_cmp(self.revision or "", other.revision or "")
if result != 0: return result if result != 0:
return result
return 0 return 0
def strcut(str, idx, accept): def strcut(string, idx, accept):
"""Cut characters from str that are entirely in accept.""" """Cut characters from string that are entirely in accept."""
ret = "" ret = ""
while idx < len(str) and str[idx] in accept: while idx < len(string) and string[idx] in accept:
ret += str[idx] ret += string[idx]
idx += 1 idx += 1
return (ret, idx) return (ret, idx)
def deb_order(str, idx): def deb_order(string, idx):
"""Return the comparison order of two characters.""" """Return the comparison order of two characters."""
if idx >= len(str): if idx >= len(string):
return 0 return 0
elif str[idx] == "~": elif string[idx] == "~":
return -1 return -1
else: else:
return cmp_table.index(str[idx]) return CMP_TABLE.index(string[idx])
def deb_cmp_str(x, y): def deb_cmp_str(x, y):
"""Compare two strings in a deb version.""" """Compare two strings in a deb version."""
@ -238,25 +242,27 @@ def deb_cmp(x, y):
x_idx = y_idx = 0 x_idx = y_idx = 0
while x_idx < len(x) or y_idx < len(y): while x_idx < len(x) or y_idx < len(y):
# Compare strings # Compare strings
(x_str, x_idx) = strcut(x, x_idx, cmp_table) (x_str, x_idx) = strcut(x, x_idx, CMP_TABLE)
(y_str, y_idx) = strcut(y, y_idx, cmp_table) (y_str, y_idx) = strcut(y, y_idx, CMP_TABLE)
result = deb_cmp_str(x_str, y_str) result = deb_cmp_str(x_str, y_str)
if result != 0: return result if result != 0:
return result
# Compare numbers # Compare numbers
(x_str, x_idx) = strcut(x, x_idx, "0123456789") (x_str, x_idx) = strcut(x, x_idx, "0123456789")
(y_str, y_idx) = strcut(y, y_idx, "0123456789") (y_str, y_idx) = strcut(y, y_idx, "0123456789")
result = cmp(int(x_str or "0"), int(y_str or "0")) result = cmp(int(x_str or "0"), int(y_str or "0"))
if result != 0: return result if result != 0:
return result
return 0 return 0
def main(): def main():
if len(sys.argv) > 1 and sys.argv[1] in ('-h', '--help'): if len(sys.argv) > 1 and sys.argv[1] in ('-h', '--help'):
usage(exit=0) usage(0)
if len(sys.argv) != 3: if len(sys.argv) != 3:
usage(exit=1) usage(1)
left_changelog = sys.argv[1] left_changelog = sys.argv[1]
right_changelog = sys.argv[2] right_changelog = sys.argv[2]

View File

@ -38,7 +38,7 @@ import ubuntutools.misc
DEBIAN_DISTROS = ['etch', 'lenny', 'squeeze', 'sid', 'stable', 'testing', DEBIAN_DISTROS = ['etch', 'lenny', 'squeeze', 'sid', 'stable', 'testing',
'unstable', 'experimental'] 'unstable', 'experimental']
class pbuilder_dist: class PbuilderDist:
def __init__(self, builder): def __init__(self, builder):
# Base directory where pbuilder will put all the files it creates. # Base directory where pbuilder will put all the files it creates.
self.base = None self.base = None
@ -116,7 +116,7 @@ class pbuilder_dist:
self.target_distro = self.system_distro self.target_distro = self.system_distro
def set_target_distro(self, distro): def set_target_distro(self, distro):
""" pbuilder_dist.set_target_distro(distro) -> None """ PbuilderDist.set_target_distro(distro) -> None
Check if the given target distribution name is correct, if it Check if the given target distribution name is correct, if it
isn't know to the system ask the user for confirmation before isn't know to the system ask the user for confirmation before
@ -145,7 +145,7 @@ class pbuilder_dist:
self.target_distro = distro self.target_distro = distro
def set_operation(self, operation): def set_operation(self, operation):
""" pbuilder_dist.set_operation -> None """ PbuilderDist.set_operation -> None
Check if the given string is a valid pbuilder operation and Check if the given string is a valid pbuilder operation and
depending on this either save it into the appropiate variable depending on this either save it into the appropiate variable
@ -172,7 +172,7 @@ class pbuilder_dist:
return [] return []
def get_command(self, remaining_arguments = None): def get_command(self, remaining_arguments = None):
""" pbuilder_dist.get_command -> string """ PbuilderDist.get_command -> string
Generate the pbuilder command which matches the given configuration Generate the pbuilder command which matches the given configuration
and return it as a string. and return it as a string.
@ -329,7 +329,7 @@ def show_help(exit_code = 0):
def main(): def main():
""" main() -> None """ main() -> None
This is pbuilder-dist's main function. It creates a pbuilder_dist This is pbuilder-dist's main function. It creates a PbuilderDist
object, modifies all necessary settings taking data from the object, modifies all necessary settings taking data from the
executable's name and command line options and finally either ends executable's name and command line options and finally either ends
the script and runs pbuilder itself or exists with an error message. the script and runs pbuilder itself or exists with an error message.
@ -353,7 +353,7 @@ def main():
if args[0] in ('-h', '--help', 'help'): if args[0] in ('-h', '--help', 'help'):
show_help(0) show_help(0)
app = pbuilder_dist(parts[0]) app = PbuilderDist(parts[0])
if len(parts) > 1 and parts[1] != 'dist' and '.' not in parts[1]: if len(parts) > 1 and parts[1] != 'dist' and '.' not in parts[1]:
app.set_target_distro(parts[1]) app.set_target_distro(parts[1])