- Support this in many u-d-t scripts, and update manpages.

- Deprecate old configuration environment variables.
This commit is contained in:
Stefano Rivera 2010-12-22 21:33:58 +01:00 committed by Benjamin Drung
commit 30df1c0ec8
15 changed files with 252 additions and 124 deletions

View File

@ -28,6 +28,7 @@ import logging
import glob import glob
import fnmatch import fnmatch
from ubuntutools.config import UDTConfig
from ubuntutools.lp.libsupport import get_launchpad from ubuntutools.lp.libsupport import get_launchpad
COMMAND_LINE_SYNTAX_ERROR = 1 COMMAND_LINE_SYNTAX_ERROR = 1
@ -147,8 +148,9 @@ def unsubscribe_sponsors(launchpad, bug):
def main(bug_numbers, all_package, all_version, all_section, update, def main(bug_numbers, all_package, all_version, all_section, update,
all_uploader_email, key, upload, verbose=False, silent=False): all_uploader_email, key, upload, lpinstance, verbose=False,
launchpad = get_launchpad("ubuntu-dev-tools") silent=False):
launchpad = get_launchpad("ubuntu-dev-tools", server=lpinstance)
# TODO: use release-info (once available) # TODO: use release-info (once available)
series = launchpad.distributions["ubuntu"].current_series series = launchpad.distributions["ubuntu"].current_series
dist = series.name dist = series.name
@ -300,8 +302,11 @@ def usage():
-e, specify uploader email address -e, specify uploader email address
-h, --help displays this help -h, --help displays this help
-k, --key key used to sign the package (in case of sponsoring) -k, --key key used to sign the package (in case of sponsoring)
--lpinstance=<instance> Launchpad instance to connect to
(default: production)
-l, --lvm lvm root dev directory, used for sbuild and piuparts -l, --lvm lvm root dev directory, used for sbuild and piuparts
default is /dev/vg default is /dev/vg
--no-conf Don't read config files or environment variables
-p, --package=<package> set the package -p, --package=<package> set the package
-P, --with-piuparts use piuparts to check the instalability -P, --with-piuparts use piuparts to check the instalability
--section=<section> Debian section (one of main, contrib, non-free) --section=<section> Debian section (one of main, contrib, non-free)
@ -318,7 +323,7 @@ if __name__ == '__main__':
try: try:
long_opts = ["help", "key=", "lvm=", "package=", "section=", "silent", long_opts = ["help", "key=", "lvm=", "package=", "section=", "silent",
"update", "upload", "verbose", "version=", "with-sbuild", "update", "upload", "verbose", "version=", "with-sbuild",
"pbuilder=", "with-piuparts"] "pbuilder=", "with-piuparts", "lpinstance=", "no-conf"]
opts, args = getopt.gnu_getopt(sys.argv[1:], "e:hk:p:PsSC:uUvV:", long_opts) opts, args = getopt.gnu_getopt(sys.argv[1:], "e:hk:p:PsSC:uUvV:", long_opts)
except getopt.GetoptError, e: except getopt.GetoptError, e:
# will print something like "option -a not recognized" # will print something like "option -a not recognized"
@ -335,9 +340,11 @@ if __name__ == '__main__':
verbose = False verbose = False
version = None version = None
piuparts = False piuparts = False
pbuilder = 'pbuilder' pbuilder = None
lvm = "/dev/vg" lvm = "/dev/vg"
key = None key = None
lpinstance = None
no_conf = False
for o, a in opts: for o, a in opts:
if o in ("-h", "--help"): if o in ("-h", "--help"):
@ -347,8 +354,12 @@ if __name__ == '__main__':
uploader_email = a uploader_email = a
elif o in ("-k", "--key"): elif o in ("-k", "--key"):
key = a key = a
elif o in ("--lpinstance"):
lpinstance = a
elif o in ("-l", "--lvm"): elif o in ("-l", "--lvm"):
lvm = a lvm = a
elif o in ("--no-conf"):
no_conf = True
elif o in ("-p", "--package"): elif o in ("-p", "--package"):
package = a package = a
elif o in ("-P", "--with-piuparts"): elif o in ("-P", "--with-piuparts"):
@ -360,7 +371,7 @@ if __name__ == '__main__':
elif o in ("-S", "--with-sbuild"): elif o in ("-S", "--with-sbuild"):
sbuild = True sbuild = True
elif o in ("-C", "--pbuilder"): elif o in ("-C", "--pbuilder"):
pbuilder=a pbuilder=a
elif o in ("-u", "--update"): elif o in ("-u", "--update"):
update = True update = True
elif o in ("-U", "--upload"): elif o in ("-U", "--upload"):
@ -387,5 +398,21 @@ if __name__ == '__main__':
sys.exit(COMMAND_LINE_SYNTAX_ERROR) sys.exit(COMMAND_LINE_SYNTAX_ERROR)
bug_numbers.append(number) bug_numbers.append(number)
config = UDTConfig(no_conf)
if lpinstance is None:
lpinstance = config.get_value('LPINSTANCE')
if pbuilder is None and not sbuild:
builder = config.get_value('BUILDER')
if builder == 'pbuilder':
pbuilder = 'pbuilder'
elif builder == 'sbuild':
sbuild = True
else:
print >> sys.stderr, "E: Unsupported build-system: %s" % builder
sys.exit(COMMAND_LINE_SYNTAX_ERROR)
if not update:
update = config.get_value('UPDATE_BUILDER', boolean=True)
#TODO: Support WORKDIR
main(bug_numbers, package, version, section, update, uploader_email, key, main(bug_numbers, package, version, section, update, uploader_email, key,
upload, verbose, silent) upload, lpinstance, verbose, silent)

View File

@ -98,8 +98,8 @@ def parse(args):
default=None, default=None,
help='Specify a working directory (default: temporary dir)', help='Specify a working directory (default: temporary dir)',
metavar='WORKDIR') metavar='WORKDIR')
p.add_option('-l', '--launchpad', p.add_option('-l', '--lpinstance',
dest='launchpad', dest='lpinstance',
default=None, default=None,
help='Launchpad instance to connect to (default: production)', help='Launchpad instance to connect to (default: production)',
metavar='INSTANCE') metavar='INSTANCE')
@ -119,8 +119,8 @@ def parse(args):
opts.update = config.get_value('UPDATE_BUILDER', boolean=True) opts.update = config.get_value('UPDATE_BUILDER', boolean=True)
if opts.workdir is None: if opts.workdir is None:
opts.workdir = config.get_value('WORKDIR') opts.workdir = config.get_value('WORKDIR')
if opts.launchpad is None: if opts.lpinstance is None:
opts.launchpad = config.get_value('LPINSTANCE') opts.lpinstance = config.get_value('LPINSTANCE')
if not opts.upload and not opts.workdir: if not opts.upload and not opts.workdir:
p.error('Please specify either a working dir or an upload target!') p.error('Please specify either a working dir or an upload target!')
@ -276,7 +276,7 @@ def main(args):
script_name = os.path.basename(sys.argv[0]) script_name = os.path.basename(sys.argv[0])
lp = launchpadlib.launchpad.Launchpad.login_anonymously(script_name, lp = launchpadlib.launchpad.Launchpad.login_anonymously(script_name,
opts.launchpad) opts.lpinstance)
if not opts.dest_releases: if not opts.dest_releases:
try: try:

2
debian/changelog vendored
View File

@ -19,6 +19,8 @@ ubuntu-dev-tools (0.109) UNRELEASED; urgency=low
- 404main, merge-changelog, pull-debian-debdiff, pull-debian-source, - 404main, merge-changelog, pull-debian-debdiff, pull-debian-source,
pull-revu-source: pull-revu-source:
+ Return 0 after showing help. + Return 0 after showing help.
- Support this in many u-d-t scripts, and update manpages.
- Deprecate old configuration environment variables.
* ubuntutools/common.py: Remove https_proxy unsetting code, working around * ubuntutools/common.py: Remove https_proxy unsetting code, working around
LP: #94130. LP: #94130.
* edit-patch: Don't let cat error through if debian/source/format doesn't * edit-patch: Don't let cat error through if debian/source/format doesn't

View File

@ -80,7 +80,7 @@ unpacked, built into, and otherwise manipulated in
\fIWORKDIR\fR. Otherwise, a temporary directory is created, which is \fIWORKDIR\fR. Otherwise, a temporary directory is created, which is
deleted before \fIbackportpackage\fR exits. deleted before \fIbackportpackage\fR exits.
.TP .TP
.B \-l \fIINSTANCE\fR, \fB\-\-launchpad\fR=\fIINSTANCE\fR .B \-l \fIINSTANCE\fR, \fB\-\-lpinstance\fR=\fIINSTANCE\fR
Use the specified instance of Launchpad (e.g. "staging"), instead of Use the specified instance of Launchpad (e.g. "staging"), instead of
the default of "production". the default of "production".
.TP .TP
@ -109,7 +109,7 @@ The default value for \fB--update\fR.
The default value for \fB--workdir\fR. The default value for \fB--workdir\fR.
.TP .TP
.BR BACKPORTPACKAGE_LPINSTANCE ", " UBUNTUTOOLS_LPINSTANCE .BR BACKPORTPACKAGE_LPINSTANCE ", " UBUNTUTOOLS_LPINSTANCE
The default value for \fB--launchpad\fR. The default value for \fB--lpinstance\fR.
.SH EXAMPLES .SH EXAMPLES
Test-build in your PPA a backport of znc from the current development Test-build in your PPA a backport of znc from the current development
release to your workstation's release, deleting the build products release to your workstation's release, deleting the build products

View File

@ -2,7 +2,7 @@
.SH NAME .SH NAME
grab\-attachments \- downloads attachments from a Launchpad bug grab\-attachments \- downloads attachments from a Launchpad bug
.SH SYNOPSIS .SH SYNOPSIS
.B grab\-attachments\fR <\fIbug-number\fR> .B grab\-attachments\fR [\fIoptions\fR] \fIbug-number\fR...
.br .br
.B grab\-attachments \-h .B grab\-attachments \-h
.SH DESCRIPTION .SH DESCRIPTION
@ -12,13 +12,36 @@ Launchpad bug report into the current directory.
.SH OPTIONS .SH OPTIONS
Listed below are the command line options for grab\-attachments: Listed below are the command line options for grab\-attachments:
.TP .TP
.B \-h .I bug-number
Display a help message and exit.
.TP
.B <bug-number>
Specifies the Launchpad bug number that the script should download Specifies the Launchpad bug number that the script should download
attachments from. attachments from.
.TP
.BR \-h ", " \-\-help
Display a help message and exit.
.TP
.B \-l \fIINSTANCE\fR, \fB\-\-lpinstance\fR=\fIINSTANCE\fR
Use the specified instance of Launchpad (e.g. "staging"), instead of
the default of "production".
.TP
.B \-\-no\-conf
Do not read any configuration files, or configuration from environment
variables.
.SH ENVIRONMENT
All of the \fBCONFIGURATION VARIABLES\fR below are also supported as
environment variables.
Variables in the environment take precedence to those in configuration
files.
.SH CONFIGURATION VARIABLES
The following variables can be set in the environment or in
.BR ubuntu\-dev\-tools (5)
configuration files.
In each case, the script\-specific variable takes precedence over the
package\-wide variable.
.TP
.BR GRAB_ATTACHMENTS_LPINSTANCE ", " UBUNTUTOOLS_LPINSTANCE
The default value for \fB--lpinstance\fR.
.SH SEE ALSO
.BR ubuntu\-dev\-tools (5)
.SH AUTHOR .SH AUTHOR
\fBgrab\-attachments\fR was written by Daniel Holbach and this manual page \fBgrab\-attachments\fR was written by Daniel Holbach and this manual page
was written by Jonathan Patrick Davies. was written by Jonathan Patrick Davies.

View File

@ -52,8 +52,6 @@ attempt to look it up in Ubuntu since it will not exist.
.TP .TP
.B \-k \fI<keyid>\fR .B \-k \fI<keyid>\fR
Specifies your GPG key. Specifies your GPG key.
Can also be set with the line `\fIexport GPGKEY=<keyid>\fR' in your shell's
configuration (for example: \fI$HOME/.bashrc\fR).
This is only used if the sync request is mailed to Launchpad. This is only used if the sync request is mailed to Launchpad.
.TP .TP
.B \-\-lp .B \-\-lp
@ -69,6 +67,14 @@ This disables the upload permissions check described above.
Use this flag after FeatureFreeze for non-bug fix syncs. \fBrequestsync\fR will Use this flag after FeatureFreeze for non-bug fix syncs. \fBrequestsync\fR will
subscribe ubuntu-release team instead of sponsorship team. subscribe ubuntu-release team instead of sponsorship team.
.TP .TP
.B \-l \fIINSTANCE\fR, \fB\-\-lpinstance\fR=\fIINSTANCE\fR
Use the specified instance of Launchpad (e.g. "staging"), instead of
the default of "production".
.TP
.B \-\-no\-conf
Do not read any configuration files, or configuration from environment
variables.
.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.
.TP .TP
@ -82,30 +88,40 @@ In some cases, the base version (where the Ubuntu package started differing
from the Debian package) cannot be automatically determined. from the Debian package) cannot be automatically determined.
Specify this option in this case. Specify this option in this case.
.SH ENVIRONMENT VARIABLES .SH ENVIRONMENT
\fBrequestsync\fR uses the following variables which should be set in your \fBrequestsync\fR uses the following variables which should be set in your
shell's configuration by adding \fIexport VARIABLE=\fR lines, where VARIABLE is shell's configuration by adding \fIexport VARIABLE=\fR lines, where VARIABLE is
one of the following: one of the following:
.TP .TP
.B GPGKEY .BR UBUMAIL ", " DEBEMAIL
Specifies your GnuPG key ID.
.TP
.B DEBEMAIL
Specifies which email should be used when sending to Launchpad. Specifies which email should be used when sending to Launchpad.
.P
All of the \fBCONFIGURATION VARIABLES\fR below are also supported as
environment variables.
Variables in the environment take precedence to those in configuration
files.
.SH CONFIGURATION VARIABLES
.TP .TP
.B DEBSMTP .B REQUESTSYNC_SMTP_SERVER
Set which SMTP server to use when sending mail. Set which SMTP server to use when sending mail.
If unspecified this defaults to fiordland.ubuntu.com. If unspecified this defaults to fiordland.ubuntu.com.
.TP .TP
.B DEBSMTP_PORT .B REQUESTSYNC_SMTP_PORT
Sets which port of the SMTP server to use. Default is 25. Sets which port of the SMTP server to use. Default is 25.
.TP .TP
.B DEBSMTP_USER \fRand\fB DEBSMTP_PASS .BR REQUESTSYNC_SMTP_USER " and " REQUESTSYNC_SMTP_PASS
Sets the username and password to use when authenticating to the SMTP server. Sets the username and password to use when authenticating to the SMTP server.
.TP
.BR REQUESTSYNC_USE_LPAPI
Setting this to \fIyes\fR is equivalent to running with \fB--lp\fR.
.TP
.BR REQUESTSYNC_LPINSTANCE ", " UBUNTUTOOLS_LPINSTANCE
The default value for \fB--lpinstance\fR.
.SH SEE ALSO .SH SEE ALSO
.BR rmadison (1) .BR rmadison (1),
.BR ubuntu\-dev\-tools (5)
.SH AUTHOR .SH AUTHOR
.B requestsync .B requestsync

View File

@ -1,7 +1,8 @@
#!/usr/bin/python #!/usr/bin/python
# #
# Copyright (C) 2007, Canonical Ltd. # Copyright (C) 2007, Canonical Ltd.
# Written by Daniel Holbach # Written by Daniel Holbach,
# Stefano Rivera
# #
# ################################################################## # ##################################################################
# #
@ -18,30 +19,38 @@
# #
# ################################################################## # ##################################################################
from optparse import OptionParser
import os import os
import sys import sys
from ubuntutools.config import UDTConfig
from ubuntutools.lp.libsupport import get_launchpad from ubuntutools.lp.libsupport import get_launchpad
USAGE = "grab-attachments <bug numbers>" USAGE = "grab-attachments <bug numbers>"
def main(): def main():
if len(sys.argv) == 1: p = OptionParser('Usage: %prog [options] <bug numbers>')
print >> sys.stderr, USAGE p.add_option('-l', '--lpinstance', metavar='INSTANCE',
sys.exit(1) dest='lpinstance', default=None,
help='Launchpad instance to connect to (default: production)')
if sys.argv[1] in ["--help", "-h"]: p.add_option('--no-conf',
print USAGE dest='no_conf', default=False, action='store_true',
sys.exit(0) help="Don't read config files or environment variables")
opts, args = p.parse_args()
if len(args) < 1:
p.error('No bug numbers provided')
config = UDTConfig(opts.no_conf)
if opts.lpinstance is None:
opts.lpinstance = config.get_value('LPINSTANCE')
try: try:
launchpad = get_launchpad("ubuntu-dev-tools") launchpad = get_launchpad("ubuntu-dev-tools", server=opts.lpinstance)
for arg in sys.argv[1:]: for arg in args:
try: try:
number = int(arg) number = int(arg)
except: except:
print >> sys.stderr, "'%s' is not a valid bug number." % arg p.error("'%s' is not a valid bug number." % arg)
sys.exit(1)
b = launchpad.bugs[number] b = launchpad.bugs[number]

View File

@ -26,11 +26,13 @@
# #
# ################################################################## # ##################################################################
import sys
from optparse import OptionParser from optparse import OptionParser
import os
import sys
from debian.changelog import Version from debian.changelog import Version
# ubuntu-dev-tools modules from ubuntutools.config import UDTConfig, ubu_email
from ubuntutools.lp import udtexceptions from ubuntutools.lp import udtexceptions
from ubuntutools.requestsync.common import (edit_report, getDebianChangelog, from ubuntutools.requestsync.common import (edit_report, getDebianChangelog,
raw_input_exit_on_ctrlc) raw_input_exit_on_ctrlc)
@ -41,32 +43,38 @@ from ubuntutools.requestsync.common import (edit_report, getDebianChangelog,
if __name__ == '__main__': if __name__ == '__main__':
# Our usage options. # Our usage options.
usage = 'Usage: %prog [-d distro] [-k keyid] [-n] [--lp] [-s] [-e] ' \ usage = 'Usage: %prog [options] ' \
'<source package> [<target release> [base version]]' '<source package> [<target release> [base version]]'
optParser = OptionParser(usage) optParser = OptionParser(usage)
optParser.add_option('-d', type = 'string', optParser.add_option('-d', type='string',
dest = 'dist', default = 'unstable', dest='dist', default='unstable',
help = 'Debian distribution to sync from.') help='Debian distribution to sync from.')
optParser.add_option('-k', type = 'string', optParser.add_option('-k', type='string',
dest = 'keyid', default = None, dest='keyid', default=None,
help = 'GnuPG key ID to use for signing report (only used when emailing the sync request).') help='GnuPG key ID to use for signing report (only used when emailing the sync request).')
optParser.add_option('-n', action = 'store_true', optParser.add_option('-n', action='store_true',
dest = 'newpkg', default = False, dest='newpkg', default=False,
help = 'Whether package to sync is a new package in Ubuntu.') help='Whether package to sync is a new package in Ubuntu.')
optParser.add_option('--lp', action = 'store_true', optParser.add_option('--lp', action='store_true',
dest = 'lpapi', default = False, dest='lpapi', default=False,
help = 'Specify whether to use the LP API for filing the sync request (recommended).') help='Specify whether to use the LP API for filing the sync request (recommended).')
optParser.add_option('-s', action = 'store_true', optParser.add_option('-l', '--lpinstance', type='string', metavar='INSTANCE',
dest = 'sponsorship', default = False, dest='lpinstance', default=None,
help = 'Force sponsorship') help='Launchpad instance to connect to (default: production).')
optParser.add_option('-C', action = 'store_true', optParser.add_option('-s', action='store_true',
dest = 'missing_changelog_ok', default = False, dest='sponsorship', default=False,
help = 'Allow changelog to be manually filled in when missing') help='Force sponsorship')
optParser.add_option('-e', action = 'store_true', optParser.add_option('-C', action='store_true',
dest = 'ffe', default = False, dest='missing_changelog_ok', default=False,
help = 'Use this after FeatureFreeze for non-bug fix syncs, changes ' \ 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.') 'default subscription to the appropriate release team.')
optParser.add_option('--no-conf', action='store_true',
dest='no_conf', default=False,
help="Don't read config files or environment variables")
(options, args) = optParser.parse_args() (options, args) = optParser.parse_args()
@ -74,6 +82,22 @@ if __name__ == '__main__':
optParser.print_help() optParser.print_help()
sys.exit(1) sys.exit(1)
config = UDTConfig(options.no_conf)
if not options.lpapi:
options.lpapi = config.get_value('USE_LPAPI', default=False,
boolean=True)
if options.lpinstance is None:
options.lpinstance = config.get_value('LPINSTANCE')
mailserver_host = config.get_value('SMTP_SERVER',
default='fiordland.ubuntu.com',
compat_keys=['UBUSMTP', 'DEBSMTP'])
mailserver_port = config.get_value('SMTP_PORT', default=25,
compat_keys=['UBUSMTP_PORT', 'DEBSMTP_PORT'])
mailserver_user = config.get_value('SMTP_USER',
compat_keys=['UBUSMTP_USER', 'DEBSMTP_USER'])
mailserver_pass = config.get_value('SMTP_PASS',
compat_keys=['UBUSMTP_PASS', 'DEBSMTP_PASS'])
# import the needed requestsync module # import the needed requestsync module
if options.lpapi: if options.lpapi:
from ubuntutools.requestsync.lp import (checkExistingReports, from ubuntutools.requestsync.lp import (checkExistingReports,
@ -84,16 +108,18 @@ if __name__ == '__main__':
# See if we have LP credentials and exit if we don't - cannot continue in this case # See if we have LP credentials and exit if we don't - cannot continue in this case
try: try:
Launchpad.login() Launchpad.login(service=options.lpinstance)
except IOError: except IOError:
sys.exit(1) sys.exit(1)
else: else:
from ubuntutools.requestsync.mail import (checkExistingReports, from ubuntutools.requestsync.mail import (checkExistingReports,
getDebianSrcPkg, getDebianSrcPkg,
getEmailAddress,
getUbuntuSrcPkg, getUbuntuSrcPkg,
mailBug, needSponsorship) mailBug, needSponsorship)
if not getEmailAddress(): if not any(x in os.environ for x in ('UBUMAIL', 'DEBEMAIL', 'EMAIL')):
print >> sys.stderr, (
'E: The environment variable UBUMAIL, DEBEMAIL or EMAIL needs '
'to be set to let this script mail the sync request.')
sys.exit(1) sys.exit(1)
newsource = options.newpkg newsource = options.newpkg
@ -146,7 +172,7 @@ if __name__ == '__main__':
print >> sys.stderr, "E: %s" % e print >> sys.stderr, "E: %s" % e
sys.exit(1) sys.exit(1)
# Stop if Ubuntu has already the version from Debian or a newer version # Stop if Ubuntu has already the version from Debian or a newer version
if (ubuntu_version >= debian_version) and options.lpapi: if (ubuntu_version >= debian_version) and options.lpapi:
# try rmadison # try rmadison
import ubuntutools.requestsync.mail import ubuntutools.requestsync.mail
@ -162,10 +188,10 @@ if __name__ == '__main__':
print >> sys.stderr, \ print >> sys.stderr, \
'E: The versions in Debian and Ubuntu are the same already (%s). Aborting.' % ubuntu_version 'E: The versions in Debian and Ubuntu are the same already (%s). Aborting.' % ubuntu_version
sys.exit(1) sys.exit(1)
if ubuntu_version > debian_version: if ubuntu_version > debian_version:
print >> sys.stderr, \ print >> sys.stderr, \
'E: The version in Ubuntu (%s) is newer than the version in Debian (%s). Aborting.' % (ubuntu_version, debian_version) 'E: The version in Ubuntu (%s) is newer than the version in Debian (%s). Aborting.' % (ubuntu_version, debian_version)
sys.exit(1) sys.exit(1)
# -s flag not specified - check if we do need sponsorship # -s flag not specified - check if we do need sponsorship
if not sponsorship: if not sponsorship:
@ -242,5 +268,8 @@ if __name__ == '__main__':
# Post sync request using LP API # Post sync request using LP API
postBug(srcpkg, subscribe, mapping[status], title, report) postBug(srcpkg, subscribe, mapping[status], title, report)
else: else:
email_from = ubu_email(export=False)[1]
# Mail sync request # Mail sync request
mailBug(srcpkg, subscribe, status, title, report, options.keyid) mailBug(srcpkg, subscribe, status, title, report, options.lpinstance,
options.keyid, email_from, mailserver_host, mailserver_port,
mailserver_user, mailserver_pass)

View File

@ -21,9 +21,10 @@ import pwd
import re import re
import shlex import shlex
import socket import socket
import StringIO
import sys import sys
from ubuntutools.logger import Logger
class UDTConfig(object): class UDTConfig(object):
"""Ubuntu Dev Tools configuration file (devscripts config file) and """Ubuntu Dev Tools configuration file (devscripts config file) and
environment variable parsing. environment variable parsing.
@ -60,10 +61,9 @@ class UDTConfig(object):
continue continue
for line in f: for line in f:
parsed = shlex.split(line, comments=True) parsed = shlex.split(line, comments=True)
if len(parsed) > 1 and not isinstance(f, StringIO.StringIO): if len(parsed) > 1:
print >> sys.stderr, ( Logger.warn('Cannot parse variable assignment in %s: %s',
"W: Cannot parse variable assignment in %s: %s" getattr(f, 'name', '<config>'), line)
% (f.name, line))
if len(parsed) >= 1 and '=' in parsed[0]: if len(parsed) >= 1 and '=' in parsed[0]:
key, value = parsed[0].split('=', 1) key, value = parsed[0].split('=', 1)
config[key] = value config[key] = value
@ -98,6 +98,14 @@ class UDTConfig(object):
value = value == 'yes' value = value == 'yes'
else: else:
continue continue
if k in compat_keys:
replacements = self.prefix + '_' + key
if key in self.defaults:
replacements += 'or UBUNTUTOOLS_' + key
Logger.warn(
'Using deprecated configuration variable %s. '
'You should use %s.',
k, replacements)
return value return value
return default return default
@ -106,7 +114,7 @@ def ubu_email(name=None, email=None, export=True):
"""Find the developer's Ubuntu e-mail address, and export it in """Find the developer's Ubuntu e-mail address, and export it in
DEBFULLNAME, DEBEMAIL if necessary (and export isn't False). DEBFULLNAME, DEBEMAIL if necessary (and export isn't False).
e-mail Priority: arguments, UBUMAIL, DEBEMAIL, user@mailname e-mail Priority: arguments, UBUMAIL, DEBEMAIL, EMAIL, user@mailname
name Priority: arguments, UBUMAIL, DEBFULLNAME, DEBEMAIL, NAME, /etc/passwd name Priority: arguments, UBUMAIL, DEBFULLNAME, DEBEMAIL, NAME, /etc/passwd
Name and email are only exported if provided as arguments or found in Name and email are only exported if provided as arguments or found in
@ -129,6 +137,7 @@ def ubu_email(name=None, email=None, export=True):
for var, target in (('UBUMAIL', 'email'), for var, target in (('UBUMAIL', 'email'),
('DEBFULLNAME', 'name'), ('DEBFULLNAME', 'name'),
('DEBEMAIL', 'email'), ('DEBEMAIL', 'email'),
('EMAIL', 'email'),
('NAME', 'name'), ('NAME', 'name'),
): ):
if name and email: if name and email:

View File

@ -24,31 +24,39 @@ class Logger(object):
script_name = os.path.basename(sys.argv[0]) script_name = os.path.basename(sys.argv[0])
verbose = False verbose = False
stdout = sys.stdout
stderr = sys.stderr
@classmethod @classmethod
def command(cls, cmd): def command(cls, cmd):
if cls.verbose: if cls.verbose:
for i in xrange(len(cmd)): for i in xrange(len(cmd)):
if cmd[i].find(" ") >= 0: if cmd[i].find(" ") >= 0:
cmd[i] = '"' + cmd[i] + '"' cmd[i] = '"' + cmd[i] + '"'
print "%s: I: %s" % (cls.script_name, " ".join(cmd)) print >> cls.stdout, "%s: I: %s" % (cls.script_name, " ".join(cmd))
@classmethod @classmethod
def debug(cls, message): def debug(cls, message, *args):
if cls.verbose: if cls.verbose:
print "%s: D: %s" % (cls.script_name, message) print >> cls.stderr, "%s: D: %s" % (cls.script_name, message % args)
@classmethod @classmethod
def error(cls, message): def error(cls, message, *args):
print >> sys.stderr, "%s: Error: %s" % (cls.script_name, message) print >> cls.stderr, "%s: Error: %s" % (cls.script_name, message % args)
@classmethod @classmethod
def info(cls, message): def warn(cls, message, *args):
print >> cls.stderr, "%s: Warning: %s" % (cls.script_name,
message % args)
@classmethod
def info(cls, message, *args):
if cls.verbose: if cls.verbose:
print "%s: I: %s" % (cls.script_name, message) print >> cls.stdout, "%s: I: %s" % (cls.script_name, message % args)
@classmethod @classmethod
def normal(cls, message): def normal(cls, message, *args):
print "%s: %s" % (cls.script_name, message) print >> cls.stdout, "%s: %s" % (cls.script_name, message % args)
@classmethod @classmethod
def set_verbosity(cls, verbose): def set_verbosity(cls, verbose):

View File

@ -52,11 +52,12 @@ __all__ = [
class Launchpad(object): class Launchpad(object):
'''Singleton for LP API access.''' '''Singleton for LP API access.'''
def login(self): def login(self, service=service):
'''Enforce a non-anonymous login.''' '''Enforce a non-anonymous login.'''
if '_Launchpad__lp' not in self.__dict__: if '_Launchpad__lp' not in self.__dict__:
try: try:
self.__lp = libsupport.get_launchpad('ubuntu-dev-tools') self.__lp = libsupport.get_launchpad('ubuntu-dev-tools',
server=service)
except IOError, error: except IOError, error:
print >> sys.stderr, 'E: %s' % error print >> sys.stderr, 'E: %s' % error
raise raise

View File

@ -49,7 +49,7 @@ def needSponsorship(name, component, release):
itself or the component itself or the component
''' '''
archive = Distribution('ubuntu').getArchive() archive = Distribution('ubuntu').getArchive()
distroseries = Distribution('ubuntu').getSeries(release) distroseries = Distribution('ubuntu').getSeries(release)
need_sponsor = not PersonTeam.me.canUploadPackage(archive, distroseries, name, component) need_sponsor = not PersonTeam.me.canUploadPackage(archive, distroseries, name, component)
if need_sponsor: if need_sponsor:

View File

@ -31,7 +31,6 @@ from ubuntutools.lp.udtexceptions import PackageNotFoundException
__all__ = [ __all__ = [
'getDebianSrcPkg', 'getDebianSrcPkg',
'getUbuntuSrcPkg', 'getUbuntuSrcPkg',
'getEmailAddress',
'needSponsorship', 'needSponsorship',
'checkExistingReports', 'checkExistingReports',
'mailBug', 'mailBug',
@ -106,18 +105,6 @@ def getDebianSrcPkg(name, release):
def getUbuntuSrcPkg(name, release): def getUbuntuSrcPkg(name, release):
return getSrcPkg('ubuntu', name, release) return getSrcPkg('ubuntu', name, release)
def getEmailAddress():
'''
Get the From email address from the UBUMAIL, DEBEMAIL or EMAIL
environment variable or give an error.
'''
myemailaddr = os.getenv('UBUMAIL') or os.getenv('DEBEMAIL') or os.getenv('EMAIL')
if not myemailaddr:
print >> sys.stderr, 'E: The environment variable UBUMAIL, ' \
'DEBEMAIL or EMAIL needs to be set to let this script ' \
'mail the sync request.'
return myemailaddr
def needSponsorship(name, component, release): def needSponsorship(name, component, release):
''' '''
Ask the user if he has upload permissions for the package or the Ask the user if he has upload permissions for the package or the
@ -143,16 +130,20 @@ def checkExistingReports(srcpkg):
'for duplicate sync requests before continuing.' % srcpkg 'for duplicate sync requests before continuing.' % srcpkg
raw_input_exit_on_ctrlc('Press [Enter] to continue or [Ctrl-C] to abort. ') raw_input_exit_on_ctrlc('Press [Enter] to continue or [Ctrl-C] to abort. ')
def mailBug(srcpkg, subscribe, status, bugtitle, bugtext, keyid = None): def mailBug(srcpkg, subscribe, status, bugtitle, bugtext, lpinstance, keyid,
myemailaddr, mailserver_host, mailserver_port, mailserver_user,
mailserver_pass):
''' '''
Submit the sync request per email. Submit the sync request per email.
''' '''
to = 'new@bugs.launchpad.net' if lpinstance == 'production':
to = 'new@bugs.launchpad.net'
# getEmailAddress() can't fail here as the main code in requestsync elif lpinstance == 'staging':
# already checks its return value to = 'new@bugs.staging.launchpad.net'
myemailaddr = getEmailAddress() else:
print >> sys.stderr, 'Error: Unknown launchpad instance:', lpinstance
sys.exit(1)
# generate mailbody # generate mailbody
if srcpkg: if srcpkg:
@ -195,10 +186,6 @@ Content-Type: text/plain; charset=UTF-8
print 'The final report is:\n%s' % mail print 'The final report is:\n%s' % mail
raw_input_exit_on_ctrlc('Press [Enter] to continue or [Ctrl-C] to abort. ') raw_input_exit_on_ctrlc('Press [Enter] to continue or [Ctrl-C] to abort. ')
# get server address and port
mailserver_host = os.getenv('UBUSMTP') or os.getenv('DEBSMTP') or 'fiordland.ubuntu.com'
mailserver_port = os.getenv('UBUSMTP_PORT') or os.getenv('DEBSMTP_PORT') or 25
# connect to the server # connect to the server
try: try:
print 'Connecting to %s:%s ...' % (mailserver_host, mailserver_port) print 'Connecting to %s:%s ...' % (mailserver_host, mailserver_port)
@ -208,9 +195,6 @@ Content-Type: text/plain; charset=UTF-8
(mailserver_host, mailserver_port, s[1], s[0]) (mailserver_host, mailserver_port, s[1], s[0])
return return
# authenticate to the server
mailserver_user = os.getenv('UBUSMTP_USER') or os.getenv('DEBSMTP_USER')
mailserver_pass = os.getenv('UBUSMTP_PASS') or os.getenv('DEBSMTP_PASS')
if mailserver_user and mailserver_pass: if mailserver_user and mailserver_pass:
try: try:
s.login(mailserver_user, mailserver_pass) s.login(mailserver_user, mailserver_pass)

View File

@ -14,16 +14,15 @@
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE. # PERFORMANCE OF THIS SOFTWARE.
from sys import version_info as _version_info import os
import sys
if _version_info < (2, 7): if sys.version_info < (2, 7):
import unittest2 as unittest import unittest2 as unittest
else: else:
import unittest import unittest
def discover(): def discover():
import os
import sys
# import __main__ triggers code re-execution # import __main__ triggers code re-execution
__main__ = sys.modules['__main__'] __main__ = sys.modules['__main__']
setupDir = os.path.abspath(os.path.dirname(__main__.__file__)) setupDir = os.path.abspath(os.path.dirname(__main__.__file__))

View File

@ -16,10 +16,12 @@
import os import os
import os.path import os.path
import sys
from StringIO import StringIO from StringIO import StringIO
import ubuntutools.config import ubuntutools.config
from ubuntutools.config import UDTConfig, ubu_email from ubuntutools.config import UDTConfig, ubu_email
from ubuntutools.logger import Logger
from ubuntutools.test import unittest from ubuntutools.test import unittest
config_files = { config_files = {
@ -42,10 +44,19 @@ def fake_open(filename, mode='r'):
class ConfigTestCase(unittest.TestCase): class ConfigTestCase(unittest.TestCase):
def setUp(self): def setUp(self):
ubuntutools.config.open = fake_open ubuntutools.config.open = fake_open
Logger.stdout = StringIO()
Logger.stderr = StringIO()
self.cleanEnvironment() self.cleanEnvironment()
def tearDown(self): def tearDown(self):
del ubuntutools.config.open del ubuntutools.config.open
self.assertEqual(Logger.stdout.getvalue(), '')
self.assertEqual(Logger.stderr.getvalue(), '')
Logger.stdout = sys.stdout
Logger.stderr = sys.stderr
self.cleanEnvironment() self.cleanEnvironment()
def cleanEnvironment(self): def cleanEnvironment(self):
@ -82,6 +93,11 @@ REPEAT=yes
'INHERIT': 'user', 'INHERIT': 'user',
'REPEAT': 'yes', 'REPEAT': 'yes',
}) })
errs = Logger.stderr.getvalue().strip()
Logger.stderr = StringIO()
self.assertEqual(len(errs.splitlines()), 1)
self.assertRegexpMatches(errs,
r'Warning: Cannot parse.*\bCOMMAND_EXECUTION=a')
def get_value(self, *args, **kwargs): def get_value(self, *args, **kwargs):
config = UDTConfig(prefix='TEST') config = UDTConfig(prefix='TEST')
@ -117,6 +133,11 @@ REPEAT=yes
config_files['user'] = 'COMPATFOOBAR=bar' config_files['user'] = 'COMPATFOOBAR=bar'
self.assertEqual(self.get_value('QUX', compat_keys=['COMPATFOOBAR']), self.assertEqual(self.get_value('QUX', compat_keys=['COMPATFOOBAR']),
'bar') 'bar')
errs = Logger.stderr.getvalue().strip()
Logger.stderr = StringIO()
self.assertEqual(len(errs.splitlines()), 1)
self.assertRegexpMatches(errs,
r'deprecated.*\bCOMPATFOOBAR\b.*\bTEST_QUX\b')
def test_boolean(self): def test_boolean(self):
config_files['user'] = "TEST_BOOLEAN=yes" config_files['user'] = "TEST_BOOLEAN=yes"