Hello community, here is the log from the commit of package python-pbr for openSUSE:Factory checked in at 2015-06-09 08:48:24 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-pbr (Old) and /work/SRC/openSUSE:Factory/.python-pbr.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pbr" Changes: -------- --- /work/SRC/openSUSE:Factory/python-pbr/python-pbr.changes 2015-05-10 10:46:13.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.python-pbr.new/python-pbr.changes 2015-06-09 08:48:26.000000000 +0200 @@ -1,0 +2,16 @@ +Tue Jun 2 16:19:13 UTC 2015 - [email protected] + +- update to 1.0.1: + * Remove self.pre_run calls in packaging.py + * Update hacking to 0.10.x series + * 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 +- Removed pbr-0.10.8-fix-sphinx-init_values.patch . Replaced upstream + with 0001-Remove-sphinx_config.init_values-manual-call.patch +- Added 0001-Remove-sphinx_config.init_values-manual-call.patch + +------------------------------------------------------------------- Old: ---- pbr-0.10.8-fix-sphinx-init_values.patch pbr-0.11.0.tar.gz New: ---- 0001-Remove-sphinx_config.init_values-manual-call.patch pbr-1.0.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-pbr.spec ++++++ --- /var/tmp/diff_new_pack.sqqjgy/_old 2015-06-09 08:48:27.000000000 +0200 +++ /var/tmp/diff_new_pack.sqqjgy/_new 2015-06-09 08:48:27.000000000 +0200 @@ -21,7 +21,7 @@ %bcond_with test Name: python-pbr -Version: 0.11.0 +Version: 1.0.1 Release: 0 Summary: Python Build Reasonableness License: Apache-2.0 @@ -29,7 +29,8 @@ Url: http://pypi.python.org/pypi/pbr Source: https://pypi.python.org/packages/source/p/pbr/pbr-%{version}.tar.gz Source1: python-pbr-rpmlintrc -Patch: pbr-0.10.8-fix-sphinx-init_values.patch +# PATCH-FIX-UPSTREAM needed to be able to use Sphinx >= 1.3 versions +Patch: 0001-Remove-sphinx_config.init_values-manual-call.patch BuildRequires: fdupes BuildRequires: python-devel BuildRequires: python-pip >= 1.4 ++++++ 0001-Remove-sphinx_config.init_values-manual-call.patch ++++++ >From 1dfe9ef348c777bef67b2c2b1d35e50ebc720333 Mon Sep 17 00:00:00 2001 From: Thomas Bechtold <[email protected]> Date: Tue, 2 Jun 2015 18:40:38 +0200 Subject: [PATCH] Remove sphinx_config.init_values() manual call The function signature for Sphinx's config.init_values() changed since version 1.3. That leads to: TypeError: init_values() takes exactly 2 arguments (1 given) But the function is already correctly called from application.Sphinx()'s constructor. So use the configuration object from the application instead of creating an own config object. Change-Id: I343c26560bfe5116d5348b50b1890b3442ed845a Closes-Bug: #1379998 --- pbr/builddoc.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/pbr/builddoc.py b/pbr/builddoc.py index 7c9916b..60f2afd 100644 --- a/pbr/builddoc.py +++ b/pbr/builddoc.py @@ -26,7 +26,6 @@ except ImportError: try: from sphinx import apidoc from sphinx import application - from sphinx import config from sphinx import setup_command except Exception as e: # NOTE(dhellmann): During the installation of docutils, setuptools @@ -126,16 +125,16 @@ class LocalBuildDoc(setup_command.BuildDoc): confoverrides['release'] = self.release if self.today: confoverrides['today'] = self.today - sphinx_config = config.Config(self.config_dir, 'conf.py', {}, []) - sphinx_config.init_values() - if self.builder == 'man' and len(sphinx_config.man_pages) == 0: - return + app = application.Sphinx( self.source_dir, self.config_dir, self.builder_target_dir, self.doctree_dir, self.builder, confoverrides, status_stream, freshenv=self.fresh_env, warningiserror=True) + if self.builder == 'man' and len(app.config.man_pages) == 0: + return + try: app.build(force_all=self.all_files) except Exception as err: -- 2.4.2 ++++++ 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 <[email protected]> Claudiu Popa <[email protected]> Dan Prince <[email protected]> +Darragh Bailey <[email protected]> Davanum Srinivas <[email protected]> Dave Walker (Daviey) <[email protected]> David Ripton <[email protected]> @@ -23,6 +24,7 @@ Doug Hellmann <[email protected]> Doug Hellmann <[email protected]> Doug Hellmann <[email protected]> +Elena Ezhova <[email protected]> Eoghan Glynn <[email protected]> Eric Windisch <[email protected]> Erik M. Bray <[email protected]> @@ -31,6 +33,7 @@ Giampaolo Lauria <[email protected]> Ionuț Arțăriși <[email protected]> James E. Blair <[email protected]> +James Polley <[email protected]> Jason Kölker <[email protected]> Jay Pipes <[email protected]> Jeremy Stanley <[email protected]> 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', '[email protected]'], + None) + _run_cmd( + ['git', 'config', '--global', 'user.name', 'OpenStack Developer'], + None) + _run_cmd( + ['git', 'config', '--global', 'user.signingkey', + '[email protected]'], 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', '[email protected]'], - self._basedir) - base._run_cmd( - ['git', 'config', '--global', 'user.name', 'OpenStack Developer'], - self._basedir) - base._run_cmd( - ['git', 'config', '--global', 'user.signingkey', - '[email protected]'], 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<env_marker>.*)$' + 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<env_marker>.*)$' + 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}'
