Hello community,
here is the log from the commit of package python3-pbr for openSUSE:Factory checked in at 2015-05-25 11:16:33
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python3-pbr (Old)
and /work/SRC/openSUSE:Factory/.python3-pbr.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python3-pbr"
Changes:
--------
--- /work/SRC/openSUSE:Factory/python3-pbr/python3-pbr.changes 2015-05-02 21:42:18.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.python3-pbr.new/python3-pbr.changes 2015-05-25 11:16:34.000000000 +0200
@@ -1,0 +2,17 @@
+Mon May 25 05:03:12 UTC 2015 - arun@gmx.de
+
+- update to version 1.0.1:
+ * Remove self.pre_run calls in packaging.py
+ * Update hacking to 0.10.x series
+
+- changes from version 1.0.0:
+ * Teach pbr to read extras and env markers
+ * Bump integration test timeouts.
+ * Finish removing invocations of pip.
+ * Advertise support for Python3.4
+ * Issue #1451976: handle commits with non-utf8 text
+ * Parallelise integration tests.
+ * Stop re-invoking pip
+ * Allow overwriting sphinx builder from command line
+
+-------------------------------------------------------------------
Old:
----
pbr-0.11.0.tar.gz
New:
----
pbr-1.0.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python3-pbr.spec ++++++
--- /var/tmp/diff_new_pack.4wiZ7S/_old 2015-05-25 11:16:34.000000000 +0200
+++ /var/tmp/diff_new_pack.4wiZ7S/_new 2015-05-25 11:16:34.000000000 +0200
@@ -21,7 +21,7 @@
%bcond_with tests
Name: python3-pbr
-Version: 0.11.0
+Version: 1.0.1
Release: 0
Summary: Python Build Reasonableness
License: Apache-2.0
++++++ pbr-0.11.0.tar.gz -> pbr-1.0.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pbr-0.11.0/.testr.conf new/pbr-1.0.1/.testr.conf
--- old/pbr-0.11.0/.testr.conf 2015-05-01 00:32:23.000000000 +0200
+++ new/pbr-1.0.1/.testr.conf 2015-05-20 00:36:58.000000000 +0200
@@ -1,4 +1,4 @@
[DEFAULT]
-test_command=OS_STDOUT_CAPTURE=1 OS_STDERR_CAPTURE=1 OS_TEST_TIMEOUT=60 ${PYTHON:-python} -m subunit.run discover -t ./ . $LISTOPT $IDOPTION
+test_command=OS_STDOUT_CAPTURE=1 OS_STDERR_CAPTURE=1 OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-60} ${PYTHON:-python} -m subunit.run discover -t ./ . $LISTOPT $IDOPTION
test_id_option=--load-list $IDFILE
test_list_option=--list
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pbr-0.11.0/AUTHORS new/pbr-1.0.1/AUTHORS
--- old/pbr-0.11.0/AUTHORS 2015-05-01 00:33:09.000000000 +0200
+++ new/pbr-1.0.1/AUTHORS 2015-05-20 00:37:15.000000000 +0200
@@ -14,6 +14,7 @@
Clark Boylan
Claudiu Popa
Dan Prince
+Darragh Bailey
Davanum Srinivas
Dave Walker (Daviey)
David Ripton
@@ -23,6 +24,7 @@
Doug Hellmann
Doug Hellmann
Doug Hellmann
+Elena Ezhova
Eoghan Glynn
Eric Windisch
Erik M. Bray
@@ -31,6 +33,7 @@
Giampaolo Lauria
Ionuț Arțăriși
James E. Blair
+James Polley
Jason Kölker
Jay Pipes
Jeremy Stanley
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pbr-0.11.0/ChangeLog new/pbr-1.0.1/ChangeLog
--- old/pbr-0.11.0/ChangeLog 2015-05-01 00:33:09.000000000 +0200
+++ new/pbr-1.0.1/ChangeLog 2015-05-20 00:37:15.000000000 +0200
@@ -1,6 +1,22 @@
CHANGES
=======
+1.0.1
+-----
+
+* Remove self.pre_run calls in packaging.py
+* Update hacking to 0.10.x series
+
+1.0.0
+-----
+
+* Teach pbr to read extras and env markers
+* Bump integration test timeouts
+* Finish removing invocations of pip
+* Advertise support for Python3.4
+* Issue #1451976: handle commits with non-utf8 text
+* Parallelise integration tests
+
0.11.0
------
@@ -9,6 +25,7 @@
* Test pip install -e of projects
* Build all the wheels in one pass rather than many
* Improve integration.sh
+* Stop re-invoking pip
* Honour new test variable PIPVERSION
* Be safe, don't let friends use RawConfigParser
* Revert "Support platform-specific requirements files"
@@ -19,6 +36,7 @@
* Better diagnostics on test failure
* Don't avoid egg-info quite so often
* Add truncated lincense text
+* Allow overwriting sphinx builder from command line
* "packages" might list multiple directories
* Support script text override for newer develop
* Fixes Windows generated scripts headers
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pbr-0.11.0/PKG-INFO new/pbr-1.0.1/PKG-INFO
--- old/pbr-0.11.0/PKG-INFO 2015-05-01 00:33:09.000000000 +0200
+++ new/pbr-1.0.1/PKG-INFO 2015-05-20 00:37:15.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: pbr
-Version: 0.11.0
+Version: 1.0.1
Summary: Python Build Reasonableness
Home-page: https://launchpad.net/pbr
Author: OpenStack
@@ -55,3 +55,4 @@
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pbr-0.11.0/doc/source/index.rst new/pbr-1.0.1/doc/source/index.rst
--- old/pbr-0.11.0/doc/source/index.rst 2015-05-01 00:32:23.000000000 +0200
+++ new/pbr-1.0.1/doc/source/index.rst 2015-05-20 00:36:58.000000000 +0200
@@ -123,6 +123,45 @@
Only the first file found is used to install the list of packages it
contains.
+Extra requirements
+------------------
+
+Groups of optional dependencies (`"extra" requirements
+https://www.python.org/dev/peps/pep-0426/#extras-optional-dependencies`_)
+can be described in your setup.cfg, rather than needing to be added to
+setup.py. An example (which also demonstrates the use of environment
+markers) is shown below.
+
+Environment markers
+-------------------
+
+Environment markers are `conditional dependencies
+https://www.python.org/dev/peps/pep-0426/#environment-markers`_
+which can be added to the requirements (or to a group of extra
+requirements) automatically, depending on the environment the
+installer is running in. They can be added to requirements in the
+requirements file, or to extras definied in setup.cfg - but the format
+is slightly different for each.
+
+For ``requirements.txt``::
+
+ argparse; python=='2.6'
+
+will result in the package depending on ``argparse`` only if it's being
+installed into python2.6
+
+For extras specifed in setup.cfg, add an ``extras`` section. For
+instance, to create two groups of extra requirements with additional
+constraints on the environment, you can use::
+
+ [extras]
+ security =
+ aleph
+ bet :python_environment=='3.2'
+ gimel :python_environment=='2.7'
+ testing =
+ quux :python_environment=='2.7'
+
long_description
----------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pbr-0.11.0/doc/source/packagers.rst new/pbr-1.0.1/doc/source/packagers.rst
--- old/pbr-0.11.0/doc/source/packagers.rst 2015-05-01 00:32:23.000000000 +0200
+++ new/pbr-1.0.1/doc/source/packagers.rst 2015-05-20 00:36:58.000000000 +0200
@@ -42,17 +42,19 @@
Dependencies
============
-`pbr` overrides almost everything having to do with python dependency
-resolution and calls out to `pip`. In the python source package world this
-leads to a more consistent experience. However, in the distro packaging world,
-dependencies are handled by the distro. Setting `SKIP_PIP_INSTALL`:
+As of 1.0.0 `pbr` doesn't alter the dependency behaviour of `setuptools`.
-::
+Older versions would invoke `pip` internally under some circumstances and
+required the environment variable `SKIP_PIP_INSTALL` to be set to prevent
+that. Since 1.0.0 we now document that dependencies should be installed before
+installing a `pbr` using package. We don't support easy install, but neither
+do we interfere with it today. If you observe easy install being triggered when
+building a binary package, then you've probably missed one or more package
+requirements.
- SKIP_PIP_INSTALL=1
-
-will cause all logic around use of `pip` to be skipped, including the logic
-that includes pip as a dependency of `pbr` itself.
+Note: we reserve the right to disable easy install via `pbr` in future, since
+we don't want to debug or support the interactions that can occur when using
+it.
Tarballs
========
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pbr-0.11.0/pbr/builddoc.py new/pbr-1.0.1/pbr/builddoc.py
--- old/pbr-0.11.0/pbr/builddoc.py 2015-05-01 00:32:23.000000000 +0200
+++ new/pbr-1.0.1/pbr/builddoc.py 2015-05-20 00:36:58.000000000 +0200
@@ -198,6 +198,10 @@
def finalize_options(self):
# Not a new style class, super keyword does not work.
setup_command.BuildDoc.finalize_options(self)
+ # Handle builder option from command line - override cfg
+ option_dict = self.distribution.get_option_dict('build_sphinx')
+ if 'command line' in option_dict.get('builder', [[]])[0]:
+ self.builders = option_dict['builder'][1]
# Allow builders to be configurable - as a comma separated list.
if not isinstance(self.builders, list) and self.builders:
self.builders = self.builders.split(',')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pbr-0.11.0/pbr/git.py new/pbr-1.0.1/pbr/git.py
--- old/pbr-0.11.0/pbr/git.py 2015-05-01 00:32:23.000000000 +0200
+++ new/pbr-1.0.1/pbr/git.py 2015-05-20 00:36:58.000000000 +0200
@@ -50,7 +50,9 @@
"%s returned %d" % (cmd, output.returncode))
if len(out) == 0 or not out[0] or not out[0].strip():
return ''
- return out[0].strip().decode('utf-8')
+ # Since we don't control the history, and forcing users to rebase arbitrary
+ # history to fix utf8 issues is harsh, decode with replace.
+ return out[0].strip().decode('utf-8', 'replace')
def _run_git_command(cmd, git_dir, **kwargs):
@@ -96,6 +98,8 @@
if git_dir:
log.info("[pbr] In git context, generating filelist from git")
file_list = _run_git_command(['ls-files', '-z'], git_dir)
+ # Users can fix utf8 issues locally with a single commit, so we are
+ # strict here.
file_list = file_list.split(b'\x00'.decode('utf-8'))
return [f for f in file_list if f]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pbr-0.11.0/pbr/packaging.py new/pbr-1.0.1/pbr/packaging.py
--- old/pbr-0.11.0/pbr/packaging.py 2015-05-01 00:32:23.000000000 +0200
+++ new/pbr-1.0.1/pbr/packaging.py 2015-05-20 00:36:59.000000000 +0200
@@ -68,23 +68,6 @@
config[key] = '\n'.join(new_value)
-def _pip_install(links, requires, root=None, option_dict=dict()):
- if options.get_boolean_option(
- option_dict, 'skip_pip_install', 'SKIP_PIP_INSTALL'):
- return
- cmd = [sys.executable, '-m', 'pip.__init__', 'install']
- if root:
- cmd.append("--root=%s" % root)
- for link in links:
- cmd.append("-f")
- cmd.append(link)
-
- # NOTE(ociuhandu): popen on Windows does not accept unicode strings
- git._run_shell_command(
- cmd + requires,
- throw_on_error=True, buffer=False, env=dict(PIP_USE_WHEEL=b"true"))
-
-
def _any_existing(file_list):
return [f for f in file_list if os.path.exists(f)]
@@ -179,83 +162,23 @@
Force a non-egg installed in the manner of
single-version-externally-managed, which allows us to install manpages
and config files.
-
- Because non-egg installs bypass the depend processing machinery, we
- need to do our own. Because easy_install is evil, just use pip to
- process our requirements files directly, which means we don't have to
- do crazy extra processing.
-
- Bypass installation if --single-version-externally-managed is given,
- so that behavior for packagers remains the same.
"""
command_name = 'install'
def run(self):
- option_dict = self.distribution.get_option_dict('pbr')
- if (not self.single_version_externally_managed
- and self.distribution.install_requires):
- _pip_install(
- self.distribution.dependency_links,
- self.distribution.install_requires, self.root,
- option_dict=option_dict)
-
return du_install.install.run(self)
-def _newer_requires_files(egg_info_dir):
- """Check to see if any of the requires files are newer than egg-info."""
- for target, sources in (('requires.txt', get_requirements_files()),
- ('test-requires.txt', TEST_REQUIREMENTS_FILES)):
- target_path = os.path.join(egg_info_dir, target)
- for src in _any_existing(sources):
- if (not os.path.exists(target_path) or
- os.path.getmtime(target_path)
- < os.path.getmtime(src)):
- return True
- return False
-
-
-def _copy_test_requires_to(egg_info_dir):
- """Copy the requirements file to egg-info/test-requires.txt."""
- with open(os.path.join(egg_info_dir, 'test-requires.txt'), 'w') as dest:
- for source in _any_existing(TEST_REQUIREMENTS_FILES):
- dest.write(open(source, 'r').read().rstrip('\n') + '\n')
-
-
-class _PipInstallTestRequires(object):
- """Mixin class to install test-requirements.txt before running tests."""
-
- def install_test_requirements(self):
-
- links = parse_dependency_links(TEST_REQUIREMENTS_FILES)
- if self.distribution.tests_require:
- option_dict = self.distribution.get_option_dict('pbr')
- _pip_install(
- links, self.distribution.tests_require,
- option_dict=option_dict)
-
- def pre_run(self):
- self.egg_name = pkg_resources.safe_name(self.distribution.get_name())
- self.egg_info = "%s.egg-info" % pkg_resources.to_filename(
- self.egg_name)
- if (not os.path.exists(self.egg_info) or
- _newer_requires_files(self.egg_info)):
- ei_cmd = self.get_finalized_command('egg_info')
- ei_cmd.run()
- self.install_test_requirements()
- _copy_test_requires_to(self.egg_info)
-
try:
from pbr import testr_command
- class TestrTest(testr_command.Testr, _PipInstallTestRequires):
+ class TestrTest(testr_command.Testr):
"""Make setup.py test do the right thing."""
command_name = 'test'
def run(self):
- self.pre_run()
# Can't use super - base class old-style class
testr_command.Testr.run(self)
@@ -271,13 +194,12 @@
try:
from nose import commands
- class NoseTest(commands.nosetests, _PipInstallTestRequires):
+ class NoseTest(commands.nosetests):
"""Fallback test runner if testr is a no-go."""
command_name = 'test'
def run(self):
- self.pre_run()
# Can't use super - base class old-style class
commands.nosetests.run(self)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pbr-0.11.0/pbr/tests/base.py new/pbr-1.0.1/pbr/tests/base.py
--- old/pbr-0.11.0/pbr/tests/base.py 2015-05-01 00:32:23.000000000 +0200
+++ new/pbr-1.0.1/pbr/tests/base.py 2015-05-20 00:36:58.000000000 +0200
@@ -161,3 +161,15 @@
for content in streams:
print(content)
return (streams) + (p.returncode,)
+
+
+def _config_git():
+ _run_cmd(
+ ['git', 'config', '--global', 'user.email', 'example@example.com'],
+ None)
+ _run_cmd(
+ ['git', 'config', '--global', 'user.name', 'OpenStack Developer'],
+ None)
+ _run_cmd(
+ ['git', 'config', '--global', 'user.signingkey',
+ 'example@example.com'], None)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pbr-0.11.0/pbr/tests/test_integration.py new/pbr-1.0.1/pbr/tests/test_integration.py
--- old/pbr-0.11.0/pbr/tests/test_integration.py 1970-01-01 01:00:00.000000000 +0100
+++ new/pbr-1.0.1/pbr/tests/test_integration.py 2015-05-20 00:36:58.000000000 +0200
@@ -0,0 +1,165 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os.path
+import shlex
+import subprocess
+
+import fixtures
+import testscenarios
+import testtools
+from testtools import content
+import virtualenv
+
+from pbr.tests import base
+
+PIPFLAGS = shlex.split(os.environ.get('PIPFLAGS', ''))
+PIPVERSION = os.environ.get('PIPVERSION', 'pip')
+PBRVERSION = os.environ.get('PBRVERSION', 'pbr')
+REPODIR = os.environ.get('REPODIR', '')
+WHEELHOUSE = os.environ.get('WHEELHOUSE', '')
+PIP_CMD = ['-m', 'pip'] + PIPFLAGS + ['install', '-f', WHEELHOUSE]
+PROJECTS = shlex.split(os.environ.get('PROJECTS', ''))
+
+
+def all_projects():
+ if not REPODIR:
+ return
+ # Future: make this path parameterisable.
+ excludes = set(['pypi-mirror', 'jeepyb', 'tempest', 'requirements'])
+ for name in PROJECTS:
+ name = name.strip()
+ short_name = name.split('/')[-1]
+ try:
+ with open(os.path.join(
+ REPODIR, short_name, 'setup.py'), 'rt') as f:
+ if 'pbr' not in f.read():
+ continue
+ except IOError:
+ continue
+ if short_name in excludes:
+ continue
+ yield (short_name, dict(name=name, short_name=short_name))
+
+
+class CapturedSubprocess(fixtures.Fixture):
+ """Run a process and capture its output.
+
+ :attr stdout: The output (a string).
+ :attr stderr: The standard error (a string).
+ :attr returncode: The return code of the process.
+
+ Note that stdout and stderr are decoded from the bytestrings subprocess
+ returns using error=replace.
+ """
+
+ def __init__(self, label, *args, **kwargs):
+ """Create a CapturedSubprocess.
+
+ :param label: A label for the subprocess in the test log. E.g. 'foo'.
+ :param *args: The *args to pass to Popen.
+ :param **kwargs: The **kwargs to pass to Popen.
+ """
+ super(CapturedSubprocess, self).__init__()
+ self.label = label
+ self.args = args
+ self.kwargs = kwargs
+ self.kwargs['stderr'] = subprocess.PIPE
+ self.kwargs['stdin'] = subprocess.PIPE
+ self.kwargs['stdout'] = subprocess.PIPE
+
+ def setUp(self):
+ super(CapturedSubprocess, self).setUp()
+ proc = subprocess.Popen(*self.args, **self.kwargs)
+ out, err = proc.communicate()
+ self.out = out.decode('utf-8', 'replace')
+ self.err = err.decode('utf-8', 'replace')
+ self.addDetail(self.label + '-stdout', content.text_content(self.out))
+ self.addDetail(self.label + '-stderr', content.text_content(self.err))
+ self.returncode = proc.returncode
+ if proc.returncode:
+ raise AssertionError('Failed process %s' % proc.returncode)
+ self.addCleanup(delattr, self, 'out')
+ self.addCleanup(delattr, self, 'err')
+ self.addCleanup(delattr, self, 'returncode')
+
+
+class TestIntegration(base.BaseTestCase):
+
+ scenarios = list(all_projects())
+
+ def setUp(self):
+ # Integration tests need a higher default - big repos can be slow to
+ # clone, particularly under guest load.
+ os.environ['OS_TEST_TIMEOUT'] = os.environ.get('OS_TEST_TIMEOUT', 600)
+ super(TestIntegration, self).setUp()
+ base._config_git()
+
+ def venv(self, reason):
+ path = self.useFixture(fixtures.TempDir()).path
+ virtualenv.create_environment(path, clear=True)
+ python = os.path.join(path, 'bin', 'python')
+ self.useFixture(CapturedSubprocess(
+ 'mkvenv-' + reason, [python] + PIP_CMD + [
+ '-U', PIPVERSION, 'wheel', PBRVERSION]))
+ return path, python
+
+ @testtools.skipUnless(
+ os.environ.get('PBR_INTEGRATION', None) == '1',
+ 'integration tests not enabled')
+ def test_integration(self):
+ # Test that we can:
+ # - run sdist from the repo in a venv
+ # - install the resulting tarball in a new venv
+ # - pip install the repo
+ # - pip install -e the repo
+ # We don't break these into separate tests because we'd need separate
+ # source dirs to isolate from side effects of running pip, and the
+ # overheads of setup would start to beat the benefits of parallelism.
+ self.useFixture(CapturedSubprocess(
+ 'sync-req',
+ ['python', 'update.py', os.path.join(REPODIR, self.short_name)],
+ cwd=os.path.join(REPODIR, 'requirements')))
+ self.useFixture(CapturedSubprocess(
+ 'commit-requirements',
+ 'git diff --quiet || git commit -amrequirements',
+ cwd=os.path.join(REPODIR, self.short_name), shell=True))
+ path = os.path.join(
+ self.useFixture(fixtures.TempDir()).path, 'project')
+ self.useFixture(CapturedSubprocess(
+ 'clone',
+ ['git', 'clone', os.path.join(REPODIR, self.short_name), path]))
+ _, python = self.venv('sdist')
+ self.useFixture(CapturedSubprocess(
+ 'sdist', [python, 'setup.py', 'sdist'], cwd=path))
+ _, python = self.venv('tarball')
+ filename = os.path.join(
+ path, 'dist', os.listdir(os.path.join(path, 'dist'))[0])
+ self.useFixture(CapturedSubprocess(
+ 'tarball', [python] + PIP_CMD + [filename]))
+ root, python = self.venv('install-git')
+ self.useFixture(CapturedSubprocess(
+ 'install-git', [python] + PIP_CMD + ['git+file://' + path]))
+ if self.short_name == 'nova':
+ found = False
+ for _, _, filenames in os.walk(root):
+ if 'migrate.cfg' in filenames:
+ found = True
+ self.assertTrue(found)
+ _, python = self.venv('install-e')
+ self.useFixture(CapturedSubprocess(
+ 'install-e', [python] + PIP_CMD + ['-e', path]))
+
+
+def load_tests(loader, in_tests, pattern):
+ return testscenarios.load_tests_apply_scenarios(loader, in_tests, pattern)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pbr-0.11.0/pbr/tests/test_packaging.py new/pbr-1.0.1/pbr/tests/test_packaging.py
--- old/pbr-0.11.0/pbr/tests/test_packaging.py 2015-05-01 00:32:23.000000000 +0200
+++ new/pbr-1.0.1/pbr/tests/test_packaging.py 2015-05-20 00:36:58.000000000 +0200
@@ -40,10 +40,14 @@
import os
import re
+import sys
import tempfile
+import textwrap
import fixtures
import mock
+import pkg_resources
+import six
import testscenarios
from testtools import matchers
@@ -67,15 +71,7 @@
def setUp(self):
super(TestRepo, self).setUp()
base._run_cmd(['git', 'init', '.'], self._basedir)
- base._run_cmd(
- ['git', 'config', '--global', 'user.email', 'example@example.com'],
- self._basedir)
- base._run_cmd(
- ['git', 'config', '--global', 'user.name', 'OpenStack Developer'],
- self._basedir)
- base._run_cmd(
- ['git', 'config', '--global', 'user.signingkey',
- 'example@example.com'], self._basedir)
+ base._config_git()
base._run_cmd(['git', 'add', '.'], self._basedir)
def commit(self, message_content='test commit'):
@@ -425,5 +421,57 @@
self.assertEqual('1.3.0.0a1', version)
+class TestRequirementParsing(base.BaseTestCase):
+
+ def test_requirement_parsing(self):
+ tempdir = self.useFixture(fixtures.TempDir()).path
+ requirements = os.path.join(tempdir, 'requirements.txt')
+ with open(requirements, 'wt') as f:
+ f.write(textwrap.dedent(six.u("""\
+ bar
+ quux<1.0; python_version=='2.6'
+ """)))
+ setup_cfg = os.path.join(tempdir, 'setup.cfg')
+ with open(setup_cfg, 'wt') as f:
+ f.write(textwrap.dedent(six.u("""\
+ [metadata]
+ name = test_reqparse
+
+ [extras]
+ test =
+ foo
+ baz>3.2 :python_version=='2.7'
+ """)))
+ # pkg_resources.split_sections uses None as the title of an
+ # anonymous section instead of the empty string. Weird.
+ expected_requirements = {
+ None: ['bar'],
+ ":python_version=='2.6'": ['quux<1.0'],
+ "test:python_version=='2.7'": ['baz>3.2'],
+ "test": ['foo']
+ }
+ setup_py = os.path.join(tempdir, 'setup.py')
+ with open(setup_py, 'wt') as f:
+ f.write(textwrap.dedent(six.u("""\
+ #!/usr/bin/env python
+ import setuptools
+ setuptools.setup(
+ setup_requires=['pbr'],
+ pbr=True,
+ )
+ """)))
+
+ self._run_cmd(sys.executable, (setup_py, 'egg_info'),
+ allow_fail=False, cwd=tempdir)
+ egg_info = os.path.join(tempdir, 'test_reqparse.egg-info')
+
+ requires_txt = os.path.join(egg_info, 'requires.txt')
+ with open(requires_txt, 'rt') as requires:
+ generated_requirements = dict(
+ pkg_resources.split_sections(requires))
+
+ self.assertEqual(expected_requirements, generated_requirements)
+
+
def load_tests(loader, in_tests, pattern):
return testscenarios.load_tests_apply_scenarios(loader, in_tests, pattern)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pbr-0.11.0/pbr/tests/test_setup.py new/pbr-1.0.1/pbr/tests/test_setup.py
--- old/pbr-0.11.0/pbr/tests/test_setup.py 2015-05-01 00:32:23.000000000 +0200
+++ new/pbr-1.0.1/pbr/tests/test_setup.py 2015-05-20 00:36:58.000000000 +0200
@@ -275,6 +275,41 @@
self.assertIn('man', build_doc.builders)
self.assertIn('doctest', build_doc.builders)
+ def test_cmd_builder_override(self):
+
+ if self.has_opt:
+ self.distr.command_options["pbr"] = {
+ "autodoc_index_modules": ('setup.cfg', self.autodoc)
+ }
+
+ self.distr.command_options["build_sphinx"]["builder"] = (
+ "command line", "non-existing-builder")
+
+ build_doc = packaging.LocalBuildDoc(self.distr)
+ self.assertNotIn('non-existing-builder', build_doc.builders)
+ self.assertIn('html', build_doc.builders)
+
+ # process command line options which should override config
+ build_doc.finalize_options()
+
+ self.assertIn('non-existing-builder', build_doc.builders)
+ self.assertNotIn('html', build_doc.builders)
+
+ def test_cmd_builder_override_multiple_builders(self):
+
+ if self.has_opt:
+ self.distr.command_options["pbr"] = {
+ "autodoc_index_modules": ('setup.cfg', self.autodoc)
+ }
+
+ self.distr.command_options["build_sphinx"]["builder"] = (
+ "command line", "builder1,builder2")
+
+ build_doc = packaging.LocalBuildDoc(self.distr)
+ build_doc.finalize_options()
+
+ self.assertEqual(["builder1", "builder2"], build_doc.builders)
+
class ParseRequirementsTest(base.BaseTestCase):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pbr-0.11.0/pbr/tests/test_util.py new/pbr-1.0.1/pbr/tests/test_util.py
--- old/pbr-0.11.0/pbr/tests/test_util.py 1970-01-01 01:00:00.000000000 +0100
+++ new/pbr-1.0.1/pbr/tests/test_util.py 2015-05-20 00:36:58.000000000 +0200
@@ -0,0 +1,80 @@
+# Copyright (c) 2015 Hewlett-Packard Development Company, L.P. (HP)
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import io
+import textwrap
+
+import six
+from six.moves import configparser
+import testscenarios
+
+from pbr.tests import base
+from pbr import util
+
+
+class TestExtrasRequireParsingScenarios(base.BaseTestCase):
+
+ scenarios = [
+ ('simple_extras', {
+ 'config_text': """
+ [extras]
+ first =
+ foo
+ bar==1.0
+ second =
+ baz>=3.2
+ foo
+ """,
+ 'expected_extra_requires': {'first': ['foo', 'bar==1.0'],
+ 'second': ['baz>=3.2', 'foo']}
+ }),
+ ('with_markers', {
+ 'config_text': """
+ [extras]
+ test =
+ foo:python_version=='2.6'
+ bar
+ baz<1.6 :python_version=='2.6'
+ """,
+ 'expected_extra_requires': {
+ "test:python_version=='2.6'": ['foo', 'baz<1.6'],
+ "test": ['bar']}}),
+ ('no_extras', {
+ 'config_text': """
+ [metadata]
+ long_description = foo
+ """,
+ 'expected_extra_requires':
+ {}
+ })]
+
+ def config_from_ini(self, ini):
+ config = {}
+ parser = configparser.SafeConfigParser()
+ ini = textwrap.dedent(six.u(ini))
+ parser.readfp(io.StringIO(ini))
+ for section in parser.sections():
+ config[section] = dict(parser.items(section))
+ return config
+
+ def test_extras_parsing(self):
+ config = self.config_from_ini(self.config_text)
+ kwargs = util.setup_cfg_to_setup_kwargs(config)
+
+ self.assertEqual(self.expected_extra_requires,
+ kwargs['extras_require'])
+
+
+def load_tests(loader, in_tests, pattern):
+ return testscenarios.load_tests_apply_scenarios(loader, in_tests, pattern)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pbr-0.11.0/pbr/util.py new/pbr-1.0.1/pbr/util.py
--- old/pbr-0.11.0/pbr/util.py 2015-05-01 00:32:23.000000000 +0200
+++ new/pbr-1.0.1/pbr/util.py 2015-05-20 00:36:58.000000000 +0200
@@ -280,6 +280,10 @@
kwargs = {}
+ # Temporarily holds install_reqires and extra_requires while we
+ # parse env_markers.
+ all_requirements = {}
+
for arg in D1_D2_SETUP_ARGS:
if len(D1_D2_SETUP_ARGS[arg]) == 2:
# The distutils field name is different than distutils2's.
@@ -326,6 +330,17 @@
# setuptools
in_cfg_value = [_VERSION_SPEC_RE.sub(r'\1\2', pred)
for pred in in_cfg_value]
+ if arg == 'install_requires':
+ # Split install_requires into package,env_marker tuples
+ # These will be re-assembled later
+ install_requires = []
+ requirement_pattern = '(?P<package>[^;]*);?(?P.*)$'
+ for requirement in in_cfg_value:
+ m = re.match(requirement_pattern, requirement)
+ requirement_package = m.group('package').strip()
+ env_marker = m.group('env_marker').strip()
+ install_requires.append((requirement_package,env_marker))
+ all_requirements[''] = install_requires
elif arg == 'package_dir':
in_cfg_value = {'': in_cfg_value}
elif arg in ('package_data', 'data_files'):
@@ -367,6 +382,50 @@
kwargs[arg] = in_cfg_value
+ # Transform requirements with embedded environment markers to
+ # setuptools' supported marker-per-requirement format.
+ #
+ # install_requires are treated as a special case of extras, before
+ # being put back in the expected place
+ #
+ # fred =
+ # foo:marker
+ # bar
+ # -> {'fred': ['bar'], 'fred:marker':['foo']}
+
+ if 'extras' in config:
+ requirement_pattern = '(?P<package>[^:]*):?(?P.*)$'
+ extras = config['extras']
+ for extra in extras:
+ extra_requirements = []
+ requirements = split_multiline(extras[extra])
+ for requirement in requirements:
+ m = re.match(requirement_pattern, requirement)
+ extras_value = m.group('package').strip()
+ env_marker = m.group('env_marker')
+ extra_requirements.append((extras_value,env_marker))
+ all_requirements[extra] = extra_requirements
+
+ # Transform the full list of requirements into:
+ # - install_requires, for those that have no extra and no
+ # env_marker
+ # - named extras, for those with an extra name (which may include
+ # an env_marker)
+ # - and as a special case, install_requires with an env_marker are
+ # treated as named extras where the name is the empty string
+
+ extras_require = {}
+ for req_group in all_requirements:
+ for requirement, env_marker in all_requirements[req_group]:
+ if env_marker:
+ extras_key = '%s:%s' % (req_group, env_marker)
+ else:
+ extras_key = req_group
+ extras_require.setdefault(extras_key, []).append(requirement)
+
+ kwargs['install_requires'] = extras_require.pop('', [])
+ kwargs['extras_require'] = extras_require
+
return kwargs
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pbr-0.11.0/pbr.egg-info/PKG-INFO new/pbr-1.0.1/pbr.egg-info/PKG-INFO
--- old/pbr-0.11.0/pbr.egg-info/PKG-INFO 2015-05-01 00:33:09.000000000 +0200
+++ new/pbr-1.0.1/pbr.egg-info/PKG-INFO 2015-05-20 00:37:15.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: pbr
-Version: 0.11.0
+Version: 1.0.1
Summary: Python Build Reasonableness
Home-page: https://launchpad.net/pbr
Author: OpenStack
@@ -55,3 +55,4 @@
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pbr-0.11.0/pbr.egg-info/SOURCES.txt new/pbr-1.0.1/pbr.egg-info/SOURCES.txt
--- old/pbr-0.11.0/pbr.egg-info/SOURCES.txt 2015-05-01 00:33:09.000000000 +0200
+++ new/pbr-1.0.1/pbr.egg-info/SOURCES.txt 2015-05-20 00:37:15.000000000 +0200
@@ -6,7 +6,6 @@
LICENSE
MANIFEST.in
README.rst
-requirements.txt
setup.cfg
setup.py
test-requirements.txt
@@ -45,7 +44,6 @@
pbr.egg-info/entry_points.txt
pbr.egg-info/not-zip-safe
pbr.egg-info/pbr.json
-pbr.egg-info/requires.txt
pbr.egg-info/top_level.txt
pbr/cmd/__init__.py
pbr/cmd/main.py
@@ -61,8 +59,10 @@
pbr/tests/test_core.py
pbr/tests/test_files.py
pbr/tests/test_hooks.py
+pbr/tests/test_integration.py
pbr/tests/test_packaging.py
pbr/tests/test_setup.py
+pbr/tests/test_util.py
pbr/tests/test_version.py
pbr/tests/util.py
pbr/tests/testpackage/CHANGES.txt
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pbr-0.11.0/pbr.egg-info/pbr.json new/pbr-1.0.1/pbr.egg-info/pbr.json
--- old/pbr-0.11.0/pbr.egg-info/pbr.json 2015-05-01 00:33:09.000000000 +0200
+++ new/pbr-1.0.1/pbr.egg-info/pbr.json 2015-05-20 00:37:15.000000000 +0200
@@ -1 +1 @@
-{"is_release": true, "git_version": "a67e2c3"}
\ No newline at end of file
+{"is_release": true, "git_version": "b72e446"}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pbr-0.11.0/pbr.egg-info/requires.txt new/pbr-1.0.1/pbr.egg-info/requires.txt
--- old/pbr-0.11.0/pbr.egg-info/requires.txt 2015-05-01 00:33:09.000000000 +0200
+++ new/pbr-1.0.1/pbr.egg-info/requires.txt 1970-01-01 01:00:00.000000000 +0100
@@ -1 +0,0 @@
-pip
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pbr-0.11.0/requirements.txt new/pbr-1.0.1/requirements.txt
--- old/pbr-0.11.0/requirements.txt 2015-05-01 00:32:23.000000000 +0200
+++ new/pbr-1.0.1/requirements.txt 1970-01-01 01:00:00.000000000 +0100
@@ -1 +0,0 @@
-pip
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pbr-0.11.0/setup.cfg new/pbr-1.0.1/setup.cfg
--- old/pbr-0.11.0/setup.cfg 2015-05-01 00:33:09.000000000 +0200
+++ new/pbr-1.0.1/setup.cfg 2015-05-20 00:37:15.000000000 +0200
@@ -21,6 +21,7 @@
Programming Language :: Python :: 2.7
Programming Language :: Python :: 3
Programming Language :: Python :: 3.3
+ Programming Language :: Python :: 3.4
[files]
packages =
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pbr-0.11.0/test-requirements.txt new/pbr-1.0.1/test-requirements.txt
--- old/pbr-0.11.0/test-requirements.txt 2015-05-01 00:32:23.000000000 +0200
+++ new/pbr-1.0.1/test-requirements.txt 2015-05-20 00:36:59.000000000 +0200
@@ -1,11 +1,13 @@
coverage>=3.6
discover
fixtures>=0.3.14
-hacking>=0.9.2,<0.10
+hacking>=0.10.0,<0.11
mock>=1.0
python-subunit>=0.0.18
sphinx>=1.1.2,<1.2
+six>=1.9.0
testrepository>=0.0.18
testresources>=0.2.4
testscenarios>=0.4
testtools>=0.9.34
+virtualenv
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pbr-0.11.0/tools/integration.sh new/pbr-1.0.1/tools/integration.sh
--- old/pbr-0.11.0/tools/integration.sh 2015-05-01 00:32:23.000000000 +0200
+++ new/pbr-1.0.1/tools/integration.sh 2015-05-20 00:36:58.000000000 +0200
@@ -148,68 +148,19 @@
projectdir=$tmpdir/projects
mkdir -p $projectdir
+sudo chown -R $USER $REPODIR
-for PROJECT in $PROJECTS ; do
- SHORT_PROJECT=$(basename $PROJECT)
- if ! grep 'pbr' $REPODIR/$SHORT_PROJECT/setup.py >/dev/null 2>&1
- then
- # project doesn't use pbr
- continue
- fi
- if [ $SHORT_PROJECT = 'pypi-mirror' ]; then
- # pypi-mirror doesn't consume the mirror
- continue
- fi
- if [ $SHORT_PROJECT = 'jeepyb' ]; then
- # pypi-mirror doesn't consume the mirror
- continue
- fi
- if [ $SHORT_PROJECT = 'tempest' ]; then
- # Tempest doesn't really install
- continue
- fi
- if [ $SHORT_PROJECT = 'requirements' ]; then
- # requirements doesn't really install
- continue
- fi
-
- # set up the project synced with the global requirements
- sudo chown -R $USER $REPODIR/$SHORT_PROJECT
- (cd $REPODIR/requirements && python update.py $REPODIR/$SHORT_PROJECT)
- pushd $REPODIR/$SHORT_PROJECT
- if ! git diff --quiet ; then
- git commit -a -m'Update requirements'
- fi
- popd
-
- # Clone from synced repo
- shortprojectdir=$projectdir/$SHORT_PROJECT
- git clone $REPODIR/$SHORT_PROJECT $shortprojectdir
-
- # Test that we can make a tarball from scratch
- sdistvenv=$tmpdir/sdist
- mkvenv $sdistvenv
- cd $shortprojectdir
- $sdistvenv/bin/python setup.py sdist
-
- cd $tmpdir
-
- # Test that the tarball installs
- tarballvenv=$tmpdir/tarball
- mkvenv $tarballvenv
- $tarballvenv/bin/pip $PIPFLAGS install -f $WHEELHOUSE $shortprojectdir/dist/*tar.gz
-
- # Test pip installing
- pipvenv=$tmpdir/pip
- mkvenv $pipvenv
- $pipvenv/bin/pip $PIPFLAGS install -f $WHEELHOUSE git+file://$shortprojectdir
- # Ensure the install_package_data is doing the thing it should do
- if [ $SHORT_PROJECT = 'nova' ]; then
- find $pipvenv | grep migrate.cfg
- fi
-
- # Test pip install -e
- pipvenv=$tmpdir/pip
- mkvenv $pipvenv
- $pipvenv/bin/pip $PIPFLAGS install -f $WHEELHOUSE -e $shortprojectdir
-done
+export PBR_INTEGRATION=1
+export PIPFLAGS
+export PIPVERSION
+PBRVERSION=pbr
+if [ -n "$PBR_CHANGE" ] ; then
+ PBRVERSION=$(ls $pbrsdistdir/dist/pbr-*.whl)
+fi
+export PBRVERSION
+export PROJECTS
+export REPODIR
+export WHEELHOUSE
+export OS_TEST_TIMEOUT=600
+cd $REPODIR/pbr
+tox -epy27 -- test_integration
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pbr-0.11.0/tox.ini new/pbr-1.0.1/tox.ini
--- old/pbr-0.11.0/tox.ini 2015-05-01 00:32:23.000000000 +0200
+++ new/pbr-1.0.1/tox.ini 2015-05-20 00:36:58.000000000 +0200
@@ -8,7 +8,6 @@
install_command = pip install {opts} {packages}
setenv = VIRTUAL_ENV={envdir}
deps = .
- -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
commands =
python setup.py testr --testr-args='{posargs}'