From a335ef7949ae24e2b2966af7c0f69d3ae93ff036 Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Sun, 19 Dec 2010 20:47:01 +0200 Subject: [PATCH 01/37] Support reading configuration variables from devscripts configuration files. (LP: #681693) --- debian/changelog | 6 +++-- ubuntutools/common.py | 10 +++++++ ubuntutools/config.py | 61 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 ubuntutools/config.py diff --git a/debian/changelog b/debian/changelog index dae1a49..7a3b596 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,9 +1,11 @@ ubuntu-dev-tools (0.109) UNRELEASED; urgency=low * Convert debian/copyright to DEP5, make sure all scripts are listed - (LP: #692003) + (LP: #692003) + * Support reading configuration variables from devscripts configuration + files. (LP: #681693) - -- Stefano Rivera Sun, 19 Dec 2010 02:26:12 +0200 + -- Stefano Rivera Sun, 19 Dec 2010 20:41:06 +0200 ubuntu-dev-tools (0.108) experimental; urgency=low diff --git a/ubuntutools/common.py b/ubuntutools/common.py index 1be265f..490a518 100644 --- a/ubuntutools/common.py +++ b/ubuntutools/common.py @@ -32,3 +32,13 @@ import sys if os.environ.has_key('https_proxy'): print >> sys.stderr, "Ignoring https_proxy (no support in urllib/urllib2; see LP #122551)" del os.environ['https_proxy'] + + +def memoize_noargs(func): + "Simple memoization wrapper, for functions without arguments" + func.cache = None + def wrapper(): + if func.cache is None: + func.cache = func() + return func.cache + return wrapper diff --git a/ubuntutools/config.py b/ubuntutools/config.py new file mode 100644 index 0000000..391b058 --- /dev/null +++ b/ubuntutools/config.py @@ -0,0 +1,61 @@ +# config.py - Common configuration file and environment variable handling for +# the ubuntu-dev-tools package. +# +# Copyright (C) 2010 Stefano Rivera +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# See file /usr/share/common-licenses/GPL-2 for more details. +# + +import os +import os.path +import re +import sys + +from ubuntutools.common import memoize_noargs + +@memoize_noargs +def get_devscripts_config(): + """Read the devscripts configuration files, and return the values as a + dictionary + """ + config = {} + var_re = re.compile(r'^\s*([A-Z_]+?)=(.+)$') + for fn in ('/etc/devscripts.conf', '~/.devscripts'): + f = open(os.path.expanduser(fn), 'r') + for line in f: + m = var_re.match(line) + if m: + config[m.group(1)] = m.group(2) + f.close() + return config + +def get_value(key, default=None, prefix=None, compat_keys=[]): + """Retrieve a value from the environment or configuration files. + keys are prefixed with the script name + _, or prefix. + Historical variable names can be supplied via compat_keys, no prefix is + applied to them. + """ + if prefix is None: + prefix = sys.argv[0].upper().replace('-', '_') + '_' + + keys = [prefix + key, 'UBUNTUTOOLS_' + key] + compat_keys + + value = default + for store in (os.environ, get_devscripts_config()): + for k in keys: + if k in store: + value = store[k] + if value in ('yes', 'no'): + value = value == 'yes' + return value + return value From 3a9ffe412c0eb42b2d31c03e055c57b06a25bb3a Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Sun, 19 Dec 2010 20:47:37 +0200 Subject: [PATCH 02/37] Support the combined "Name " format in UBUMAIL, DEBFULLNAME, and DEBEMAIL. (LP: #665202) --- debian/changelog | 4 ++- ubuntutools/config.py | 77 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 7a3b596..cb27ceb 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,8 +4,10 @@ ubuntu-dev-tools (0.109) UNRELEASED; urgency=low (LP: #692003) * Support reading configuration variables from devscripts configuration files. (LP: #681693) + * Support the combined "Name " format in UBUMAIL, DEBFULLNAME, and + DEBEMAIL. (LP: #665202) - -- Stefano Rivera Sun, 19 Dec 2010 20:41:06 +0200 + -- Stefano Rivera Sun, 19 Dec 2010 20:47:22 +0200 ubuntu-dev-tools (0.108) experimental; urgency=low diff --git a/ubuntutools/config.py b/ubuntutools/config.py index 391b058..b6223de 100644 --- a/ubuntutools/config.py +++ b/ubuntutools/config.py @@ -18,7 +18,9 @@ import os import os.path +import pwd import re +import socket import sys from ubuntutools.common import memoize_noargs @@ -59,3 +61,78 @@ def get_value(key, default=None, prefix=None, compat_keys=[]): value = value == 'yes' return value return value + +def ubu_email(name=None, email=None, export=True): + """Find the developer's Ubuntu e-mail address, and export it in + DEBFULLNAME, DEBEMAIL if necessary (and export isn't False). + + e-mail Priority: arguments, UBUMAIL, DEBEMAIL, DEBFULLNAME, user@mailname + name Priority: arguments, UBUMAIL, DEBFULLNAME, DEBEMAIL, NAME, /etc/passwd + + Name and email are only exported if provided as arguments or found in + UBUMAIL. Otherwise, wrapped devscripts scripts can be expected to determine + the values themselves. + + Return email, name. + """ + name_email_re = re.compile(r'^\s*(.+?)\s*<(.+@.+)>\s*$') + + # First priority is to sanity-check command-line supplied values: + if name: + name = name.strip() + if email: + email = email.strip() + if name: + m = name_email_re.match(name) + if m: + name = m.group(1) + if not email: + email = m.group(2) + if email: + m = name_email_re.match(email) + if m: + if not name: + name = m.group(1) + email = m.group(2) + + if export and not name and not email and 'UBUMAIL' not in os.environ: + export = False + + for var, target in ( + ('UBUMAIL', 'name'), + ('UBUMAIL', 'email'), + ('DEBEMAIL', 'email'), + ('DEBFULLNAME', 'name'), + ('DEBEMAIL', 'name'), + ('DEBFULLNAME', 'email'), + ('NAME', 'name'), + ): + if name and email: + break + if var in os.environ and not locals()[target]: + m = name_email_re.match(os.environ[var]) + if m: + if target == 'name': + name = m.group(1) + elif target == 'email': + email = m.group(2) + elif var.endswith('MAIL') and target == 'email': + email = os.environ[var].strip() + elif var.endswith('NAME') and target == 'name': + name = os.environ[var].strip() + + if not name: + gecos_name = pwd.getpwuid(os.getuid())[4].split(',')[0].strip() + if gecos_name: + name = gecos_name + + if not email: + mailname = socket.getfqdn() + if os.path.isfile('/etc/mailname'): + mailname = open('/etc/mailname', 'r').read().strip() + email = pwd.getpwuid(os.getuid())[0] + '@' + mailname + + if export: + os.environ['DEBFULLNAME'] = name + os.environ['DEBEMAIL'] = email + return name, email From ae8648282c334832e8870fccc5177f391e2d1e1d Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Sun, 19 Dec 2010 21:19:04 +0200 Subject: [PATCH 03/37] Added ubuntu-dev-tools.5 --- debian/changelog | 3 +- doc/ubuntu-dev-tools.5 | 63 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 doc/ubuntu-dev-tools.5 diff --git a/debian/changelog b/debian/changelog index cb27ceb..951bf5d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,10 +4,11 @@ ubuntu-dev-tools (0.109) UNRELEASED; urgency=low (LP: #692003) * Support reading configuration variables from devscripts configuration files. (LP: #681693) + - Added ubuntu-dev-tools.5 * Support the combined "Name " format in UBUMAIL, DEBFULLNAME, and DEBEMAIL. (LP: #665202) - -- Stefano Rivera Sun, 19 Dec 2010 20:47:22 +0200 + -- Stefano Rivera Sun, 19 Dec 2010 21:15:02 +0200 ubuntu-dev-tools (0.108) experimental; urgency=low diff --git a/doc/ubuntu-dev-tools.5 b/doc/ubuntu-dev-tools.5 new file mode 100644 index 0000000..162a228 --- /dev/null +++ b/doc/ubuntu-dev-tools.5 @@ -0,0 +1,63 @@ +.\" Copyright (C) 2010 Stefano Rivera +.\" +.\" This program is free software; you can redistribute it and/or +.\" modify it under the terms of the GNU General Public License +.\" as published by the Free Software Foundation; either version 2 +.\" of the License, or (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" See file /usr/share/common-licenses/GPL-2 for more details. +.\" +.TH ubuntu\-dev\-tools "5" "December 19 2010" "ubuntu\-dev\-tools" +.SH NAME +ubuntu\-dev\-tools \- Configuration for the ubuntu\-dev\-tools package. + +.SH DESCRIPTION +The \fBubuntu\-dev\-tools\fR package is similar in scope to the +.BR devscripts (1) +package, providing a collection of scripts which may be of use +to Ubuntu and Debian developers or others wishing to build Debian packages. + +Some of these scripts have options which may be configured on a +system\-wide and per\-user basis. +These options are configured in +.BR devscripts.conf (5). + +All variables are described in the script's manpages. Package\-wide +variables begin with "\fIUBUNTUTOOLS\fR" and are listed below. + +Every script which reads the configuration files can be forced to ignore +them by using \fB\-\-no\-conf\fR as the \fIfirst\fR command\-line +option. + +.SH ENVIRONMENT +Several scripts use the following environment variables: + +.TP +.B UBUMAIL +Overrides \fBDEBEMAIL\fR and \fBDEBFULLNAME\fR when the target is +clearly Ubuntu. + +.TP +.BR DEBEMAIL ", " DEBFULLNAME +As in +.BR devscripts (1). + +.SH PACKAGE\-WIDE VARIABLES +The currently recognised package\-wide variables are: + +.TP +.B UBUNTUTOOLS_BUILDER +This specifies the preferred test\-builder, one of +.BR pbuilder " (default), " sbuild ", " pbuilder\-dist . + +.SH SEE ALSO +.BR devscripts (1), +.BR devscripts.conf (5) + +.SH AUTHORS +This manpage was written by Stefano Rivera . From baae70c00175948b848c9d0e1a17e6ab89f1f0b9 Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Sun, 19 Dec 2010 21:56:10 +0200 Subject: [PATCH 04/37] Support --noconf --- ubuntutools/config.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ubuntutools/config.py b/ubuntutools/config.py index b6223de..1fb62bb 100644 --- a/ubuntutools/config.py +++ b/ubuntutools/config.py @@ -31,6 +31,8 @@ def get_devscripts_config(): dictionary """ config = {} + if len(sys.argv) > 1 and sys.argv[1] in ('--no-conf', '--noconf'): + return config var_re = re.compile(r'^\s*([A-Z_]+?)=(.+)$') for fn in ('/etc/devscripts.conf', '~/.devscripts'): f = open(os.path.expanduser(fn), 'r') From 8b5cd3d04551bff41f685d3a45eb1961d8e7f3cb Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Sun, 19 Dec 2010 22:08:25 +0200 Subject: [PATCH 05/37] Actually configuration variables shouldn't come from the environment --- ubuntutools/config.py | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/ubuntutools/config.py b/ubuntutools/config.py index 1fb62bb..2713f8a 100644 --- a/ubuntutools/config.py +++ b/ubuntutools/config.py @@ -43,26 +43,31 @@ def get_devscripts_config(): f.close() return config -def get_value(key, default=None, prefix=None, compat_keys=[]): - """Retrieve a value from the environment or configuration files. +def get_value(key, default=None, prefix=None, compat_vars=[]): + """Retrieve a value from a configuration file. keys are prefixed with the script name + _, or prefix. - Historical variable names can be supplied via compat_keys, no prefix is - applied to them. + Historical *environment variable* names can be supplied via compat_keys, no + prefix is applied to them. """ if prefix is None: prefix = sys.argv[0].upper().replace('-', '_') + '_' - keys = [prefix + key, 'UBUNTUTOOLS_' + key] + compat_keys + config = get_devscripts_config() + for k in (prefix + key, 'UBUNTUTOOLS_' + key): + if k in config: + value = config[k] + if value in ('yes', 'no'): + value = value == 'yes' + return value - value = default - for store in (os.environ, get_devscripts_config()): - for k in keys: - if k in store: - value = store[k] - if value in ('yes', 'no'): - value = value == 'yes' - return value - return value + for k in compat_vars: + if k in os.environ: + value = os.environ[k] + if value in ('yes', 'no'): + value = value == 'yes' + return value + + return default def ubu_email(name=None, email=None, export=True): """Find the developer's Ubuntu e-mail address, and export it in From 1bb418e02fa775fb2431f8313b899a59e6e08c59 Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Sun, 19 Dec 2010 22:32:53 +0200 Subject: [PATCH 06/37] Support configuration in backportpackage --- backportpackage | 12 +++++++----- doc/backportpackage.1 | 20 ++++++++++++++------ doc/ubuntu-dev-tools.5 | 5 +++++ ubuntutools/builder.py | 3 ++- ubuntutools/config.py | 8 ++++++++ 5 files changed, 36 insertions(+), 12 deletions(-) diff --git a/backportpackage b/backportpackage index ea2a8ec..8cb4617 100755 --- a/backportpackage +++ b/backportpackage @@ -30,6 +30,7 @@ from debian.deb822 import Dsc import launchpadlib.launchpad import lsb_release +from ubuntutools.config import get_value, ubu_email from ubuntutools.builder import getBuilder from ubuntutools.logger import Logger from ubuntutools.question import YesNoQuestion @@ -70,12 +71,12 @@ def parse(args): help='Build the package before uploading (default: %default)') p.add_option('-B', '--builder', dest='builder', - default=None, - help='Specify the package builder (default: pbuilder)', + default=get_value('BUILDER'), + help='Specify the package builder (default: %default)', metavar='BUILDER') p.add_option('-U', '--update', dest='update', - default=False, + default=get_value('UPDATE_BUILDER'), action='store_true', help='Update the build environment before attempting to build') p.add_option('-u', '--upload', @@ -94,12 +95,12 @@ def parse(args): metavar='VERSION') p.add_option('-w', '--workdir', dest='workdir', - default=None, + default=get_value('WORKDIR'), help='Specify a working directory (default: temporary dir)', metavar='WORKDIR') p.add_option('-l', '--launchpad', dest='launchpad', - default='production', + default=get_value('LPINSTANCE'), help='Launchpad instance to connect to (default: %default)', metavar='INSTANCE') @@ -233,6 +234,7 @@ def do_backport(workdir, package, dscfile, version, suffix, release, build, bp_version = get_backport_version(version, suffix, upload, release) bp_dist = get_backport_dist(upload, release) + ubu_email() check_call(['dch', '--force-bad-version', '--preserve', diff --git a/doc/backportpackage.1 b/doc/backportpackage.1 index 0f6d065..e07cc40 100644 --- a/doc/backportpackage.1 +++ b/doc/backportpackage.1 @@ -83,13 +83,19 @@ removed once the script finishes running. .PP \fBbackportpackage\fR is only recommended for testing backports in a PPA, not uploading backports to the Ubuntu archive. -.SH ENVIRONMENT +.SH CONFIGURATION VARIABLES +The following variables can be set in the +.BR ubuntu\-dev\-tools (5) +configuration files: .TP -.B UBUNTUTOOLS_BUILDER -The default builder for Ubuntu development tools that support it -(including \fBbackportpackage\fR). Supported are \fBpbuilder\fR(8), -\fBpbuilder-dist\fR(1), and \fBsbuild\fR(1). -If unset and not provided on the command line, \fBpbuilder\fR(8) is used. +.BR BACKPORTPACKAGE_BUILDER ", " UBUNTUTOOLS_BUILDER +The default value for \fB\-\-builder\fR. +.TP +.BR BACKPORTPACKAGE_UPDATE_BUILDER ", " UBUNTUTOOLS_UPDATE_BUILDER +The default value for \fB--update\fR. +.TP +.BR BACKPORTPACKAGE_LPINSTANCE ", " UBUNTUTOOLS_LPINSTANCE +The default value for \fB--launchpad\fR. .SH EXAMPLES Test-build in your PPA a backport of znc from the current development release to your workstation's release, deleting the build products @@ -115,6 +121,8 @@ to the same PPA: .B backportpackage -d hardy -u ppa:\fIuser\fR/\fIppa\fR \\\\ .B " "https://launchpad.net/\fIsome/file.dsc\fR .fi +.SH SEE ALSO +.BR ubuntu\-dev\-tools (5) .SH AUTHOR \fBbackportpackage\fR and this manpage were written by Evan Broder diff --git a/doc/ubuntu-dev-tools.5 b/doc/ubuntu-dev-tools.5 index 162a228..5b6a1a5 100644 --- a/doc/ubuntu-dev-tools.5 +++ b/doc/ubuntu-dev-tools.5 @@ -55,6 +55,11 @@ The currently recognised package\-wide variables are: This specifies the preferred test\-builder, one of .BR pbuilder " (default), " sbuild ", " pbuilder\-dist . +.TP +.B UBUNTUTOOLS_LPINSTANCE +The launchpad instance to communicate with. e.g. \fBproduction\fR +(default) or \fBstaging\fR. + .SH SEE ALSO .BR devscripts (1), .BR devscripts.conf (5) diff --git a/ubuntutools/builder.py b/ubuntutools/builder.py index dab6fea..8b581cf 100644 --- a/ubuntutools/builder.py +++ b/ubuntutools/builder.py @@ -22,6 +22,7 @@ import os import subprocess +from ubuntutools.config import get_value from ubuntutools.logger import Logger class Builder(object): @@ -146,7 +147,7 @@ class Sbuild(Builder): def getBuilder(builder=None): if not builder: - builder = os.environ.get('UBUNTUTOOLS_BUILDER', 'pbuilder') + builder = get_value('BUILDER') if builder == 'pbuilder': return Pbuilder() diff --git a/ubuntutools/config.py b/ubuntutools/config.py index 2713f8a..4c24ace 100644 --- a/ubuntutools/config.py +++ b/ubuntutools/config.py @@ -25,6 +25,12 @@ import sys from ubuntutools.common import memoize_noargs +defaults = { + 'BUILDER': 'pbuilder', + 'UPDATE_BUILDER': False, + 'LPINSTANCE': 'production', +} + @memoize_noargs def get_devscripts_config(): """Read the devscripts configuration files, and return the values as a @@ -67,6 +73,8 @@ def get_value(key, default=None, prefix=None, compat_vars=[]): value = value == 'yes' return value + if key in defaults: + return defaults[key] return default def ubu_email(name=None, email=None, export=True): From 4e827697e848db8fb04cde1faae5b374fb0c77b6 Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Mon, 20 Dec 2010 00:27:21 +0200 Subject: [PATCH 07/37] basename() script name for prefix --- ubuntutools/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ubuntutools/config.py b/ubuntutools/config.py index 4c24ace..d9f611d 100644 --- a/ubuntutools/config.py +++ b/ubuntutools/config.py @@ -56,7 +56,7 @@ def get_value(key, default=None, prefix=None, compat_vars=[]): prefix is applied to them. """ if prefix is None: - prefix = sys.argv[0].upper().replace('-', '_') + '_' + prefix = os.path.basename(sys.argv[0]).upper().replace('-', '_') + '_' config = get_devscripts_config() for k in (prefix + key, 'UBUNTUTOOLS_' + key): From 3764bd12afc56472ac93a99f5b432d030618a76e Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Mon, 20 Dec 2010 01:07:17 +0200 Subject: [PATCH 08/37] Handle and document --noconf in backportpackage --- backportpackage | 5 +++++ doc/backportpackage.1 | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/backportpackage b/backportpackage index 8cb4617..f91ab5f 100755 --- a/backportpackage +++ b/backportpackage @@ -103,6 +103,11 @@ def parse(args): default=get_value('LPINSTANCE'), help='Launchpad instance to connect to (default: %default)', metavar='INSTANCE') + p.add_option('--no-conf', '--noconf', + dest='no_configuration', + default=False, + help="Don't read config files, must be the first option given", + action='store_true') opts, args = p.parse_args(args) if len(args) != 1: diff --git a/doc/backportpackage.1 b/doc/backportpackage.1 index e07cc40..4a44e06 100644 --- a/doc/backportpackage.1 +++ b/doc/backportpackage.1 @@ -71,6 +71,10 @@ deleted before \fIbackportpackage\fR exits. .B \-l \fIINSTANCE\fR, \-\-launchpad=\fIINSTANCE\fR Use the specified instance of Launchpad (e.g. "staging"), instead of the default of "production". +.TP +.B \-\-no\-conf\fR, \fB\-\-noconf +Do not read any configuration files. +This can only be used as the first option given on the command\-line. .SH DESCRIPTION \fBbackportpackage\fR fetches a package from one Ubuntu release or from a specified .dsc path or URL and creates a no-change backport of From d80f54dfa539632739d633031e961d293e19a1a9 Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Mon, 20 Dec 2010 01:08:07 +0200 Subject: [PATCH 09/37] Revert r863, let's use environment variables again --- doc/backportpackage.1 | 2 +- doc/ubuntu-dev-tools.5 | 6 +++++- ubuntutools/config.py | 43 +++++++++++++++++++++--------------------- 3 files changed, 27 insertions(+), 24 deletions(-) diff --git a/doc/backportpackage.1 b/doc/backportpackage.1 index 4a44e06..be4407c 100644 --- a/doc/backportpackage.1 +++ b/doc/backportpackage.1 @@ -88,7 +88,7 @@ removed once the script finishes running. \fBbackportpackage\fR is only recommended for testing backports in a PPA, not uploading backports to the Ubuntu archive. .SH CONFIGURATION VARIABLES -The following variables can be set in the +The following variables can be set in the environment or in .BR ubuntu\-dev\-tools (5) configuration files: .TP diff --git a/doc/ubuntu-dev-tools.5 b/doc/ubuntu-dev-tools.5 index 5b6a1a5..2174b45 100644 --- a/doc/ubuntu-dev-tools.5 +++ b/doc/ubuntu-dev-tools.5 @@ -35,7 +35,11 @@ them by using \fB\-\-no\-conf\fR as the \fIfirst\fR command\-line option. .SH ENVIRONMENT -Several scripts use the following environment variables: +All \fBubuntu\-dev\-tools\fR configuration variables can be set (and +overridden) by setting them in the environment (unlike +\fBdevscripts\fR). + +In addition, several scripts use the following environment variables: .TP .B UBUMAIL diff --git a/ubuntutools/config.py b/ubuntutools/config.py index d9f611d..e4c4d2a 100644 --- a/ubuntutools/config.py +++ b/ubuntutools/config.py @@ -37,8 +37,6 @@ def get_devscripts_config(): dictionary """ config = {} - if len(sys.argv) > 1 and sys.argv[1] in ('--no-conf', '--noconf'): - return config var_re = re.compile(r'^\s*([A-Z_]+?)=(.+)$') for fn in ('/etc/devscripts.conf', '~/.devscripts'): f = open(os.path.expanduser(fn), 'r') @@ -49,32 +47,33 @@ def get_devscripts_config(): f.close() return config -def get_value(key, default=None, prefix=None, compat_vars=[]): - """Retrieve a value from a configuration file. +def get_value(key, default=None, prefix=None, compat_keys=[]): + """Retrieve a value from the environment or configuration files. keys are prefixed with the script name + _, or prefix. - Historical *environment variable* names can be supplied via compat_keys, no - prefix is applied to them. + + Store Priority: Environment variables, user config file, system config file + Variable Priority: PREFIX_KEY, UBUNTUTOOLS_KEY, compat_keys + + Historical variable names can be supplied via compat_keys, no prefix is + applied to them. """ + if default is None and key in defaults: + default = defaults[key] + if len(sys.argv) > 1 and sys.argv[1] in ('--no-conf', '--noconf'): + return default + if prefix is None: prefix = os.path.basename(sys.argv[0]).upper().replace('-', '_') + '_' - config = get_devscripts_config() - for k in (prefix + key, 'UBUNTUTOOLS_' + key): - if k in config: - value = config[k] - if value in ('yes', 'no'): - value = value == 'yes' - return value + keys = [prefix + key, 'UBUNTUTOOLS_' + key] + compat_keys - for k in compat_vars: - if k in os.environ: - value = os.environ[k] - if value in ('yes', 'no'): - value = value == 'yes' - return value - - if key in defaults: - return defaults[key] + for store in (os.environ, get_devscripts_config()): + for k in keys: + if k in store: + value = store[k] + if value in ('yes', 'no'): + value = value == 'yes' + return value return default def ubu_email(name=None, email=None, export=True): From d67edd7c3c338d83388730bee7e237b6c9db4936 Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Mon, 20 Dec 2010 01:19:09 +0200 Subject: [PATCH 10/37] Relicense the code in this branch to ISC --- debian/copyright | 5 ++++- doc/ubuntu-dev-tools.5 | 23 +++++++++++------------ ubuntutools/common.py | 31 +++++++++++-------------------- ubuntutools/config.py | 23 +++++++++++------------ 4 files changed, 37 insertions(+), 45 deletions(-) diff --git a/debian/copyright b/debian/copyright index e56b1ef..ea32b6a 100644 --- a/debian/copyright +++ b/debian/copyright @@ -185,16 +185,19 @@ License: GPL-3+ Files: doc/sponsor-patch.1, doc/suspicious-source.1, + doc/ubuntu-dev-tools.5, doc/wrap-and-sort.1, sponsor-patch, suspicious-source, ubuntutools/builder.py, + ubuntutools/common.py, + ubuntutools/config.py, ubuntutools/logger.py, ubuntutools/question.py, ubuntutools/sponsor_patch/bugtask.py, ubuntutools/sponsor_patch/main.py, ubuntutools/sponsor_patch/patch.py, - wrap-and-sort, + wrap-and-sort Copyright: 2010, Benjamin Drung 2010, Evan Broder diff --git a/doc/ubuntu-dev-tools.5 b/doc/ubuntu-dev-tools.5 index 2174b45..3e709f4 100644 --- a/doc/ubuntu-dev-tools.5 +++ b/doc/ubuntu-dev-tools.5 @@ -1,17 +1,16 @@ -.\" Copyright (C) 2010 Stefano Rivera +.\" Copyright (C) 2010, Stefano Rivera .\" -.\" This program is free software; you can redistribute it and/or -.\" modify it under the terms of the GNU General Public License -.\" as published by the Free Software Foundation; either version 2 -.\" of the License, or (at your option) any later version. -.\" -.\" This program is distributed in the hope that it will be useful, -.\" but WITHOUT ANY WARRANTY; without even the implied warranty of -.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -.\" GNU General Public License for more details. -.\" -.\" See file /usr/share/common-licenses/GPL-2 for more details. +.\" Permission to use, copy, modify, and/or distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. .\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +.\" AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +.\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +.\" OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +.\" PERFORMANCE OF THIS SOFTWARE. .TH ubuntu\-dev\-tools "5" "December 19 2010" "ubuntu\-dev\-tools" .SH NAME ubuntu\-dev\-tools \- Configuration for the ubuntu\-dev\-tools package. diff --git a/ubuntutools/common.py b/ubuntutools/common.py index 490a518..571c403 100644 --- a/ubuntutools/common.py +++ b/ubuntutools/common.py @@ -1,28 +1,19 @@ -# # common.py - provides functions which are commonly used by the # ubuntu-dev-tools package. # -# Copyright (C) 2008 Jonathan Davies -# Copyright (C) 2008 Siegfried-Angel Gevatter Pujals +# Copyright (C) 2010, Stefano Rivera # -# Some of the functions are based upon code written by Martin Pitt -# and Kees Cook . +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. # -# ################################################################## -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 3 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# See file /usr/share/common-licenses/GPL for more details. -# -# ################################################################## +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. import os import sys diff --git a/ubuntutools/config.py b/ubuntutools/config.py index e4c4d2a..f5fcb0a 100644 --- a/ubuntutools/config.py +++ b/ubuntutools/config.py @@ -1,20 +1,19 @@ # config.py - Common configuration file and environment variable handling for # the ubuntu-dev-tools package. # -# Copyright (C) 2010 Stefano Rivera +# Copyright (C) 2010, Stefano Rivera # -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# See file /usr/share/common-licenses/GPL-2 for more details. +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. # +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. import os import os.path From 686b6a864921f4412c7cfffaacd9c2130843fe7d Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Mon, 20 Dec 2010 11:19:37 +0200 Subject: [PATCH 11/37] * Add the beginnings of a test suite. (LP: #690386) - Switch to setuptools, to support setup.py test. --- debian/changelog | 4 +++- debian/clean | 1 + debian/control | 6 ++++-- debian/copyright | 2 +- debian/rules | 8 ++++++++ setup.py | 6 ++++-- ubuntutools/test/__init__.py | 30 ++++++++++++++++++++++++++++ ubuntutools/test/test_common.py | 35 +++++++++++++++++++++++++++++++++ 8 files changed, 86 insertions(+), 6 deletions(-) create mode 100644 debian/clean create mode 100644 ubuntutools/test/__init__.py create mode 100644 ubuntutools/test/test_common.py diff --git a/debian/changelog b/debian/changelog index 951bf5d..d1bff39 100644 --- a/debian/changelog +++ b/debian/changelog @@ -7,8 +7,10 @@ ubuntu-dev-tools (0.109) UNRELEASED; urgency=low - Added ubuntu-dev-tools.5 * Support the combined "Name " format in UBUMAIL, DEBFULLNAME, and DEBEMAIL. (LP: #665202) + * Add the beginnings of a test suite. (LP: #690386) + - Switch to setuptools, to support setup.py test. - -- Stefano Rivera Sun, 19 Dec 2010 21:15:02 +0200 + -- Stefano Rivera Mon, 20 Dec 2010 10:58:53 +0200 ubuntu-dev-tools (0.108) experimental; urgency=low diff --git a/debian/clean b/debian/clean new file mode 100644 index 0000000..45149aa --- /dev/null +++ b/debian/clean @@ -0,0 +1 @@ +*.egg-info/* diff --git a/debian/control b/debian/control index 5f0959f..aa8b6a8 100644 --- a/debian/control +++ b/debian/control @@ -6,8 +6,10 @@ Uploaders: Luca Falavigna , Benjamin Drung Vcs-Bzr: lp:ubuntu-dev-tools Vcs-Browser: https://code.launchpad.net/~ubuntu-dev/ubuntu-dev-tools/trunk -Build-Depends: debhelper (>= 7), python (>= 2.5) -Build-Depends-Indep: python-support (>= 0.5.3) +Build-Depends: debhelper (>= 7.0.50~), python-all (>= 2.5) +Build-Depends-Indep: python-setuptools, + python-support (>= 0.5.3), + python-unittest2 DM-Upload-Allowed: yes XS-Python-Version: >= 2.5 Homepage: https://launchpad.net/ubuntu-dev-tools diff --git a/debian/copyright b/debian/copyright index ea32b6a..1c29932 100644 --- a/debian/copyright +++ b/debian/copyright @@ -150,7 +150,6 @@ Files: pull-lp-source, pull-revu-source, ubuntu-build, - ubuntutools/common.py, ubuntutools/lp/libsupport.py, ubuntutools/lp/lpapicache.py, ubuntutools/misc.py, @@ -197,6 +196,7 @@ Files: ubuntutools/sponsor_patch/bugtask.py, ubuntutools/sponsor_patch/main.py, ubuntutools/sponsor_patch/patch.py, + ubuntutools/test/*, wrap-and-sort Copyright: 2010, Benjamin Drung diff --git a/debian/rules b/debian/rules index 2d33f6a..883be80 100755 --- a/debian/rules +++ b/debian/rules @@ -2,3 +2,11 @@ %: dh $@ + +override_dh_auto_test: +ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS))) + set -e; \ + for python in $(shell pyversions -r); do \ + $$python setup.py test; \ + done +endif diff --git a/setup.py b/setup.py index 6bc464b..91920e7 100755 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ #!/usr/bin/python -from distutils.core import setup +from setuptools import setup import glob import os import re @@ -60,6 +60,8 @@ setup(name='ubuntu-dev-tools', 'ubuntutools/lp', 'ubuntutools/requestsync', 'ubuntutools/sponsor_patch', + 'ubuntutools/test', ], - data_files=[('share/man/man1', glob.glob("doc/*.1"))] + data_files=[('share/man/man1', glob.glob("doc/*.1"))], + test_suite='ubuntutools.test.discover', ) diff --git a/ubuntutools/test/__init__.py b/ubuntutools/test/__init__.py new file mode 100644 index 0000000..f47644d --- /dev/null +++ b/ubuntutools/test/__init__.py @@ -0,0 +1,30 @@ +# Test suite for ubuntutools +# +# Copyright (C) 2010, Stefano Rivera +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +from sys import version_info as _version_info + +if _version_info < (2, 7): + import unittest2 as unittest +else: + import unittest + +def discover(): + import os + import sys + # import __main__ triggers code re-execution + __main__ = sys.modules['__main__'] + setupDir = os.path.abspath(os.path.dirname(__main__.__file__)) + return unittest.defaultTestLoader.discover(setupDir) diff --git a/ubuntutools/test/test_common.py b/ubuntutools/test/test_common.py new file mode 100644 index 0000000..7e9a2fd --- /dev/null +++ b/ubuntutools/test/test_common.py @@ -0,0 +1,35 @@ +# test_common.py - Test suite for ubuntutools.common +# +# Copyright (C) 2010, Stefano Rivera +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +from ubuntutools.test import unittest +from ubuntutools.common import memoize_noargs + +class MemoizeTestCase(unittest.TestCase): + def test_memoize_noargs(self): + global run_count + run_count = 0 + + @memoize_noargs + def test_func(): + global run_count + run_count += 1 + return 42 + + self.assertEqual(run_count, 0) + self.assertEqual(test_func(), 42) + self.assertEqual(run_count, 1) + self.assertEqual(test_func(), 42) + self.assertEqual(run_count, 1) From 324c2957fd10e30742550fa0e466bd4bf24d2a03 Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Mon, 20 Dec 2010 20:56:38 +0200 Subject: [PATCH 12/37] ubuntutools/common.py: Remove https_proxy unsetting code, working around LP: #94130. --- debian/changelog | 4 +++- ubuntutools/common.py | 10 ---------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/debian/changelog b/debian/changelog index 205e400..8e754d7 100644 --- a/debian/changelog +++ b/debian/changelog @@ -14,8 +14,10 @@ ubuntu-dev-tools (0.109) UNRELEASED; urgency=low DEBEMAIL. (LP: #665202) * Add the beginnings of a test suite. (LP: #690386) - Switch to setuptools, to support setup.py test. + * ubuntutools/common.py: Remove https_proxy unsetting code, working around + LP: #94130. - -- Stefano Rivera Mon, 20 Dec 2010 10:58:53 +0200 + -- Stefano Rivera Mon, 20 Dec 2010 20:54:14 +0200 ubuntu-dev-tools (0.108) experimental; urgency=low diff --git a/ubuntutools/common.py b/ubuntutools/common.py index 571c403..34667aa 100644 --- a/ubuntutools/common.py +++ b/ubuntutools/common.py @@ -15,16 +15,6 @@ # OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -import os -import sys - -# Clear https_proxy env var as it's not supported in urllib/urllib2; see -# LP #122551 -if os.environ.has_key('https_proxy'): - print >> sys.stderr, "Ignoring https_proxy (no support in urllib/urllib2; see LP #122551)" - del os.environ['https_proxy'] - - def memoize_noargs(func): "Simple memoization wrapper, for functions without arguments" func.cache = None From 453112f342b41c6d2035dd1b76adbec0c7c4c93c Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Mon, 20 Dec 2010 21:00:14 +0200 Subject: [PATCH 13/37] Support quoted values --- ubuntutools/config.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/ubuntutools/config.py b/ubuntutools/config.py index f5fcb0a..1f983cc 100644 --- a/ubuntutools/config.py +++ b/ubuntutools/config.py @@ -36,13 +36,20 @@ def get_devscripts_config(): dictionary """ config = {} - var_re = re.compile(r'^\s*([A-Z_]+?)=(.+)$') + var_re = re.compile(r'^\s*([A-Z_]+?)=(.+?)\s*$') for fn in ('/etc/devscripts.conf', '~/.devscripts'): f = open(os.path.expanduser(fn), 'r') for line in f: m = var_re.match(line) if m: - config[m.group(1)] = m.group(2) + value = m.group(2) + # This isn't quite the same as bash's parsing, but + # mostly-compatible for configuration files that aren't broken + # like this: KEY=foo bar + if (len(value) > 2 and value[0] == value[-1] + and value[0] in ("'", '"')): + value = value[1:-1] + config[m.group(1)] = value f.close() return config From 9c62fb8723d1f8686bdae9c31ca64fa77d6b3986 Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Mon, 20 Dec 2010 21:33:48 +0200 Subject: [PATCH 14/37] bzrignore egg-info --- .bzrignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.bzrignore b/.bzrignore index 84fa991..6e47d73 100644 --- a/.bzrignore +++ b/.bzrignore @@ -6,3 +6,4 @@ /debian/ubuntu-dev-tools.debhelper.log /debian/ubuntu-dev-tools.*.debhelper /debian/ubuntu-dev-tools.substvars +ubuntu_dev_tools.egg-info From 254be7bb5d21bc1c2383bf70ea1935688a77a729 Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Mon, 20 Dec 2010 22:08:12 +0200 Subject: [PATCH 15/37] Configuration system uses a class, add test suite --- backportpackage | 29 ++++-- debian/copyright | 1 - ubuntutools/builder.py | 6 +- ubuntutools/common.py | 25 ----- ubuntutools/config.py | 109 ++++++++++---------- ubuntutools/test/test_common.py | 35 ------- ubuntutools/test/test_config.py | 169 ++++++++++++++++++++++++++++++++ 7 files changed, 246 insertions(+), 128 deletions(-) delete mode 100644 ubuntutools/common.py delete mode 100644 ubuntutools/test/test_common.py create mode 100644 ubuntutools/test/test_config.py diff --git a/backportpackage b/backportpackage index f91ab5f..ae5bb6a 100755 --- a/backportpackage +++ b/backportpackage @@ -30,7 +30,7 @@ from debian.deb822 import Dsc import launchpadlib.launchpad import lsb_release -from ubuntutools.config import get_value, ubu_email +from ubuntutools.config import UDTConfig, ubu_email from ubuntutools.builder import getBuilder from ubuntutools.logger import Logger from ubuntutools.question import YesNoQuestion @@ -71,12 +71,12 @@ def parse(args): help='Build the package before uploading (default: %default)') p.add_option('-B', '--builder', dest='builder', - default=get_value('BUILDER'), - help='Specify the package builder (default: %default)', + default=None, + help='Specify the package builder (default: pbuilder)', metavar='BUILDER') p.add_option('-U', '--update', dest='update', - default=get_value('UPDATE_BUILDER'), + default=False, action='store_true', help='Update the build environment before attempting to build') p.add_option('-u', '--upload', @@ -95,23 +95,32 @@ def parse(args): metavar='VERSION') p.add_option('-w', '--workdir', dest='workdir', - default=get_value('WORKDIR'), + default=None, help='Specify a working directory (default: temporary dir)', metavar='WORKDIR') p.add_option('-l', '--launchpad', dest='launchpad', - default=get_value('LPINSTANCE'), - help='Launchpad instance to connect to (default: %default)', + default=None, + help='Launchpad instance to connect to (default: production)', metavar='INSTANCE') p.add_option('--no-conf', '--noconf', - dest='no_configuration', + dest='no_conf', default=False, - help="Don't read config files, must be the first option given", + help="Don't read config files or environment variables", action='store_true') opts, args = p.parse_args(args) if len(args) != 1: p.error('You must specify a single source package or a .dsc URL/path.') + config = UDTConfig(opts.no_conf) + if opts.builder is None: + opts.builder = config.get_value('BUILDER') + if not opts.update: + opts.update = config.get_value('UPDATE_BUILDER') + if opts.workdir is None: + opts.workdir = config.get_value('WORKDIR') + if opts.launchpad is None: + opts.launchpad = config.get_value('LPINSTANCE') if not opts.upload and not opts.workdir: p.error('Please specify either a working dir or an upload target!') @@ -239,7 +248,6 @@ def do_backport(workdir, package, dscfile, version, suffix, release, build, bp_version = get_backport_version(version, suffix, upload, release) bp_dist = get_backport_dist(upload, release) - ubu_email() check_call(['dch', '--force-bad-version', '--preserve', @@ -262,6 +270,7 @@ def do_backport(workdir, package, dscfile, version, suffix, release, build, def main(args): os.environ['DEB_VENDOR'] = 'Ubuntu' + ubu_email() opts, (package_or_dsc,) = parse(args[1:]) diff --git a/debian/copyright b/debian/copyright index 1c29932..bcc6f85 100644 --- a/debian/copyright +++ b/debian/copyright @@ -189,7 +189,6 @@ Files: sponsor-patch, suspicious-source, ubuntutools/builder.py, - ubuntutools/common.py, ubuntutools/config.py, ubuntutools/logger.py, ubuntutools/question.py, diff --git a/ubuntutools/builder.py b/ubuntutools/builder.py index 8b581cf..c677613 100644 --- a/ubuntutools/builder.py +++ b/ubuntutools/builder.py @@ -22,7 +22,6 @@ import os import subprocess -from ubuntutools.config import get_value from ubuntutools.logger import Logger class Builder(object): @@ -145,10 +144,7 @@ class Sbuild(Builder): return 0 -def getBuilder(builder=None): - if not builder: - builder = get_value('BUILDER') - +def getBuilder(builder='pbuilder'): if builder == 'pbuilder': return Pbuilder() elif builder == 'pbuilder-dist': diff --git a/ubuntutools/common.py b/ubuntutools/common.py deleted file mode 100644 index 34667aa..0000000 --- a/ubuntutools/common.py +++ /dev/null @@ -1,25 +0,0 @@ -# common.py - provides functions which are commonly used by the -# ubuntu-dev-tools package. -# -# Copyright (C) 2010, Stefano Rivera -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -# PERFORMANCE OF THIS SOFTWARE. - -def memoize_noargs(func): - "Simple memoization wrapper, for functions without arguments" - func.cache = None - def wrapper(): - if func.cache is None: - func.cache = func() - return func.cache - return wrapper diff --git a/ubuntutools/config.py b/ubuntutools/config.py index 1f983cc..1161dff 100644 --- a/ubuntutools/config.py +++ b/ubuntutools/config.py @@ -22,65 +22,70 @@ import re import socket import sys -from ubuntutools.common import memoize_noargs +class UDTConfig(object): -defaults = { - 'BUILDER': 'pbuilder', - 'UPDATE_BUILDER': False, - 'LPINSTANCE': 'production', -} + defaults = { + 'BUILDER': 'pbuilder', + 'UPDATE_BUILDER': False, + 'LPINSTANCE': 'production', + } -@memoize_noargs -def get_devscripts_config(): - """Read the devscripts configuration files, and return the values as a - dictionary - """ - config = {} - var_re = re.compile(r'^\s*([A-Z_]+?)=(.+?)\s*$') - for fn in ('/etc/devscripts.conf', '~/.devscripts'): - f = open(os.path.expanduser(fn), 'r') - for line in f: - m = var_re.match(line) - if m: - value = m.group(2) - # This isn't quite the same as bash's parsing, but - # mostly-compatible for configuration files that aren't broken - # like this: KEY=foo bar - if (len(value) > 2 and value[0] == value[-1] - and value[0] in ("'", '"')): - value = value[1:-1] - config[m.group(1)] = value - f.close() - return config + def __init__(self, no_conf=False, prefix=None): -def get_value(key, default=None, prefix=None, compat_keys=[]): - """Retrieve a value from the environment or configuration files. - keys are prefixed with the script name + _, or prefix. + self.no_conf = no_conf + if prefix is None: + prefix = os.path.basename(sys.argv[0]).upper().replace('-', '_') + self.prefix = prefix + if not no_conf: + self.config = self.parse_devscripts_config() - Store Priority: Environment variables, user config file, system config file - Variable Priority: PREFIX_KEY, UBUNTUTOOLS_KEY, compat_keys + def parse_devscripts_config(self): + """Read the devscripts configuration files, and return the values as a + dictionary + """ + config = {} + var_re = re.compile(r'^\s*([A-Z_]+?)=(.+?)\s*$') + for fn in ('/etc/devscripts.conf', '~/.devscripts'): + f = open(os.path.expanduser(fn), 'r') + for line in f: + m = var_re.match(line) + if m: + value = m.group(2) + # This isn't quite the same as bash's parsing, but + # mostly-compatible for configuration files that aren't + # broken like this: KEY=foo bar + if (len(value) > 2 and value[0] == value[-1] + and value[0] in ("'", '"')): + value = value[1:-1] + config[m.group(1)] = value + f.close() + return config - Historical variable names can be supplied via compat_keys, no prefix is - applied to them. - """ - if default is None and key in defaults: - default = defaults[key] - if len(sys.argv) > 1 and sys.argv[1] in ('--no-conf', '--noconf'): + def get_value(self, key, default=None, compat_keys=[]): + """Retrieve a value from the environment or configuration files. + keys are prefixed with the script name, falling back to UBUNTUTOOLS for + package-wide keys. + + Store Priority: Environment variables, user conf, system conf + Variable Priority: PREFIX_KEY, UBUNTUTOOLS_KEY, compat_keys + + Historical variable names can be supplied via compat_keys, no prefix is + applied to them. + """ + if default is None and key in self.defaults: + default = self.defaults[key] + + keys = [self.prefix + '_' + key, 'UBUNTUTOOLS_' + key] + compat_keys + + for store in (os.environ, self.config): + for k in keys: + if k in store: + value = store[k] + if value in ('yes', 'no'): + value = value == 'yes' + return value return default - if prefix is None: - prefix = os.path.basename(sys.argv[0]).upper().replace('-', '_') + '_' - - keys = [prefix + key, 'UBUNTUTOOLS_' + key] + compat_keys - - for store in (os.environ, get_devscripts_config()): - for k in keys: - if k in store: - value = store[k] - if value in ('yes', 'no'): - value = value == 'yes' - return value - return default def ubu_email(name=None, email=None, export=True): """Find the developer's Ubuntu e-mail address, and export it in diff --git a/ubuntutools/test/test_common.py b/ubuntutools/test/test_common.py deleted file mode 100644 index 7e9a2fd..0000000 --- a/ubuntutools/test/test_common.py +++ /dev/null @@ -1,35 +0,0 @@ -# test_common.py - Test suite for ubuntutools.common -# -# Copyright (C) 2010, Stefano Rivera -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -# PERFORMANCE OF THIS SOFTWARE. - -from ubuntutools.test import unittest -from ubuntutools.common import memoize_noargs - -class MemoizeTestCase(unittest.TestCase): - def test_memoize_noargs(self): - global run_count - run_count = 0 - - @memoize_noargs - def test_func(): - global run_count - run_count += 1 - return 42 - - self.assertEqual(run_count, 0) - self.assertEqual(test_func(), 42) - self.assertEqual(run_count, 1) - self.assertEqual(test_func(), 42) - self.assertEqual(run_count, 1) diff --git a/ubuntutools/test/test_config.py b/ubuntutools/test/test_config.py new file mode 100644 index 0000000..0d167bc --- /dev/null +++ b/ubuntutools/test/test_config.py @@ -0,0 +1,169 @@ +# test_config.py - Test suite for ubuntutools.config +# +# Copyright (C) 2010, Stefano Rivera +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +import os +import os.path +from StringIO import StringIO + +import ubuntutools.config +from ubuntutools.config import UDTConfig, ubu_email +from ubuntutools.test import unittest + +config_files = { + 'system': '', + 'user': '', +} + +def fake_open(filename, mode='r'): + if mode != 'r': + raise IOError("Read only fake-file") + files = { + '/etc/devscripts.conf': config_files['system'], + os.path.expanduser('~/.devscripts'): config_files['user'], + } + if filename not in files: + raise IOError("No such file or directory: '%s'" % filename) + return StringIO(files[filename]) + + +class ConfigTestCase(unittest.TestCase): + def setUp(self): + ubuntutools.config.open = fake_open + self.cleanEnvironment() + + def tearDown(self): + del ubuntutools.config.open + self.cleanEnvironment() + + def cleanEnvironment(self): + config_files['system'] = '' + config_files['user'] = '' + for k in os.environ.keys(): + if k.startswith(('UBUNTUTOOLS_', 'TEST_')): + del os.environ[k] + + def test_config_parsing(self): + config_files['user'] = """#COMMENT=yes +\tTAB_INDENTED=yes + SPACE_INDENTED=yes +SPACE_SUFFIX=yes +SINGLE_QUOTE='yes no' +DOUBLE_QUOTE="yes no" +QUOTED_QUOTE="it's" +INHERIT=user +REPEAT=no +REPEAT=yes +""" + config_files['system'] = 'INHERIT=system' + self.assertEqual(UDTConfig(prefix='TEST').config, { + 'TAB_INDENTED': 'yes', + 'SPACE_INDENTED': 'yes', + 'SPACE_SUFFIX': 'yes', + 'SINGLE_QUOTE': 'yes no', + 'DOUBLE_QUOTE': 'yes no', + 'QUOTED_QUOTE': "it's", + 'INHERIT': 'user', + 'REPEAT': 'yes', + }) + + def get_value(self, key, default=None, compat_keys=[]): + config = UDTConfig(prefix='TEST') + return config.get_value(key, default=default, compat_keys=compat_keys) + + def test_defaults(self): + self.assertEqual(self.get_value('BUILDER'), 'pbuilder') + + def test_provided_default(self): + self.assertEqual(self.get_value('BUILDER', default='foo'), 'foo') + + def test_scriptname_precedence(self): + config_files['user'] = """TEST_BUILDER=foo + UBUNTUTOOLS_BUILDER=bar""" + self.assertEqual(self.get_value('BUILDER'), 'foo') + + def test_configfile_precedence(self): + config_files['system'] = "UBUNTUTOOLS_BUILDER=foo" + config_files['user'] = "UBUNTUTOOLS_BUILDER=bar" + self.assertEqual(self.get_value('BUILDER'), 'bar') + + def test_environment_precedence(self): + config_files['user'] = "UBUNTUTOOLS_BUILDER=bar" + os.environ['UBUNTUTOOLS_BUILDER'] = 'baz' + self.assertEqual(self.get_value('BUILDER'), 'baz') + + def test_any_environment_precedence(self): + config_files['user'] = "TEST_BUILDER=bar" + os.environ['UBUNTUTOOLS_BUILDER'] = 'foo' + self.assertEqual(self.get_value('BUILDER'), 'foo') + + def test_compat_environment_precedence(self): + config_files['user'] = "TEST_BUILDER=bar" + os.environ['BUILDER'] = 'baz' + self.assertEqual(self.get_value('BUILDER', compat_keys=['BUILDER']), + 'baz') + + def test_boolean(self): + config_files['user'] = "TEST_BOOLEAN=yes" + self.assertEqual(self.get_value('BOOLEAN'), True) + config_files['user'] = "TEST_BOOLEAN=no" + self.assertEqual(self.get_value('BOOLEAN'), False) + +class UbuEmailTestCase(unittest.TestCase): + def setUp(self): + self.cleanEnvironment() + + def tearDown(self): + self.cleanEnvironment() + + def cleanEnvironment(self): + for k in ('UBUMAIL', 'DEBEMAIL', 'DEBFULLNAME'): + if k in os.environ: + del os.environ[k] + + def test_pristine(self): + os.environ['DEBFULLNAME'] = name = 'Joe Developer' + os.environ['DEBEMAIL'] = email = 'joe@example.net' + self.assertEqual(ubu_email(), (name, email)) + + def test_two_hat(self): + os.environ['DEBFULLNAME'] = name = 'Joe Developer' + os.environ['DEBEMAIL'] = 'joe@debian.org' + os.environ['UBUMAIL'] = email = 'joe@ubuntu.com' + self.assertEqual(ubu_email(), (name, email)) + self.assertEqual(os.environ['DEBFULLNAME'], name) + self.assertEqual(os.environ['DEBEMAIL'], email) + + def test_two_hat_with_name(self): + os.environ['DEBFULLNAME'] = 'Joe Developer' + os.environ['DEBEMAIL'] = 'joe@debian.org' + name = 'Joe Ubuntunista' + email = 'joe@ubuntu.com' + os.environ['UBUMAIL'] = '%s <%s>' % (name, email) + self.assertEqual(ubu_email(), (name, email)) + self.assertEqual(os.environ['DEBFULLNAME'], name) + self.assertEqual(os.environ['DEBEMAIL'], email) + + def test_debfullname_with_email(self): + name = 'Joe Developer' + email = 'joe@example.net' + os.environ['DEBFULLNAME'] = '%s <%s>' % (name, email) + self.assertEqual(ubu_email(), (name, email)) + + def test_debemail_with_name(self): + name = 'Joe Developer' + email = 'joe@example.net' + os.environ['DEBEMAIL'] = '%s <%s>' % (name, email) + self.assertEqual(ubu_email(), (name, email)) From 680a4698d71551ba8d38a8a46619901d1a13fa2e Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Mon, 20 Dec 2010 22:38:36 +0200 Subject: [PATCH 16/37] Some more ubu_email test-cases --- ubuntutools/test/test_config.py | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/ubuntutools/test/test_config.py b/ubuntutools/test/test_config.py index 0d167bc..59ab198 100644 --- a/ubuntutools/test/test_config.py +++ b/ubuntutools/test/test_config.py @@ -121,6 +121,7 @@ REPEAT=yes config_files['user'] = "TEST_BOOLEAN=no" self.assertEqual(self.get_value('BOOLEAN'), False) + class UbuEmailTestCase(unittest.TestCase): def setUp(self): self.cleanEnvironment() @@ -146,6 +147,24 @@ class UbuEmailTestCase(unittest.TestCase): self.assertEqual(os.environ['DEBFULLNAME'], name) self.assertEqual(os.environ['DEBEMAIL'], email) + def test_two_hat_cmdlineoverride(self): + os.environ['DEBFULLNAME'] = 'Joe Developer' + os.environ['DEBEMAIL'] = 'joe@debian.org' + os.environ['UBUMAIL'] = 'joe@ubuntu.com' + name = 'Foo Bar' + email = 'joe@example.net' + self.assertEqual(ubu_email(name, email), (name, email)) + self.assertEqual(os.environ['DEBFULLNAME'], name) + self.assertEqual(os.environ['DEBEMAIL'], email) + + def test_two_hat_noexport(self): + os.environ['DEBFULLNAME'] = name = 'Joe Developer' + os.environ['DEBEMAIL'] = demail = 'joe@debian.org' + os.environ['UBUMAIL'] = uemail = 'joe@ubuntu.com' + self.assertEqual(ubu_email(export=False), (name, uemail)) + self.assertEqual(os.environ['DEBFULLNAME'], name) + self.assertEqual(os.environ['DEBEMAIL'], demail) + def test_two_hat_with_name(self): os.environ['DEBFULLNAME'] = 'Joe Developer' os.environ['DEBEMAIL'] = 'joe@debian.org' @@ -159,11 +178,13 @@ class UbuEmailTestCase(unittest.TestCase): def test_debfullname_with_email(self): name = 'Joe Developer' email = 'joe@example.net' - os.environ['DEBFULLNAME'] = '%s <%s>' % (name, email) + os.environ['DEBFULLNAME'] = orig = '%s <%s>' % (name, email) self.assertEqual(ubu_email(), (name, email)) + self.assertEqual(os.environ['DEBFULLNAME'], orig) def test_debemail_with_name(self): name = 'Joe Developer' email = 'joe@example.net' - os.environ['DEBEMAIL'] = '%s <%s>' % (name, email) + os.environ['DEBEMAIL'] = orig = '%s <%s>' % (name, email) self.assertEqual(ubu_email(), (name, email)) + self.assertEqual(os.environ['DEBEMAIL'], orig) From 887aa1a9ab9fe5eaac023aabf55f8779e897a21d Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Mon, 20 Dec 2010 22:38:53 +0200 Subject: [PATCH 17/37] UDTConfig docstring --- ubuntutools/config.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ubuntutools/config.py b/ubuntutools/config.py index 1161dff..ca9e310 100644 --- a/ubuntutools/config.py +++ b/ubuntutools/config.py @@ -23,7 +23,10 @@ import socket import sys class UDTConfig(object): - + """Ubuntu Dev Tools configuration file (devscripts config file) and + environment variable parsing. + """ + no_conf = False defaults = { 'BUILDER': 'pbuilder', 'UPDATE_BUILDER': False, @@ -31,7 +34,6 @@ class UDTConfig(object): } def __init__(self, no_conf=False, prefix=None): - self.no_conf = no_conf if prefix is None: prefix = os.path.basename(sys.argv[0]).upper().replace('-', '_') From 9bc2bbf64fedf325bf76ef32467f958bd5d046c5 Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Mon, 20 Dec 2010 22:45:37 +0200 Subject: [PATCH 18/37] Settle on simply --no-conf, update manpages appropriately --- backportpackage | 2 +- doc/backportpackage.1 | 6 +++--- doc/ubuntu-dev-tools.5 | 3 +-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/backportpackage b/backportpackage index ae5bb6a..b01836a 100755 --- a/backportpackage +++ b/backportpackage @@ -103,7 +103,7 @@ def parse(args): default=None, help='Launchpad instance to connect to (default: production)', metavar='INSTANCE') - p.add_option('--no-conf', '--noconf', + p.add_option('--no-conf', dest='no_conf', default=False, help="Don't read config files or environment variables", diff --git a/doc/backportpackage.1 b/doc/backportpackage.1 index be4407c..ea5353a 100644 --- a/doc/backportpackage.1 +++ b/doc/backportpackage.1 @@ -72,9 +72,9 @@ deleted before \fIbackportpackage\fR exits. Use the specified instance of Launchpad (e.g. "staging"), instead of the default of "production". .TP -.B \-\-no\-conf\fR, \fB\-\-noconf -Do not read any configuration files. -This can only be used as the first option given on the command\-line. +.B \-\-no\-conf +Do not read any configuration files, or configuration from environment +variables. .SH DESCRIPTION \fBbackportpackage\fR fetches a package from one Ubuntu release or from a specified .dsc path or URL and creates a no-change backport of diff --git a/doc/ubuntu-dev-tools.5 b/doc/ubuntu-dev-tools.5 index 3e709f4..be239e3 100644 --- a/doc/ubuntu-dev-tools.5 +++ b/doc/ubuntu-dev-tools.5 @@ -30,8 +30,7 @@ All variables are described in the script's manpages. Package\-wide variables begin with "\fIUBUNTUTOOLS\fR" and are listed below. Every script which reads the configuration files can be forced to ignore -them by using \fB\-\-no\-conf\fR as the \fIfirst\fR command\-line -option. +them by using the \fB\-\-no\-conf\fR command\-line option. .SH ENVIRONMENT All \fBubuntu\-dev\-tools\fR configuration variables can be set (and From 4adf0f3eebe346d841cc92546c9773bf35f71628 Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Mon, 20 Dec 2010 22:47:36 +0200 Subject: [PATCH 19/37] Tweak d/rules indentation --- debian/rules | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/debian/rules b/debian/rules index 7bd0636..7e1ce2c 100755 --- a/debian/rules +++ b/debian/rules @@ -6,7 +6,7 @@ override_dh_auto_test: ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS))) set -e; \ - for python in $(shell pyversions -r); do \ - $$python setup.py test; \ - done + for python in $(shell pyversions -r); do \ + $$python setup.py test; \ + done endif From 432ddc28ff4e330c3a9670bbeb0eef03ef532983 Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Mon, 20 Dec 2010 22:49:16 +0200 Subject: [PATCH 20/37] override_dh_auto_test can go in the ifeq nocheck block, it's a noop with python_distutils atm --- debian/rules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/rules b/debian/rules index 7e1ce2c..da314d6 100755 --- a/debian/rules +++ b/debian/rules @@ -3,8 +3,8 @@ %: dh $@ --with python2 -override_dh_auto_test: ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS))) +override_dh_auto_test: set -e; \ for python in $(shell pyversions -r); do \ $$python setup.py test; \ From 3d03dcdb3fcb5fc35d42788f6ecee8f944ca2adf Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Mon, 20 Dec 2010 23:36:17 +0200 Subject: [PATCH 21/37] Switch to using shlex for config file parsing --- ubuntutools/config.py | 26 ++++++++++++++------------ ubuntutools/test/test_config.py | 4 ++++ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/ubuntutools/config.py b/ubuntutools/config.py index ca9e310..a42959e 100644 --- a/ubuntutools/config.py +++ b/ubuntutools/config.py @@ -19,7 +19,9 @@ import os import os.path import pwd import re +import shlex import socket +import StringIO import sys class UDTConfig(object): @@ -46,20 +48,20 @@ class UDTConfig(object): dictionary """ config = {} - var_re = re.compile(r'^\s*([A-Z_]+?)=(.+?)\s*$') for fn in ('/etc/devscripts.conf', '~/.devscripts'): - f = open(os.path.expanduser(fn), 'r') + try: + f = open(os.path.expanduser(fn), 'r') + except IOError: + continue for line in f: - m = var_re.match(line) - if m: - value = m.group(2) - # This isn't quite the same as bash's parsing, but - # mostly-compatible for configuration files that aren't - # broken like this: KEY=foo bar - if (len(value) > 2 and value[0] == value[-1] - and value[0] in ("'", '"')): - value = value[1:-1] - config[m.group(1)] = value + parsed = shlex.split(line, comments=True) + if len(parsed) > 1 and not isinstance(f, StringIO.StringIO): + print >> sys.stderr, ( + "W: Cannot parse variable assignment in %s: %s" + % (f.name, line)) + if len(parsed) >= 1 and '=' in parsed[0]: + key, value = parsed[0].split('=', 1) + config[key] = value f.close() return config diff --git a/ubuntutools/test/test_config.py b/ubuntutools/test/test_config.py index 59ab198..b5aba8c 100644 --- a/ubuntutools/test/test_config.py +++ b/ubuntutools/test/test_config.py @@ -63,6 +63,8 @@ SPACE_SUFFIX=yes SINGLE_QUOTE='yes no' DOUBLE_QUOTE="yes no" QUOTED_QUOTE="it's" +PAIR_QUOTES="yes "a' no' +COMMAND_EXECUTION=a b INHERIT=user REPEAT=no REPEAT=yes @@ -75,6 +77,8 @@ REPEAT=yes 'SINGLE_QUOTE': 'yes no', 'DOUBLE_QUOTE': 'yes no', 'QUOTED_QUOTE': "it's", + 'PAIR_QUOTES': 'yes a no', + 'COMMAND_EXECUTION': 'a', 'INHERIT': 'user', 'REPEAT': 'yes', }) From 5716fa6d50bf5e09f5e3e3d9080675c9905a645e Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Mon, 20 Dec 2010 23:39:50 +0200 Subject: [PATCH 22/37] Describe precedence in backportpackage.1 --- doc/backportpackage.1 | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/doc/backportpackage.1 b/doc/backportpackage.1 index ea5353a..88d6090 100644 --- a/doc/backportpackage.1 +++ b/doc/backportpackage.1 @@ -87,10 +87,17 @@ removed once the script finishes running. .PP \fBbackportpackage\fR is only recommended for testing backports in a PPA, not uploading backports to the Ubuntu archive. +.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: +configuration files. +In each case, the script\-specific variable takes precedence over the +package\-wide variable. .TP .BR BACKPORTPACKAGE_BUILDER ", " UBUNTUTOOLS_BUILDER The default value for \fB\-\-builder\fR. From b038e247d51ff6a1a5384b7102501b33235e6e9a Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Mon, 20 Dec 2010 23:45:16 +0200 Subject: [PATCH 23/37] Add missing bold formatting to option list in backportpackage.1 --- doc/backportpackage.1 | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/doc/backportpackage.1 b/doc/backportpackage.1 index 88d6090..801a652 100644 --- a/doc/backportpackage.1 +++ b/doc/backportpackage.1 @@ -11,18 +11,18 @@ backportpackage \- helper to test package backports .B backportpackage \-h .SH OPTIONS .TP -.B \-d \fIDEST\fR, \-\-destination=\fIDEST\fR +.B \-d \fIDEST\fR, \fB\-\-destination\fR=\fIDEST\fR Backport the package to the specified Ubuntu release. If this option is unspecified, then \fBbackportpackage\fR defaults to the release on which it is currently running. .TP -.B \-s \fISOURCE\fR, \-\-source=\fISOURCE\fR +.B \-s \fISOURCE\fR, \fB\-\-source\fR=\fISOURCE\fR Backport the package from the specified Ubuntu release. If neither this option nor \fB\-\-version\fR are specified, then \fBbackportpackage\fR defaults to the current Ubuntu development release. .TP -.B \-S \fISUFFIX\fR, \-\-suffix=\fISUFFIX\fR +.B \-S \fISUFFIX\fR, \fB\-\-suffix\fR=\fISUFFIX\fR Add the specified suffix to the version number when backporting. \fBbackportpackage\fR will always append ~\fIDESTINATION\fR1 to the original version number, and if @@ -32,7 +32,7 @@ numbers of the form backported package is being uploaded to a PPA, then \fISUFFIX\fR defaults to \fB~ppa1\fR, otherwise the default is blank. .TP -.B \-b, \-\-build +.B \-b\fR, \fB\-\-build Build the package with the specified builder before uploading. Note for \fBpbuilder\fR(8) users: This assumes the common configuration, where the \fBDIST\fR environment is read by \fBpbuilderrc\fR(5) to @@ -43,17 +43,17 @@ Use the specified builder to build the package. Supported are \fBpbuilder\fR(8), \fBpbuilder-dist\fR(1), and \fBsbuild\fR(1). This overrides \fBUBUNTUTOOLS_BUILDER\fR. The default is \fBpbuilder\fR(8). .TP -.B \-U, \-\-update +.B \-U\fR, \fB\-\-update Update the build environment before attempting to build. .TP -.B \-u \fIUPLOAD\fR, \-\-upload=\fIUPLOAD\fR +.B \-u \fIUPLOAD\fR, \fB\-\-upload\fR=\fIUPLOAD\fR Upload to \fIUPLOAD\fR with \fBdput\fR(1) (after confirmation). .TP -.B \-y, \-\-yes +.B \-y\fR, \fB\-\-yes Do not prompt before uploading to a PPA. For everyone's safety, this option is ignored if \fIUPLOAD\fR is \fBubuntu\fR. .TP -.B \-v \fIVERSION\fR, \-\-version=\fIVERSION\fR +.B \-v \fIVERSION\fR, \fB\-\-version\fR=\fIVERSION\fR If the \fB\-\-source\fR option is specified, then \fBbackportpackage\fR verifies that the current version of \fIsource package\fR in \fISOURCE\fR is the same as \fIVERSION\fR. Otherwise, @@ -62,13 +62,13 @@ package\fR, regardless of the release in which it was published (or if that version is still current). This option is ignored if a .dsc URL or path is passed in instead of a source package name. .TP -.B \-w \fIWORKDIR\fR, \-\-workdir=\fIWORKDIR\fR +.B \-w \fIWORKDIR\fR, \fB\-\-workdir\fR=\fIWORKDIR\fR If \fIWORKDIR\fR is specified, then all files are downloaded, unpacked, built into, and otherwise manipulated in \fIWORKDIR\fR. Otherwise, a temporary directory is created, which is deleted before \fIbackportpackage\fR exits. .TP -.B \-l \fIINSTANCE\fR, \-\-launchpad=\fIINSTANCE\fR +.B \-l \fIINSTANCE\fR, \fB\-\-launchpad\fR=\fIINSTANCE\fR Use the specified instance of Launchpad (e.g. "staging"), instead of the default of "production". .TP From 2a1a48ae56b67e4d1be97c1b9f1225083851909d Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Mon, 20 Dec 2010 23:56:54 +0200 Subject: [PATCH 24/37] Tone down ubu_email magic --- ubuntutools/config.py | 38 +++++++++++---------------------- ubuntutools/test/test_config.py | 7 ------ 2 files changed, 13 insertions(+), 32 deletions(-) diff --git a/ubuntutools/config.py b/ubuntutools/config.py index a42959e..c736eb8 100644 --- a/ubuntutools/config.py +++ b/ubuntutools/config.py @@ -95,33 +95,21 @@ def ubu_email(name=None, email=None, export=True): """Find the developer's Ubuntu e-mail address, and export it in DEBFULLNAME, DEBEMAIL if necessary (and export isn't False). - e-mail Priority: arguments, UBUMAIL, DEBEMAIL, DEBFULLNAME, user@mailname + e-mail Priority: arguments, UBUMAIL, DEBEMAIL, user@mailname name Priority: arguments, UBUMAIL, DEBFULLNAME, DEBEMAIL, NAME, /etc/passwd Name and email are only exported if provided as arguments or found in UBUMAIL. Otherwise, wrapped devscripts scripts can be expected to determine the values themselves. - Return email, name. + Return name, email. """ name_email_re = re.compile(r'^\s*(.+?)\s*<(.+@.+)>\s*$') - # First priority is to sanity-check command-line supplied values: - if name: - name = name.strip() - if email: - email = email.strip() - if name: - m = name_email_re.match(name) - if m: - name = m.group(1) - if not email: - email = m.group(2) if email: m = name_email_re.match(email) - if m: - if not name: - name = m.group(1) + if m and not name: + name = m.group(1) email = m.group(2) if export and not name and not email and 'UBUMAIL' not in os.environ: @@ -130,23 +118,23 @@ def ubu_email(name=None, email=None, export=True): for var, target in ( ('UBUMAIL', 'name'), ('UBUMAIL', 'email'), - ('DEBEMAIL', 'email'), ('DEBFULLNAME', 'name'), ('DEBEMAIL', 'name'), - ('DEBFULLNAME', 'email'), + ('DEBEMAIL', 'email'), ('NAME', 'name'), ): if name and email: break if var in os.environ and not locals()[target]: - m = name_email_re.match(os.environ[var]) - if m: - if target == 'name': - name = m.group(1) + if var.endswith('MAIL'): + m = name_email_re.match(os.environ[var]) + if m: + if target == 'name': + name = m.group(1) + elif target == 'email': + email = m.group(2) elif target == 'email': - email = m.group(2) - elif var.endswith('MAIL') and target == 'email': - email = os.environ[var].strip() + email = os.environ[var].strip() elif var.endswith('NAME') and target == 'name': name = os.environ[var].strip() diff --git a/ubuntutools/test/test_config.py b/ubuntutools/test/test_config.py index b5aba8c..84df714 100644 --- a/ubuntutools/test/test_config.py +++ b/ubuntutools/test/test_config.py @@ -179,13 +179,6 @@ class UbuEmailTestCase(unittest.TestCase): self.assertEqual(os.environ['DEBFULLNAME'], name) self.assertEqual(os.environ['DEBEMAIL'], email) - def test_debfullname_with_email(self): - name = 'Joe Developer' - email = 'joe@example.net' - os.environ['DEBFULLNAME'] = orig = '%s <%s>' % (name, email) - self.assertEqual(ubu_email(), (name, email)) - self.assertEqual(os.environ['DEBFULLNAME'], orig) - def test_debemail_with_name(self): name = 'Joe Developer' email = 'joe@example.net' From 0a272cab3f58a825df3338c3e268e83c59173c5b Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Tue, 21 Dec 2010 00:13:39 +0200 Subject: [PATCH 25/37] Support the notion of non-package-wide variables --- ubuntutools/config.py | 5 ++++- ubuntutools/test/test_config.py | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ubuntutools/config.py b/ubuntutools/config.py index c736eb8..160ba2f 100644 --- a/ubuntutools/config.py +++ b/ubuntutools/config.py @@ -79,7 +79,10 @@ class UDTConfig(object): if default is None and key in self.defaults: default = self.defaults[key] - keys = [self.prefix + '_' + key, 'UBUNTUTOOLS_' + key] + compat_keys + keys = [self.prefix + '_' + key] + if key in self.defaults: + keys.append('UBUNTUTOOLS_' + key) + keys += compat_keys for store in (os.environ, self.config): for k in keys: diff --git a/ubuntutools/test/test_config.py b/ubuntutools/test/test_config.py index 84df714..8ebb4a1 100644 --- a/ubuntutools/test/test_config.py +++ b/ubuntutools/test/test_config.py @@ -125,6 +125,10 @@ REPEAT=yes config_files['user'] = "TEST_BOOLEAN=no" self.assertEqual(self.get_value('BOOLEAN'), False) + def test_nonpackagewide(self): + config_files['user'] = 'UBUNTUTOOLS_FOOBAR=a' + self.assertEquals(self.get_value('FOOBAR'), None) + class UbuEmailTestCase(unittest.TestCase): def setUp(self): From 7229c63dc2d26ce721e9ba306c9d5051e39a14ec Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Tue, 21 Dec 2010 00:18:47 +0200 Subject: [PATCH 26/37] Further magic reduction in ubu_email --- ubuntutools/config.py | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/ubuntutools/config.py b/ubuntutools/config.py index 160ba2f..40d4a43 100644 --- a/ubuntutools/config.py +++ b/ubuntutools/config.py @@ -118,28 +118,24 @@ def ubu_email(name=None, email=None, export=True): if export and not name and not email and 'UBUMAIL' not in os.environ: export = False - for var, target in ( - ('UBUMAIL', 'name'), - ('UBUMAIL', 'email'), + for var, target in (('UBUMAIL', 'email'), ('DEBFULLNAME', 'name'), - ('DEBEMAIL', 'name'), ('DEBEMAIL', 'email'), ('NAME', 'name'), ): if name and email: break - if var in os.environ and not locals()[target]: - if var.endswith('MAIL'): - m = name_email_re.match(os.environ[var]) - if m: - if target == 'name': - name = m.group(1) - elif target == 'email': - email = m.group(2) - elif target == 'email': - email = os.environ[var].strip() - elif var.endswith('NAME') and target == 'name': + if var in os.environ: + m = name_email_re.match(os.environ[var]) + if m: + if not name: + name = m.group(1) + if not email: + email = m.group(2) + elif target == 'name' and not name: name = os.environ[var].strip() + elif target == 'email' and not email: + email = os.environ[var].strip() if not name: gecos_name = pwd.getpwuid(os.getuid())[4].split(',')[0].strip() From 4336f7442ab5c01d38eb5801b1c12b4e198a6422 Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Tue, 21 Dec 2010 00:24:03 +0200 Subject: [PATCH 27/37] Use attribute accessors for pwd --- ubuntutools/config.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ubuntutools/config.py b/ubuntutools/config.py index 40d4a43..c63d87a 100644 --- a/ubuntutools/config.py +++ b/ubuntutools/config.py @@ -138,7 +138,7 @@ def ubu_email(name=None, email=None, export=True): email = os.environ[var].strip() if not name: - gecos_name = pwd.getpwuid(os.getuid())[4].split(',')[0].strip() + gecos_name = pwd.getpwuid(os.getuid()).pw_gecos.split(',')[0].strip() if gecos_name: name = gecos_name @@ -146,7 +146,7 @@ def ubu_email(name=None, email=None, export=True): mailname = socket.getfqdn() if os.path.isfile('/etc/mailname'): mailname = open('/etc/mailname', 'r').read().strip() - email = pwd.getpwuid(os.getuid())[0] + '@' + mailname + email = pwd.getpwuid(os.getuid()).pw_name + '@' + mailname if export: os.environ['DEBFULLNAME'] = name From 4f7a5232a23a35f7f476e0949b7d3db84db6ff83 Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Tue, 21 Dec 2010 00:28:31 +0200 Subject: [PATCH 28/37] Script-specific variables win over package variables no matter which store they come from --- ubuntutools/config.py | 6 +++--- ubuntutools/test/test_config.py | 13 ++++++------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/ubuntutools/config.py b/ubuntutools/config.py index c63d87a..01d8697 100644 --- a/ubuntutools/config.py +++ b/ubuntutools/config.py @@ -70,8 +70,8 @@ class UDTConfig(object): keys are prefixed with the script name, falling back to UBUNTUTOOLS for package-wide keys. - Store Priority: Environment variables, user conf, system conf Variable Priority: PREFIX_KEY, UBUNTUTOOLS_KEY, compat_keys + Store Priority: Environment variables, user conf, system conf Historical variable names can be supplied via compat_keys, no prefix is applied to them. @@ -84,8 +84,8 @@ class UDTConfig(object): keys.append('UBUNTUTOOLS_' + key) keys += compat_keys - for store in (os.environ, self.config): - for k in keys: + for k in keys: + for store in (os.environ, self.config): if k in store: value = store[k] if value in ('yes', 'no'): diff --git a/ubuntutools/test/test_config.py b/ubuntutools/test/test_config.py index 8ebb4a1..052ebd5 100644 --- a/ubuntutools/test/test_config.py +++ b/ubuntutools/test/test_config.py @@ -108,16 +108,15 @@ REPEAT=yes os.environ['UBUNTUTOOLS_BUILDER'] = 'baz' self.assertEqual(self.get_value('BUILDER'), 'baz') - def test_any_environment_precedence(self): + def test_general_environment_specific_config_precedence(self): config_files['user'] = "TEST_BUILDER=bar" os.environ['UBUNTUTOOLS_BUILDER'] = 'foo' - self.assertEqual(self.get_value('BUILDER'), 'foo') + self.assertEqual(self.get_value('BUILDER'), 'bar') - def test_compat_environment_precedence(self): - config_files['user'] = "TEST_BUILDER=bar" - os.environ['BUILDER'] = 'baz' - self.assertEqual(self.get_value('BUILDER', compat_keys=['BUILDER']), - 'baz') + def test_compat_keys(self): + config_files['user'] = 'COMPATFOOBAR=bar' + self.assertEqual(self.get_value('QUX', compat_keys=['COMPATFOOBAR']), + 'bar') def test_boolean(self): config_files['user'] = "TEST_BOOLEAN=yes" From 64e51e0617c69b9f902f6f6fe119c455244668a0 Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Tue, 21 Dec 2010 00:31:23 +0200 Subject: [PATCH 29/37] Get default builder from UDTConfig --- ubuntutools/builder.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ubuntutools/builder.py b/ubuntutools/builder.py index c677613..b8dcb40 100644 --- a/ubuntutools/builder.py +++ b/ubuntutools/builder.py @@ -22,6 +22,7 @@ import os import subprocess +from ubuntutools.config import UDTConfig from ubuntutools.logger import Logger class Builder(object): @@ -144,7 +145,10 @@ class Sbuild(Builder): return 0 -def getBuilder(builder='pbuilder'): +def getBuilder(builder=None): + if builder is None: + builder = UDTConfig.defaults['BUILDER'] + if builder == 'pbuilder': return Pbuilder() elif builder == 'pbuilder-dist': From 59464226c0202f8c271d2a12e5d2ff459edf7c1e Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Tue, 21 Dec 2010 00:35:52 +0200 Subject: [PATCH 30/37] In fact, have no default, caller is responsible --- ubuntutools/builder.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/ubuntutools/builder.py b/ubuntutools/builder.py index b8dcb40..dee4825 100644 --- a/ubuntutools/builder.py +++ b/ubuntutools/builder.py @@ -22,7 +22,6 @@ import os import subprocess -from ubuntutools.config import UDTConfig from ubuntutools.logger import Logger class Builder(object): @@ -145,10 +144,7 @@ class Sbuild(Builder): return 0 -def getBuilder(builder=None): - if builder is None: - builder = UDTConfig.defaults['BUILDER'] - +def getBuilder(builder): if builder == 'pbuilder': return Pbuilder() elif builder == 'pbuilder-dist': From 1ef4d149a7bf4b69553ca66e48adf0ca3d566f0e Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Tue, 21 Dec 2010 00:41:33 +0200 Subject: [PATCH 31/37] Install .5 manpages --- setup.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 91920e7..938857e 100755 --- a/setup.py +++ b/setup.py @@ -62,6 +62,8 @@ setup(name='ubuntu-dev-tools', 'ubuntutools/sponsor_patch', 'ubuntutools/test', ], - data_files=[('share/man/man1', glob.glob("doc/*.1"))], + data_files=[('share/man/man1', glob.glob("doc/*.1")), + ('share/man/man5', glob.glob("doc/*.5")), + ], test_suite='ubuntutools.test.discover', ) From 820b8dc0c520d422bfae97311586005011f2c1fe Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Tue, 21 Dec 2010 01:14:57 +0200 Subject: [PATCH 32/37] Default value for UDTConfig.config --- ubuntutools/config.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ubuntutools/config.py b/ubuntutools/config.py index 01d8697..0e8bcb6 100644 --- a/ubuntutools/config.py +++ b/ubuntutools/config.py @@ -34,6 +34,8 @@ class UDTConfig(object): 'UPDATE_BUILDER': False, 'LPINSTANCE': 'production', } + # Populated from the configuration files: + config = {} def __init__(self, no_conf=False, prefix=None): self.no_conf = no_conf From eeb8fd38bf2730e060609ca8e802780a9f28d1ed Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Tue, 21 Dec 2010 01:36:24 +0200 Subject: [PATCH 33/37] Document UPDATE_BUILDER --- doc/ubuntu-dev-tools.5 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/ubuntu-dev-tools.5 b/doc/ubuntu-dev-tools.5 index be239e3..7325f86 100644 --- a/doc/ubuntu-dev-tools.5 +++ b/doc/ubuntu-dev-tools.5 @@ -57,6 +57,11 @@ The currently recognised package\-wide variables are: This specifies the preferred test\-builder, one of .BR pbuilder " (default), " sbuild ", " pbuilder\-dist . +.TP +.B UBUNTUTOOLS_UPDATE_BUILDER +Boolean. Whether or not to update the test\-builder before each test +build. + .TP .B UBUNTUTOOLS_LPINSTANCE The launchpad instance to communicate with. e.g. \fBproduction\fR From 0ad5bd51746e045d055bb65ae54c4bbbffadb940 Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Tue, 21 Dec 2010 01:37:13 +0200 Subject: [PATCH 34/37] Document BACKPORTPACKAGE_WORKDIR --- doc/backportpackage.1 | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/doc/backportpackage.1 b/doc/backportpackage.1 index 801a652..7b8c42b 100644 --- a/doc/backportpackage.1 +++ b/doc/backportpackage.1 @@ -40,8 +40,8 @@ select the correct base image. .TP .B \-B \fIBUILDER\fR, \fB\-\-builder\fR=\fIBUILDER Use the specified builder to build the package. Supported are -\fBpbuilder\fR(8), \fBpbuilder-dist\fR(1), and \fBsbuild\fR(1). This overrides -\fBUBUNTUTOOLS_BUILDER\fR. The default is \fBpbuilder\fR(8). +\fBpbuilder\fR(8), \fBpbuilder-dist\fR(1), and \fBsbuild\fR(1). +The default is \fBpbuilder\fR(8). .TP .B \-U\fR, \fB\-\-update Update the build environment before attempting to build. @@ -105,6 +105,9 @@ The default value for \fB\-\-builder\fR. .BR BACKPORTPACKAGE_UPDATE_BUILDER ", " UBUNTUTOOLS_UPDATE_BUILDER The default value for \fB--update\fR. .TP +.B BACKPORTPACKAGE_WORKDIR +The default value for \fB--workdir\fR. +.TP .BR BACKPORTPACKAGE_LPINSTANCE ", " UBUNTUTOOLS_LPINSTANCE The default value for \fB--launchpad\fR. .SH EXAMPLES From 2c1e1c87270b66fbd16bdc2ec49bd88a2e0fca3f Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Tue, 21 Dec 2010 01:51:10 +0200 Subject: [PATCH 35/37] Add boolean as a get_value argument --- doc/ubuntu-dev-tools.5 | 4 ++-- ubuntutools/config.py | 9 ++++++--- ubuntutools/test/test_config.py | 10 ++++++---- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/doc/ubuntu-dev-tools.5 b/doc/ubuntu-dev-tools.5 index 7325f86..2229e8f 100644 --- a/doc/ubuntu-dev-tools.5 +++ b/doc/ubuntu-dev-tools.5 @@ -59,8 +59,8 @@ This specifies the preferred test\-builder, one of .TP .B UBUNTUTOOLS_UPDATE_BUILDER -Boolean. Whether or not to update the test\-builder before each test -build. +Whether or not to update the test\-builder before each test build. +.RB "One of " yes " or " no " (default). .TP .B UBUNTUTOOLS_LPINSTANCE diff --git a/ubuntutools/config.py b/ubuntutools/config.py index 0e8bcb6..12bdafa 100644 --- a/ubuntutools/config.py +++ b/ubuntutools/config.py @@ -67,7 +67,7 @@ class UDTConfig(object): f.close() return config - def get_value(self, key, default=None, compat_keys=[]): + def get_value(self, key, default=None, boolean=False, compat_keys=[]): """Retrieve a value from the environment or configuration files. keys are prefixed with the script name, falling back to UBUNTUTOOLS for package-wide keys. @@ -90,8 +90,11 @@ class UDTConfig(object): for store in (os.environ, self.config): if k in store: value = store[k] - if value in ('yes', 'no'): - value = value == 'yes' + if boolean: + if value in ('yes', 'no'): + value = value == 'yes' + else: + continue return value return default diff --git a/ubuntutools/test/test_config.py b/ubuntutools/test/test_config.py index 052ebd5..2d32cf2 100644 --- a/ubuntutools/test/test_config.py +++ b/ubuntutools/test/test_config.py @@ -83,9 +83,9 @@ REPEAT=yes 'REPEAT': 'yes', }) - def get_value(self, key, default=None, compat_keys=[]): + def get_value(self, *args, **kwargs): config = UDTConfig(prefix='TEST') - return config.get_value(key, default=default, compat_keys=compat_keys) + return config.get_value(*args, **kwargs) def test_defaults(self): self.assertEqual(self.get_value('BUILDER'), 'pbuilder') @@ -120,9 +120,11 @@ REPEAT=yes def test_boolean(self): config_files['user'] = "TEST_BOOLEAN=yes" - self.assertEqual(self.get_value('BOOLEAN'), True) + self.assertEqual(self.get_value('BOOLEAN', boolean=True), True) config_files['user'] = "TEST_BOOLEAN=no" - self.assertEqual(self.get_value('BOOLEAN'), False) + self.assertEqual(self.get_value('BOOLEAN', boolean=True), False) + config_files['user'] = "TEST_BOOLEAN=true" + self.assertEqual(self.get_value('BOOLEAN', boolean=True), None) def test_nonpackagewide(self): config_files['user'] = 'UBUNTUTOOLS_FOOBAR=a' From 98061bc423268449f34d8fc7b4ef0ff2bcc8801e Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Tue, 21 Dec 2010 01:56:28 +0200 Subject: [PATCH 36/37] Promote WORKDIR to UBUNTUTOOLS --- doc/backportpackage.1 | 2 +- doc/ubuntu-dev-tools.5 | 16 +++++++++------- ubuntutools/config.py | 5 ++++- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/doc/backportpackage.1 b/doc/backportpackage.1 index 7b8c42b..3911e91 100644 --- a/doc/backportpackage.1 +++ b/doc/backportpackage.1 @@ -105,7 +105,7 @@ The default value for \fB\-\-builder\fR. .BR BACKPORTPACKAGE_UPDATE_BUILDER ", " UBUNTUTOOLS_UPDATE_BUILDER The default value for \fB--update\fR. .TP -.B BACKPORTPACKAGE_WORKDIR +.BR BACKPORTPACKAGE_WORKDIR ", " UBUNTUTOOLS_WORKDIR The default value for \fB--workdir\fR. .TP .BR BACKPORTPACKAGE_LPINSTANCE ", " UBUNTUTOOLS_LPINSTANCE diff --git a/doc/ubuntu-dev-tools.5 b/doc/ubuntu-dev-tools.5 index 2229e8f..270f76f 100644 --- a/doc/ubuntu-dev-tools.5 +++ b/doc/ubuntu-dev-tools.5 @@ -51,21 +51,23 @@ As in .SH PACKAGE\-WIDE VARIABLES The currently recognised package\-wide variables are: - .TP .B UBUNTUTOOLS_BUILDER This specifies the preferred test\-builder, one of .BR pbuilder " (default), " sbuild ", " pbuilder\-dist . - -.TP -.B UBUNTUTOOLS_UPDATE_BUILDER -Whether or not to update the test\-builder before each test build. -.RB "One of " yes " or " no " (default). - .TP .B UBUNTUTOOLS_LPINSTANCE The launchpad instance to communicate with. e.g. \fBproduction\fR (default) or \fBstaging\fR. +.TP +.B UBUNTUTOOLS_UPDATE_BUILDER +Whether or not to update the test\-builder before each test build. +.RB "One of " yes " or " no " (default). +.TP +.B UBUNTUTOOLS_WORKDIR +The directory to use for preparing source packages etc. +When unset, defaults to a directory in \fI/tmp/\fR named after the +script. .SH SEE ALSO .BR devscripts (1), diff --git a/ubuntutools/config.py b/ubuntutools/config.py index 12bdafa..06a4c36 100644 --- a/ubuntutools/config.py +++ b/ubuntutools/config.py @@ -29,10 +29,13 @@ class UDTConfig(object): environment variable parsing. """ no_conf = False + # Package wide configuration variables. + # These are reqired to be used by at least two scripts. defaults = { 'BUILDER': 'pbuilder', - 'UPDATE_BUILDER': False, 'LPINSTANCE': 'production', + 'UPDATE_BUILDER': False, + 'WORKDIR': None, } # Populated from the configuration files: config = {} From c6578d1ec037669c36a370fc3693e7585cc8c28f Mon Sep 17 00:00:00 2001 From: Stefano Rivera Date: Tue, 21 Dec 2010 02:02:38 +0200 Subject: [PATCH 37/37] Specify boolean for UPDATE_BUILDER --- backportpackage | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backportpackage b/backportpackage index b01836a..d9d12af 100755 --- a/backportpackage +++ b/backportpackage @@ -116,7 +116,7 @@ def parse(args): if opts.builder is None: opts.builder = config.get_value('BUILDER') if not opts.update: - opts.update = config.get_value('UPDATE_BUILDER') + opts.update = config.get_value('UPDATE_BUILDER', boolean=True) if opts.workdir is None: opts.workdir = config.get_value('WORKDIR') if opts.launchpad is None: