summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pbr/core.py120
-rw-r--r--pbr/packaging.py172
-rw-r--r--pbr/testr_command.py2
-rw-r--r--setup.cfg2
-rw-r--r--tools/integration.sh28
5 files changed, 187 insertions, 137 deletions
diff --git a/pbr/core.py b/pbr/core.py
index f622ad0..0f4b94a 100644
--- a/pbr/core.py
+++ b/pbr/core.py
@@ -40,6 +40,7 @@
from distutils import core
from distutils import errors
+import logging
import os
import sys
import warnings
@@ -49,7 +50,17 @@ from setuptools import dist
from pbr import util
-core.Distribution = dist._get_unpatched(core.Distribution)
+_saved_core_distribution = core.Distribution
+
+
+def _monkeypatch_distribution():
+ core.Distribution = dist._get_unpatched(core.Distribution)
+
+
+def _restore_distribution_monkeypatch():
+ core.Distribution = _saved_core_distribution
+
+
if sys.version_info[0] == 3:
string_type = str
integer_types = (int,)
@@ -76,52 +87,63 @@ def pbr(dist, attr, value):
not work well with distributions that do use a `Distribution` subclass.
"""
- if not value:
- return
- if isinstance(value, string_type):
- path = os.path.abspath(value)
- else:
- path = os.path.abspath('setup.cfg')
- if not os.path.exists(path):
- raise errors.DistutilsFileError(
- 'The setup.cfg file %s does not exist.' % path)
-
- # Converts the setup.cfg file to setup() arguments
try:
- attrs = util.cfg_to_args(path)
- except Exception:
- e = sys.exc_info()[1]
- raise errors.DistutilsSetupError(
- 'Error parsing %s: %s: %s' % (path, e.__class__.__name__, e))
-
- # Repeat some of the Distribution initialization code with the newly
- # provided attrs
- if attrs:
- # Skips 'options' and 'licence' support which are rarely used; may add
- # back in later if demanded
- for key, val in attrs.items():
- if hasattr(dist.metadata, 'set_' + key):
- getattr(dist.metadata, 'set_' + key)(val)
- elif hasattr(dist.metadata, key):
- setattr(dist.metadata, key, val)
- elif hasattr(dist, key):
- setattr(dist, key, val)
- else:
- msg = 'Unknown distribution option: %s' % repr(key)
- warnings.warn(msg)
-
- # Re-finalize the underlying Distribution
- core.Distribution.finalize_options(dist)
-
- # This bit comes out of distribute/setuptools
- if isinstance(dist.metadata.version, integer_types + (float,)):
- # Some people apparently take "version number" too literally :)
- dist.metadata.version = str(dist.metadata.version)
-
- # This bit of hackery is necessary so that the Distribution will ignore
- # normally unsupport command options (namely pre-hooks and post-hooks).
- # dist.command_options is normally a dict mapping command names to dicts of
- # their options. Now it will be a defaultdict that returns IgnoreDicts for
- # the each command's options so we can pass through the unsupported options
- ignore = ['pre_hook.*', 'post_hook.*']
- dist.command_options = util.DefaultGetDict(lambda: util.IgnoreDict(ignore))
+ _monkeypatch_distribution()
+ if not value:
+ return
+ if isinstance(value, string_type):
+ path = os.path.abspath(value)
+ else:
+ path = os.path.abspath('setup.cfg')
+ if not os.path.exists(path):
+ raise errors.DistutilsFileError(
+ 'The setup.cfg file %s does not exist.' % path)
+
+ # Converts the setup.cfg file to setup() arguments
+ try:
+ attrs = util.cfg_to_args(path)
+ except Exception:
+ e = sys.exc_info()[1]
+ # NB: This will output to the console if no explicit logging has
+ # been setup - but thats fine, this is a fatal distutils error, so
+ # being pretty isn't the #1 goal.. being diagnosable is.
+ logging.exception('Error parsing')
+ raise errors.DistutilsSetupError(
+ 'Error parsing %s: %s: %s' % (path, e.__class__.__name__, e))
+
+ # Repeat some of the Distribution initialization code with the newly
+ # provided attrs
+ if attrs:
+ # Skips 'options' and 'licence' support which are rarely used; may
+ # add back in later if demanded
+ for key, val in attrs.items():
+ if hasattr(dist.metadata, 'set_' + key):
+ getattr(dist.metadata, 'set_' + key)(val)
+ elif hasattr(dist.metadata, key):
+ setattr(dist.metadata, key, val)
+ elif hasattr(dist, key):
+ setattr(dist, key, val)
+ else:
+ msg = 'Unknown distribution option: %s' % repr(key)
+ warnings.warn(msg)
+
+ # Re-finalize the underlying Distribution
+ core.Distribution.finalize_options(dist)
+
+ # This bit comes out of distribute/setuptools
+ if isinstance(dist.metadata.version, integer_types + (float,)):
+ # Some people apparently take "version number" too literally :)
+ dist.metadata.version = str(dist.metadata.version)
+
+ # This bit of hackery is necessary so that the Distribution will ignore
+ # normally unsupport command options (namely pre-hooks and post-hooks).
+ # dist.command_options is normally a dict mapping command names to
+ # dicts of their options. Now it will be a defaultdict that returns
+ # IgnoreDicts for the each command's options so we can pass through the
+ # unsupported options
+ ignore = ['pre_hook.*', 'post_hook.*']
+ dist.command_options = util.DefaultGetDict(
+ lambda: util.IgnoreDict(ignore)
+ )
+ finally:
+ _restore_distribution_monkeypatch()
diff --git a/pbr/packaging.py b/pbr/packaging.py
index a998ceb..dc256a0 100644
--- a/pbr/packaging.py
+++ b/pbr/packaging.py
@@ -253,95 +253,101 @@ def write_git_changelog(git_dir=None, dest_dir=os.path.curdir,
"""Write a changelog based on the git changelog."""
should_skip = get_boolean_option(option_dict, 'skip_changelog',
'SKIP_WRITE_GIT_CHANGELOG')
- if not should_skip:
- new_changelog = os.path.join(dest_dir, 'ChangeLog')
- # If there's already a ChangeLog and it's not writable, just use it
- if (os.path.exists(new_changelog)
- and not os.access(new_changelog, os.W_OK)):
- return
- log.info('[pbr] Writing ChangeLog')
- if git_dir is None:
- git_dir = _get_git_directory()
- if git_dir:
- log_cmd = ['log', '--oneline', '--decorate']
- changelog = _run_git_command(log_cmd, git_dir)
- first_line = True
- with io.open(new_changelog, "w",
- encoding="utf-8") as changelog_file:
- changelog_file.write("CHANGES\n=======\n\n")
- for line in changelog.split('\n'):
- line_parts = line.split()
- if len(line_parts) < 2:
- continue
- # Tags are in a list contained in ()'s. If a commit
- # subject that is tagged happens to have ()'s in it
- # this will fail
- if line_parts[1].startswith('(') and ')' in line:
- msg = line.split(')')[1].strip()
- else:
- msg = " ".join(line_parts[1:])
-
- if "tag:" in line:
- tags = [
- tag.split(",")[0]
- for tag in line.split(")")[0].split("tag: ")[1:]]
- tag = _get_highest_tag(tags)
-
- underline = len(tag) * '-'
- if not first_line:
- changelog_file.write('\n')
- changelog_file.write(
- ("%(tag)s\n%(underline)s\n\n" %
- dict(tag=tag,
- underline=underline)))
-
- if not msg.startswith("Merge "):
- if msg.endswith("."):
- msg = msg[:-1]
- changelog_file.write(
- ("* %(msg)s\n" % dict(msg=msg)))
- first_line = False
+ if should_skip:
+ return
+
+ new_changelog = os.path.join(dest_dir, 'ChangeLog')
+ # If there's already a ChangeLog and it's not writable, just use it
+ if (os.path.exists(new_changelog)
+ and not os.access(new_changelog, os.W_OK)):
+ return
+ log.info('[pbr] Writing ChangeLog')
+ if git_dir is None:
+ git_dir = _get_git_directory()
+ if not git_dir:
+ return
+
+ log_cmd = ['log', '--oneline', '--decorate']
+ changelog = _run_git_command(log_cmd, git_dir)
+ first_line = True
+ with io.open(new_changelog, "w",
+ encoding="utf-8") as changelog_file:
+ changelog_file.write("CHANGES\n=======\n\n")
+ for line in changelog.split('\n'):
+ line_parts = line.split()
+ if len(line_parts) < 2:
+ continue
+ # Tags are in a list contained in ()'s. If a commit
+ # subject that is tagged happens to have ()'s in it
+ # this will fail
+ if line_parts[1].startswith('(') and ')' in line:
+ msg = line.split(')')[1].strip()
+ else:
+ msg = " ".join(line_parts[1:])
+
+ if "tag:" in line:
+ tags = [
+ tag.split(",")[0]
+ for tag in line.split(")")[0].split("tag: ")[1:]]
+ tag = _get_highest_tag(tags)
+
+ underline = len(tag) * '-'
+ if not first_line:
+ changelog_file.write('\n')
+ changelog_file.write(
+ ("%(tag)s\n%(underline)s\n\n" %
+ dict(tag=tag,
+ underline=underline)))
+
+ if not msg.startswith("Merge "):
+ if msg.endswith("."):
+ msg = msg[:-1]
+ changelog_file.write(
+ ("* %(msg)s\n" % dict(msg=msg)))
+ first_line = False
def generate_authors(git_dir=None, dest_dir='.', option_dict=dict()):
"""Create AUTHORS file using git commits."""
should_skip = get_boolean_option(option_dict, 'skip_authors',
'SKIP_GENERATE_AUTHORS')
- if not should_skip:
- old_authors = os.path.join(dest_dir, 'AUTHORS.in')
- new_authors = os.path.join(dest_dir, 'AUTHORS')
- # If there's already an AUTHORS file and it's not writable, just use it
- if (os.path.exists(new_authors)
- and not os.access(new_authors, os.W_OK)):
- return
- log.info('[pbr] Generating AUTHORS')
- ignore_emails = '(jenkins@review|infra@lists|jenkins@openstack)'
- if git_dir is None:
- git_dir = _get_git_directory()
- if git_dir:
- authors = []
-
- # don't include jenkins email address in AUTHORS file
- git_log_cmd = ['log', '--format=%aN <%aE>']
- authors += _run_git_command(git_log_cmd, git_dir).split('\n')
- authors = [a for a in authors if not re.search(ignore_emails, a)]
-
- # get all co-authors from commit messages
- co_authors_out = _run_git_command('log', git_dir)
- co_authors = re.findall('Co-authored-by:.+', co_authors_out,
- re.MULTILINE)
- co_authors = [signed.split(":", 1)[1].strip()
- for signed in co_authors if signed]
-
- authors += co_authors
- authors = sorted(set(authors))
-
- with open(new_authors, 'wb') as new_authors_fh:
- if os.path.exists(old_authors):
- with open(old_authors, "rb") as old_authors_fh:
- new_authors_fh.write(old_authors_fh.read())
- new_authors_fh.write(('\n'.join(authors) + '\n')
- .encode('utf-8'))
+ if should_skip:
+ return
+
+ old_authors = os.path.join(dest_dir, 'AUTHORS.in')
+ new_authors = os.path.join(dest_dir, 'AUTHORS')
+ # If there's already an AUTHORS file and it's not writable, just use it
+ if (os.path.exists(new_authors)
+ and not os.access(new_authors, os.W_OK)):
+ return
+ log.info('[pbr] Generating AUTHORS')
+ ignore_emails = '(jenkins@review|infra@lists|jenkins@openstack)'
+ if git_dir is None:
+ git_dir = _get_git_directory()
+ if git_dir:
+ authors = []
+
+ # don't include jenkins email address in AUTHORS file
+ git_log_cmd = ['log', '--format=%aN <%aE>']
+ authors += _run_git_command(git_log_cmd, git_dir).split('\n')
+ authors = [a for a in authors if not re.search(ignore_emails, a)]
+
+ # get all co-authors from commit messages
+ co_authors_out = _run_git_command('log', git_dir)
+ co_authors = re.findall('Co-authored-by:.+', co_authors_out,
+ re.MULTILINE)
+ co_authors = [signed.split(":", 1)[1].strip()
+ for signed in co_authors if signed]
+
+ authors += co_authors
+ authors = sorted(set(authors))
+
+ with open(new_authors, 'wb') as new_authors_fh:
+ if os.path.exists(old_authors):
+ with open(old_authors, "rb") as old_authors_fh:
+ new_authors_fh.write(old_authors_fh.read())
+ new_authors_fh.write(('\n'.join(authors) + '\n')
+ .encode('utf-8'))
def _find_git_files(dirname='', git_dir=None):
diff --git a/pbr/testr_command.py b/pbr/testr_command.py
index bf36b27..34b02ed 100644
--- a/pbr/testr_command.py
+++ b/pbr/testr_command.py
@@ -125,7 +125,7 @@ class Testr(cmd.Command):
# Use this as coverage package name
if self.coverage_package_name:
package = self.coverage_package_name
- options = "--source %s --parallel-mode" % self.coverage_package_name
+ options = "--source %s --parallel-mode" % package
os.environ['PYTHON'] = ("coverage run %s" % options)
logger.debug("os.environ['PYTHON'] = %r", os.environ['PYTHON'])
diff --git a/setup.cfg b/setup.cfg
index 96ac041..34b88a8 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -36,6 +36,8 @@ warnerrors = True
[entry_points]
distutils.setup_keywords =
pbr = pbr.core:pbr
+distutils.commands =
+ testr = pbr.testr_command:Testr
[build_sphinx]
all_files = 1
diff --git a/tools/integration.sh b/tools/integration.sh
index b6021f3..8c2db5e 100644
--- a/tools/integration.sh
+++ b/tools/integration.sh
@@ -43,7 +43,14 @@ BASE=${BASE:-/opt/stack}
REPODIR=${REPODIR:-$BASE/new}
# TODO: Figure out how to get this on to the box properly
-sudo apt-get install -y --force-yes libxml2-dev libxslt-dev libmysqlclient-dev libpq-dev libnspr4-dev pkg-config libsqlite3-dev libzmq-dev libffi-dev libldap2-dev libsasl2-dev
+sudo apt-get install -y --force-yes libxml2-dev libxslt-dev libmysqlclient-dev libpq-dev libnspr4-dev pkg-config libsqlite3-dev libzmq-dev libffi-dev libldap2-dev libsasl2-dev ccache
+
+# FOR numpy / pyyaml
+sudo apt-get build-dep -y --force-yes python-numpy
+sudo apt-get build-dep -y --force-yes python-yaml
+
+# And use ccache explitly
+export PATH=/usr/lib/ccache:$PATH
tmpdir=$(mktemp -d)
@@ -93,7 +100,7 @@ if [ ! -d /etc/apache2/sites-enabled/ ] ; then
exit 1
fi
-sudo rm /etc/apache2/sites-enabled/*
+sudo rm -f /etc/apache2/sites-enabled/*
cat <<EOF > $tmpdir/pypi.conf
<VirtualHost *:80>
ServerAdmin webmaster@localhost
@@ -101,8 +108,21 @@ cat <<EOF > $tmpdir/pypi.conf
Options Indexes FollowSymLinks
</VirtualHost>
EOF
-sudo mv $tmpdir/pypi.conf /etc/apache2/sites-available/pypi
-sudo chown root:root /etc/apache2/sites-available/pypi
+
+# NOTE(dhellmann): This logic is copied from apache_site_config_for
+# devstack/lib/apache with non-Ubuntu OSes left out because we don't
+# run this integration test anywhere else for now.
+apache_version=$(/usr/sbin/apache2ctl -v | awk '/Server version/ {print $3}' | cut -f2 -d/)
+if [[ "$apache_version" =~ ^2\.2\. ]]
+then
+ # Ubuntu 12.04 - Apache 2.2
+ apache_conf=/etc/apache2/sites-available/pypi
+else
+ # Ubuntu 14.04 - Apache 2.4
+ apache_conf=/etc/apache2/sites-available/pypi.conf
+fi
+sudo mv $tmpdir/pypi.conf $apache_conf
+sudo chown root:root $apache_conf
sudo a2ensite pypi
sudo service apache2 reload