* Support reading configuration variables from devscripts configuration

files. (LP: #681693)
  - Added ubuntu-dev-tools.5
* Support the combined "Name <email>" 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.
* ubuntutools/common.py: Remove https_proxy unsetting code, working around
  LP: #94130.
This commit is contained in:
Stefano Rivera 2010-12-21 01:10:57 +01:00 committed by Benjamin Drung
commit e3654e914c
15 changed files with 554 additions and 64 deletions

View File

@ -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

View File

@ -30,6 +30,7 @@ from debian.deb822 import Dsc
import launchpadlib.launchpad
import lsb_release
from ubuntutools.config import UDTConfig, ubu_email
from ubuntutools.builder import getBuilder
from ubuntutools.logger import Logger
from ubuntutools.question import YesNoQuestion
@ -99,13 +100,27 @@ def parse(args):
metavar='WORKDIR')
p.add_option('-l', '--launchpad',
dest='launchpad',
default='production',
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',
dest='no_conf',
default=False,
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', boolean=True)
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!')
@ -255,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:])

13
debian/changelog vendored
View File

@ -1,14 +1,23 @@
ubuntu-dev-tools (0.109) UNRELEASED; urgency=low
* Convert debian/copyright to DEP5, make sure all scripts are listed
(LP: #692003)
(LP: #692003)
* Drop preinst (pbuilder-dist bash_completion handling), it is not required
for any current upgrade path on Debian or Ubuntu.
* Switch to dh_python2:
- Use X-Python-Version instead of XS-Python-Version.
- Use ${python:Breaks} to specify Python version compatibility.
* Support reading configuration variables from devscripts configuration
files. (LP: #681693)
- Added ubuntu-dev-tools.5
* Support the combined "Name <email>" 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.
* ubuntutools/common.py: Remove https_proxy unsetting code, working around
LP: #94130.
-- Stefano Rivera <stefanor@ubuntu.com> Mon, 20 Dec 2010 11:32:42 +0200
-- Stefano Rivera <stefanor@ubuntu.com> Mon, 20 Dec 2010 20:54:14 +0200
ubuntu-dev-tools (0.108) experimental; urgency=low

1
debian/clean vendored Normal file
View File

@ -0,0 +1 @@
*.egg-info/*

5
debian/control vendored
View File

@ -6,7 +6,10 @@ Uploaders: Luca Falavigna <dktrkranz@debian.org>,
Benjamin Drung <bdrung@ubuntu.com>
Vcs-Bzr: lp:ubuntu-dev-tools
Vcs-Browser: https://code.launchpad.net/~ubuntu-dev/ubuntu-dev-tools/trunk
Build-Depends: debhelper (>= 7), python-all (>= 2.6.5-13~)
Build-Depends: debhelper (>= 7.0.50~),
python-all (>= 2.6.5-13~),
python-setuptools,
python-unittest2
DM-Upload-Allowed: yes
X-Python-Version: >= 2.5
Homepage: https://launchpad.net/ubuntu-dev-tools

6
debian/copyright vendored
View File

@ -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,
@ -185,16 +184,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/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,
ubuntutools/test/*,
wrap-and-sort
Copyright:
2010, Benjamin Drung <bdrung@ubuntu.com>
2010, Evan Broder <evan@ebroder.net>

8
debian/rules vendored
View File

@ -2,3 +2,11 @@
%:
dh $@ --with python2
ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
override_dh_auto_test:
set -e; \
for python in $(shell pyversions -r); do \
$$python setup.py test; \
done
endif

View File

@ -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
@ -40,20 +40,20 @@ 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, \-\-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,15 +62,19 @@ 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
.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
@ -84,12 +88,28 @@ 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 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
.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_WORKDIR ", " UBUNTUTOOLS_WORKDIR
The default value for \fB--workdir\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 +135,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
<evan@ebroder.net>

77
doc/ubuntu-dev-tools.5 Normal file
View File

@ -0,0 +1,77 @@
.\" Copyright (C) 2010, Stefano Rivera <stefanor@ubuntu.com>
.\"
.\" 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.
.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 the \fB\-\-no\-conf\fR command\-line option.
.SH ENVIRONMENT
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
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 .
.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),
.BR devscripts.conf (5)
.SH AUTHORS
This manpage was written by Stefano Rivera <stefanor@ubuntu.com>.

View File

@ -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,10 @@ 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")),
('share/man/man5', glob.glob("doc/*.5")),
],
test_suite='ubuntutools.test.discover',
)

View File

@ -144,10 +144,7 @@ class Sbuild(Builder):
return 0
def getBuilder(builder=None):
if not builder:
builder = os.environ.get('UBUNTUTOOLS_BUILDER', 'pbuilder')
def getBuilder(builder):
if builder == 'pbuilder':
return Pbuilder()
elif builder == 'pbuilder-dist':

View File

@ -1,34 +0,0 @@
#
# common.py - provides functions which are commonly used by the
# ubuntu-dev-tools package.
#
# Copyright (C) 2008 Jonathan Davies <jpds@ubuntu.com>
# Copyright (C) 2008 Siegfried-Angel Gevatter Pujals <rainct@ubuntu.com>
#
# Some of the functions are based upon code written by Martin Pitt
# <martin.pitt@ubuntu.com> and Kees Cook <kees@ubuntu.com>.
#
# ##################################################################
#
# 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.
#
# ##################################################################
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']

162
ubuntutools/config.py Normal file
View File

@ -0,0 +1,162 @@
# config.py - Common configuration file and environment variable handling for
# the ubuntu-dev-tools package.
#
# Copyright (C) 2010, Stefano Rivera <stefanor@ubuntu.com>
#
# 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
import pwd
import re
import shlex
import socket
import StringIO
import sys
class UDTConfig(object):
"""Ubuntu Dev Tools configuration file (devscripts config file) and
environment variable parsing.
"""
no_conf = False
# Package wide configuration variables.
# These are reqired to be used by at least two scripts.
defaults = {
'BUILDER': 'pbuilder',
'LPINSTANCE': 'production',
'UPDATE_BUILDER': False,
'WORKDIR': None,
}
# Populated from the configuration files:
config = {}
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('-', '_')
self.prefix = prefix
if not no_conf:
self.config = self.parse_devscripts_config()
def parse_devscripts_config(self):
"""Read the devscripts configuration files, and return the values as a
dictionary
"""
config = {}
for fn in ('/etc/devscripts.conf', '~/.devscripts'):
try:
f = open(os.path.expanduser(fn), 'r')
except IOError:
continue
for line in f:
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
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.
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.
"""
if default is None and key in self.defaults:
default = self.defaults[key]
keys = [self.prefix + '_' + key]
if key in self.defaults:
keys.append('UBUNTUTOOLS_' + key)
keys += compat_keys
for k in keys:
for store in (os.environ, self.config):
if k in store:
value = store[k]
if boolean:
if value in ('yes', 'no'):
value = value == 'yes'
else:
continue
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
DEBFULLNAME, DEBEMAIL if necessary (and export isn't False).
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 name, email.
"""
name_email_re = re.compile(r'^\s*(.+?)\s*<(.+@.+)>\s*$')
if email:
m = name_email_re.match(email)
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:
export = False
for var, target in (('UBUMAIL', 'email'),
('DEBFULLNAME', 'name'),
('DEBEMAIL', 'email'),
('NAME', 'name'),
):
if name and email:
break
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()).pw_gecos.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()).pw_name + '@' + mailname
if export:
os.environ['DEBFULLNAME'] = name
os.environ['DEBEMAIL'] = email
return name, email

View File

@ -0,0 +1,30 @@
# Test suite for ubuntutools
#
# Copyright (C) 2010, Stefano Rivera <stefanor@ubuntu.com>
#
# 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)

View File

@ -0,0 +1,192 @@
# test_config.py - Test suite for ubuntutools.config
#
# Copyright (C) 2010, Stefano Rivera <stefanor@ubuntu.com>
#
# 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"
PAIR_QUOTES="yes "a' no'
COMMAND_EXECUTION=a b
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",
'PAIR_QUOTES': 'yes a no',
'COMMAND_EXECUTION': 'a',
'INHERIT': 'user',
'REPEAT': 'yes',
})
def get_value(self, *args, **kwargs):
config = UDTConfig(prefix='TEST')
return config.get_value(*args, **kwargs)
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_general_environment_specific_config_precedence(self):
config_files['user'] = "TEST_BUILDER=bar"
os.environ['UBUNTUTOOLS_BUILDER'] = 'foo'
self.assertEqual(self.get_value('BUILDER'), 'bar')
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"
self.assertEqual(self.get_value('BOOLEAN', boolean=True), True)
config_files['user'] = "TEST_BOOLEAN=no"
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'
self.assertEquals(self.get_value('FOOBAR'), None)
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_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'
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_debemail_with_name(self):
name = 'Joe Developer'
email = 'joe@example.net'
os.environ['DEBEMAIL'] = orig = '%s <%s>' % (name, email)
self.assertEqual(ubu_email(), (name, email))
self.assertEqual(os.environ['DEBEMAIL'], orig)