summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/source/index.rst8
-rw-r--r--doc/source/packagers.rst59
-rw-r--r--pbr/extra_files.py35
-rw-r--r--pbr/hooks/commands.py1
-rw-r--r--pbr/packaging.py189
-rw-r--r--pbr/tests/test_core.py27
-rw-r--r--pbr/tests/test_packaging.py106
-rw-r--r--pbr/tests/testpackage/git-extra-file.txt0
-rw-r--r--pbr/util.py23
-rw-r--r--requirements.txt1
-rw-r--r--tools/integration.sh40
11 files changed, 426 insertions, 63 deletions
diff --git a/doc/source/index.rst b/doc/source/index.rst
index d3761d7..d05657b 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -191,6 +191,14 @@ installed for `pbr.config.drivers`, one called `plain` which maps to the
`Plain` class in `pbr.cfg.driver` and one called `fancy` which maps to the
`Fancy` class in `pbr.cfg.driver`.
+Packager Notes
+==============
+
+.. toctree::
+ :maxdepth: 1
+
+ packagers
+
Indices and tables
==================
diff --git a/doc/source/packagers.rst b/doc/source/packagers.rst
new file mode 100644
index 0000000..b1ee358
--- /dev/null
+++ b/doc/source/packagers.rst
@@ -0,0 +1,59 @@
+=====================
+ Notes for Packagers
+=====================
+
+If you are maintaining packages of software that uses `pbr`, there are some
+features you probably want to be aware of that can make your life easier.
+They are exposed by environment variables, so adding them to rules or spec
+files should be fairly easy.
+
+Versioning
+==========
+
+`pbr`, when run in a git repo, derives the version of a package from the
+git tags. When run in a tarball with a proper egg-info dir, it will happily
+pull the version from that. So for the most part, the packager shouldn't need
+to care. However, if you are doing something like keeping a git repo with
+the sources and the packaging intermixed and it's causing pbr to get confused
+about whether its in its own git repo or not, you can set `PBR_VERSION`:
+
+::
+
+ PBR_VERSION=1.2.3
+
+and all version calculation logic will be completely skipped and the supplied
+version will be considered absolute.
+
+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`:
+
+::
+
+ 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.
+
+Tarballs
+========
+
+`pbr` includes everything in a source tarball that is in the original `git`
+repository. This can again cause havoc if a packager is doing fancy things
+with combined `git` repos, and is generating a source tarball using `python
+setup.py sdist` from that repo. If that is the workflow the packager is using,
+setting `SKIP_GIT_SDIST`:
+
+::
+
+ SKIP_GIT_SDIST=1
+
+will cause all logic around using git to find the files that should be in the
+source tarball to be skipped. Beware though, that because `pbr` packages
+automatically find all of the files, most of them do not have a complete
+`MANIFEST.in` file, so its possible that a tarball produced in that way will
+be missing files.
diff --git a/pbr/extra_files.py b/pbr/extra_files.py
new file mode 100644
index 0000000..a72db0c
--- /dev/null
+++ b/pbr/extra_files.py
@@ -0,0 +1,35 @@
+# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
+#
+# 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.
+
+from distutils import errors
+import os
+
+_extra_files = []
+
+
+def get_extra_files():
+ global _extra_files
+ return _extra_files
+
+
+def set_extra_files(extra_files):
+ # Let's do a sanity check
+ for filename in extra_files:
+ if not os.path.exists(filename):
+ raise errors.DistutilsFileError(
+ '%s from the extra_files option in setup.cfg does not '
+ 'exist' % filename)
+ global _extra_files
+ _extra_files[:] = extra_files[:]
diff --git a/pbr/hooks/commands.py b/pbr/hooks/commands.py
index 0171d0d..b4206ed 100644
--- a/pbr/hooks/commands.py
+++ b/pbr/hooks/commands.py
@@ -39,6 +39,7 @@ class CommandsConfig(base.BaseConfig):
self.commands = "%s\n%s" % (self.commands, command)
def hook(self):
+ self.add_command('pbr.packaging.LocalEggInfo')
self.add_command('pbr.packaging.LocalSDist')
self.add_command('pbr.packaging.LocalInstallScripts')
if os.name != 'nt':
diff --git a/pbr/packaging.py b/pbr/packaging.py
index 526b5c3..a97880c 100644
--- a/pbr/packaging.py
+++ b/pbr/packaging.py
@@ -31,6 +31,7 @@ import distutils.errors
from distutils import log
import pkg_resources
from setuptools.command import easy_install
+from setuptools.command import egg_info
from setuptools.command import install
from setuptools.command import install_scripts
from setuptools.command import sdist
@@ -40,6 +41,8 @@ try:
except ImportError:
import io
+from pbr import extra_files
+
log.set_verbosity(log.INFO)
TRUE_VALUES = ('true', '1', 'yes')
REQUIREMENTS_FILES = ('requirements.txt', 'tools/pip-requires')
@@ -49,6 +52,13 @@ TEST_REQUIREMENTS_FILES = ('test-requirements.txt', 'tools/test-requires')
BROKEN_ON_27 = ('argparse', 'importlib')
+def get_requirements_files():
+ files = os.environ.get("PBR_REQUIREMENTS_FILES")
+ if files:
+ return tuple(f.strip() for f in files.split(','))
+ return REQUIREMENTS_FILES
+
+
def append_text_list(config, key, text_list):
"""Append a \n separated list to possibly existing value."""
new_value = []
@@ -79,8 +89,9 @@ def _make_links_args(links):
return ["-f '%s'" % link for link in links]
-def _pip_install(links, requires, root=None):
- if str(os.getenv('SKIP_PIP_INSTALL', '')).lower() in TRUE_VALUES:
+def _pip_install(links, requires, root=None, option_dict=dict()):
+ if get_boolean_option(
+ option_dict, 'skip_pip_install', 'SKIP_PIP_INSTALL'):
return
root_cmd = ""
if root:
@@ -129,11 +140,7 @@ def get_reqs_from_files(requirements_files):
def parse_requirements(requirements_files=None):
if requirements_files is None:
- files = os.environ.get("PBR_REQUIREMENTS_FILES")
- if files:
- requirements_files = tuple(f.strip() for f in files.split(','))
- else:
- requirements_files = REQUIREMENTS_FILES
+ requirements_files = get_requirements_files()
def egg_fragment(match):
# take a versioned egg fragment and return a
@@ -176,7 +183,9 @@ def parse_requirements(requirements_files=None):
return requirements
-def parse_dependency_links(requirements_files=REQUIREMENTS_FILES):
+def parse_dependency_links(requirements_files=None):
+ if requirements_files is None:
+ requirements_files = get_requirements_files()
dependency_links = []
# dependency_links inject alternate locations to find packages listed
# in requirements
@@ -214,7 +223,7 @@ def _run_shell_command(cmd, throw_on_error=False, buffer=True):
raise distutils.errors.DistutilsError(
"%s returned %d" % (cmd, output.returncode))
if len(out) == 0 or not out[0] or not out[0].strip():
- return None
+ return ''
return out[0].strip().decode('utf-8')
@@ -267,27 +276,53 @@ def generate_authors(git_dir=None, dest_dir='.', option_dict=dict()):
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 = ("git --git-dir=" + git_dir +
- " log --format='%aN <%aE>' | sort -u | "
- "egrep -v '" + ignore_emails + "'")
- changelog = _run_shell_command(git_log_cmd)
- signed_cmd = ("git log --git-dir=" + git_dir +
- " | grep -i Co-authored-by: | sort -u")
- signed_entries = _run_shell_command(signed_cmd)
- if signed_entries:
- new_entries = "\n".join(
- [signed.split(":", 1)[1].strip()
- for signed in signed_entries.split("\n") if signed])
- changelog = "\n".join((changelog, new_entries))
+ " log --format='%aN <%aE>'"
+ " | egrep -v '" + ignore_emails + "'")
+ authors += _run_shell_command(git_log_cmd).split('\n')
+
+ # get all co-authors from commit messages
+ co_authors_cmd = ("git log --git-dir=" + git_dir +
+ " | grep -i Co-authored-by:")
+ co_authors = _run_shell_command(co_authors_cmd)
+
+ co_authors = [signed.split(":", 1)[1].strip()
+ for signed in co_authors.split('\n') if signed]
+
+ authors += co_authors
+
+ # canonicalize emails, remove duplicates and sort
+ mailmap = read_git_mailmap(git_dir)
+ authors = canonicalize_emails('\n'.join(authors), mailmap)
+ authors = authors.split('\n')
+ authors = sorted(set(authors))
- mailmap = read_git_mailmap()
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(canonicalize_emails(
- changelog, mailmap).encode('utf-8'))
+ new_authors_fh.write(('\n'.join(authors) + '\n')
+ .encode('utf-8'))
+
+
+def _find_git_files(dirname='', git_dir=None):
+ """Behave like a file finder entrypoint plugin.
+
+ We don't actually use the entrypoints system for this because it runs
+ at absurd times. We only want to do this when we are building an sdist.
+ """
+ file_list = []
+ if git_dir is None:
+ git_dir = _get_git_directory()
+ if git_dir:
+ log.info("[pbr] In git context, generating filelist from git")
+ git_ls_cmd = "git --git-dir=%s ls-files -z" % git_dir
+ file_list = _run_shell_command(git_ls_cmd)
+ file_list = file_list.split(b'\x00'.decode('utf-8'))
+ return [f for f in file_list if f]
_rst_template = """%(heading)s
@@ -326,17 +361,20 @@ class LocalInstall(install.install):
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):
links = _make_links_args(self.distribution.dependency_links)
- _pip_install(links, self.distribution.install_requires, self.root)
+ _pip_install(
+ 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', REQUIREMENTS_FILES),
+ 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):
@@ -362,7 +400,10 @@ class _PipInstallTestRequires(object):
links = _make_links_args(
parse_dependency_links(TEST_REQUIREMENTS_FILES))
if self.distribution.tests_require:
- _pip_install(links, 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())
@@ -447,7 +488,7 @@ def override_get_script_args(
import_target=ep.attrs[0],
invoke_target='.'.join(ep.attrs),
)
- yield (name, header+script_text)
+ yield (name, header + script_text)
class LocalInstallScripts(install_scripts.install_scripts):
@@ -488,6 +529,65 @@ class LocalInstallScripts(install_scripts.install_scripts):
self.write_script(*args)
+class LocalManifestMaker(egg_info.manifest_maker):
+ """Add any files that are in git and some standard sensible files."""
+
+ def _add_pbr_defaults(self):
+ for template_line in [
+ 'include AUTHORS',
+ 'include ChangeLog',
+ 'exclude .gitignore',
+ 'exclude .gitreview',
+ 'global-exclude *.pyc'
+ ]:
+ self.filelist.process_template_line(template_line)
+
+ def add_defaults(self):
+ option_dict = self.distribution.get_option_dict('pbr')
+
+ sdist.sdist.add_defaults(self)
+ self.filelist.append(self.template)
+ self.filelist.append(self.manifest)
+ self.filelist.extend(extra_files.get_extra_files())
+ should_skip = get_boolean_option(option_dict, 'skip_git_sdist',
+ 'SKIP_GIT_SDIST')
+ if not should_skip:
+ rcfiles = _find_git_files()
+ if rcfiles:
+ self.filelist.extend(rcfiles)
+ elif os.path.exists(self.manifest):
+ self.read_manifest()
+ ei_cmd = self.get_finalized_command('egg_info')
+ self._add_pbr_defaults()
+ self.filelist.include_pattern("*", prefix=ei_cmd.egg_info)
+
+
+class LocalEggInfo(egg_info.egg_info):
+ """Override the egg_info command to regenerate SOURCES.txt sensibly."""
+
+ command_name = 'egg_info'
+
+ def find_sources(self):
+ """Generate SOURCES.txt only if there isn't one already.
+
+ If we are in an sdist command, then we always want to update
+ SOURCES.txt. If we are not in an sdist command, then it doesn't
+ matter one flip, and is actually destructive.
+ """
+ manifest_filename = os.path.join(self.egg_info, "SOURCES.txt")
+ if not os.path.exists(manifest_filename) or 'sdist' in sys.argv:
+ log.info("[pbr] Processing SOURCES.txt")
+ mm = LocalManifestMaker(self.distribution)
+ mm.manifest = manifest_filename
+ mm.run()
+ self.filelist = mm.filelist
+ else:
+ log.info("[pbr] Reusing existing SOURCES.txt")
+ self.filelist = egg_info.FileList()
+ for entry in open(manifest_filename, 'r').read().split('\n'):
+ self.filelist.append(entry)
+
+
class LocalSDist(sdist.sdist):
"""Builds the ChangeLog and Authors files from VC first."""
@@ -501,6 +601,7 @@ class LocalSDist(sdist.sdist):
sdist.sdist.run(self)
try:
+ from sphinx import apidoc
from sphinx import application
from sphinx import config
from sphinx import setup_command
@@ -510,17 +611,21 @@ try:
command_name = 'build_sphinx'
builders = ['html', 'man']
- def generate_autoindex(self):
+ def _get_source_dir(self):
option_dict = self.distribution.get_option_dict('build_sphinx')
- log.info("[pbr] Autodocumenting from %s"
- % os.path.abspath(os.curdir))
- modules = {}
if 'source_dir' in option_dict:
source_dir = os.path.join(option_dict['source_dir'][1], 'api')
else:
source_dir = 'doc/source/api'
if not os.path.exists(source_dir):
os.makedirs(source_dir)
+ return source_dir
+
+ def generate_autoindex(self):
+ log.info("[pbr] Autodocumenting from %s"
+ % os.path.abspath(os.curdir))
+ modules = {}
+ source_dir = self._get_source_dir()
for pkg in self.distribution.packages:
if '.' not in pkg:
for dirpath, dirnames, files in os.walk(pkg):
@@ -547,6 +652,10 @@ try:
output_file.write(_rst_template % values)
autoindex.write(" %s.rst\n" % module)
+ def _sphinx_tree(self):
+ source_dir = self._get_source_dir()
+ apidoc.main(['apidoc', '.', '-H', 'Modules', '-o', source_dir])
+
def _sphinx_run(self):
if not self.verbose:
status_stream = io.StringIO()
@@ -587,11 +696,19 @@ try:
def run(self):
option_dict = self.distribution.get_option_dict('pbr')
- if ('autodoc_index_modules' in option_dict and
- option_dict.get(
- 'autodoc_index_modules')[1].lower() in TRUE_VALUES and
- not os.getenv('SPHINX_DEBUG')):
- self.generate_autoindex()
+ tree_index = get_boolean_option(option_dict,
+ 'autodoc_tree_index_modules',
+ 'AUTODOC_TREE_INDEX_MODULES')
+ auto_index = get_boolean_option(option_dict,
+ 'autodoc_index_modules',
+ 'AUTODOC_INDEX_MODULES')
+ if not os.getenv('SPHINX_DEBUG'):
+ #NOTE(afazekas): These options can be used together,
+ # but they do a very similar thing in a difffernet way
+ if tree_index:
+ self._sphinx_tree()
+ if auto_index:
+ self.generate_autoindex()
for builder in self.builders:
self.builder = builder
diff --git a/pbr/tests/test_core.py b/pbr/tests/test_core.py
index a7376eb..dd21e6f 100644
--- a/pbr/tests/test_core.py
+++ b/pbr/tests/test_core.py
@@ -90,7 +90,7 @@ class TestCore(tests.BaseTestCase):
tf = tarfile.open(tf_path)
names = ['/'.join(p.split('/')[1:]) for p in tf.getnames()]
- assert 'extra-file.txt' in names
+ self.assertIn('extra-file.txt', names)
def test_console_script_install(self):
"""Test that we install a non-pkg-resources console script."""
@@ -120,3 +120,28 @@ class TestCore(tests.BaseTestCase):
'develop', '--install-dir=%s' % self.temp_dir)
self.check_script_install(stdout)
+
+
+class TestGitSDist(tests.BaseTestCase):
+
+ def setUp(self):
+ super(TestGitSDist, self).setUp()
+
+ stdout, _, return_code = self._run_cmd('git', ('init',))
+ if return_code:
+ self.skipTest("git not installed")
+
+ stdout, _, return_code = self._run_cmd('git', ('add', '.'))
+ stdout, _, return_code = self._run_cmd(
+ 'git', ('commit', '-m', 'Turn this into a git repo'))
+
+ stdout, _, return_code = self.run_setup('sdist', '--formats=gztar')
+
+ def test_sdist_git_extra_files(self):
+ """Test that extra files found in git are correctly added."""
+ # There can be only one
+ tf_path = glob.glob(os.path.join('dist', '*.tar.gz'))[0]
+ tf = tarfile.open(tf_path)
+ names = ['/'.join(p.split('/')[1:]) for p in tf.getnames()]
+
+ self.assertIn('git-extra-file.txt', names)
diff --git a/pbr/tests/test_packaging.py b/pbr/tests/test_packaging.py
new file mode 100644
index 0000000..562b10e
--- /dev/null
+++ b/pbr/tests/test_packaging.py
@@ -0,0 +1,106 @@
+# Copyright (c) 2013 New Dream Network, LLC (DreamHost)
+#
+# 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.
+#
+# Copyright (C) 2013 Association of Universities for Research in Astronomy
+# (AURA)
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials provided
+# with the distribution.
+#
+# 3. The name of AURA and its representatives may not be used to
+# endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY AURA ``AS IS'' AND ANY EXPRESS OR IMPLIED
+# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL AURA BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+
+import os
+
+from pbr import tests
+
+
+class TestPackagingInGitRepoWithCommit(tests.BaseTestCase):
+
+ def setUp(self):
+ super(TestPackagingInGitRepoWithCommit, self).setUp()
+ self._run_cmd('git', ['init', '.'])
+ self._run_cmd('git', ['add', '.'])
+ self._run_cmd('git', ['commit', '-m', 'test commit'])
+ self.run_setup('sdist')
+ return
+
+ def test_authors(self):
+ # One commit, something should be in the authors list
+ with open(os.path.join(self.package_dir, 'AUTHORS'), 'r') as f:
+ body = f.read()
+ self.assertNotEqual(body, '')
+
+ def test_changelog(self):
+ with open(os.path.join(self.package_dir, 'ChangeLog'), 'r') as f:
+ body = f.read()
+ # One commit, something should be in the ChangeLog list
+ self.assertNotEqual(body, '')
+
+
+class TestPackagingInGitRepoWithoutCommit(tests.BaseTestCase):
+
+ def setUp(self):
+ super(TestPackagingInGitRepoWithoutCommit, self).setUp()
+ self._run_cmd('git', ['init', '.'])
+ self._run_cmd('git', ['add', '.'])
+ self.run_setup('sdist')
+ return
+
+ def test_authors(self):
+ # No commits, no authors in list
+ with open(os.path.join(self.package_dir, 'AUTHORS'), 'r') as f:
+ body = f.read()
+ self.assertEqual(body, '\n')
+
+ def test_changelog(self):
+ # No commits, nothing should be in the ChangeLog list
+ with open(os.path.join(self.package_dir, 'ChangeLog'), 'r') as f:
+ body = f.read()
+ self.assertEqual(body, '')
+
+
+class TestPackagingInPlainDirectory(tests.BaseTestCase):
+
+ def setUp(self):
+ super(TestPackagingInPlainDirectory, self).setUp()
+ self.run_setup('sdist')
+ return
+
+ def test_authors(self):
+ # Not a git repo, no AUTHORS file created
+ filename = os.path.join(self.package_dir, 'AUTHORS')
+ self.assertFalse(os.path.exists(filename))
+
+ def test_changelog(self):
+ # Not a git repo, no ChangeLog created
+ filename = os.path.join(self.package_dir, 'ChangeLog')
+ self.assertFalse(os.path.exists(filename))
diff --git a/pbr/tests/testpackage/git-extra-file.txt b/pbr/tests/testpackage/git-extra-file.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/pbr/tests/testpackage/git-extra-file.txt
diff --git a/pbr/util.py b/pbr/util.py
index 6339116..1682b66 100644
--- a/pbr/util.py
+++ b/pbr/util.py
@@ -77,6 +77,7 @@ try:
except ImportError:
import configparser
+from pbr import extra_files
import pbr.hooks
# A simplified RE for this; just checks that the line ends with version
@@ -222,7 +223,7 @@ def cfg_to_args(path='setup.cfg'):
if setup_hooks:
setup_hooks = [
hook for hook in split_multiline(setup_hooks)
- if hook != 'pbr.hook.setup_hook']
+ if hook != 'pbr.hooks.setup_hook']
for hook in setup_hooks:
hook_fn = resolve_name(hook)
try :
@@ -258,23 +259,9 @@ def cfg_to_args(path='setup.cfg'):
wrap_commands(kwargs)
# Handle the [files]/extra_files option
- extra_files = has_get_option(config, 'files', 'extra_files')
- if extra_files:
- extra_files = split_multiline(extra_files)
- # Let's do a sanity check
- for filename in extra_files:
- if not os.path.exists(filename):
- raise DistutilsFileError(
- '%s from the extra_files option in setup.cfg does not '
- 'exist' % filename)
- # Unfortunately the only really sensible way to do this is to
- # monkey-patch the manifest_maker class
- @monkeypatch_method(manifest_maker)
- def add_defaults(self, extra_files=extra_files, log=log):
- log.info('[pbr] running patched manifest_maker command '
- 'with extra_files support')
- add_defaults._orig(self)
- self.filelist.extend(extra_files)
+ files_extra_files = has_get_option(config, 'files', 'extra_files')
+ if files_extra_files:
+ extra_files.set_extra_files(split_multiline(files_extra_files))
finally:
# Perform cleanup if any paths were added to sys.path
diff --git a/requirements.txt b/requirements.txt
index da917d5..4627de5 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,2 +1 @@
-setuptools_git>=0.4
pip>=1.0
diff --git a/tools/integration.sh b/tools/integration.sh
index b32b303..8f7b46f 100644
--- a/tools/integration.sh
+++ b/tools/integration.sh
@@ -17,9 +17,6 @@ function mkvenv {
$venv/bin/pip install $pip
}
-# PROJECTS is a list of projects that we're testing
-PROJECTS=$*
-
# BASE should be a directory with a subdir called "new" and in that
# dir, there should be a git repository for every entry in PROJECTS
BASE=${BASE:-/opt/stack}
@@ -29,9 +26,9 @@ 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
-tmpdir=`mktemp -d`
+tmpdir=$(mktemp -d)
-whoami=`whoami`
+whoami=$(whoami)
tmpdownload=$tmpdir/download
mkdir -p $tmpdownload
@@ -40,9 +37,11 @@ mkdir -p $pypidir
jeepybvenv=$tmpdir/jeepyb
+sudo touch $HOME/pip.log
+sudo chown $USER $HOME/pip.log
+
rm -f ~/.pip/pip.conf ~/.pydistutils.cfg
mkdir -p ~/.pip
-
cat <<EOF > ~/.pip/pip.conf
[global]
log = $HOME/pip.log
@@ -64,6 +63,24 @@ mirrors:
output: $pypidir
EOF
+# Default to using pypi.openstack.org as an easy_install mirror
+if [ "$1" == "--no-mirror" ] ; then
+ shift
+else
+ cat <<EOF > ~/.pydistutils.cfg
+[easy_install]
+index_url = http://pypi.openstack.org/openstack
+EOF
+ cat <<EOF > ~/.pip/pip.conf
+[global]
+index-url = http://pypi.openstack.org/openstack
+log = $HOME/pip.log
+EOF
+fi
+
+# PROJECTS is a list of projects that we're testing
+PROJECTS=$*
+
pbrsdistdir=$tmpdir/pbrsdist
git clone $REPODIR/pbr $pbrsdistdir
cd $pbrsdistdir
@@ -77,6 +94,8 @@ $jeepybvenv/bin/python setup.py sdist -d $tmpdownload/pip/openstack
$jeepybvenv/bin/run-mirror -b remotes/origin/master --verbose -c $tmpdir/mirror.yaml --no-download
+find $pypidir
+
# Make pypi thing
pypiurl=file://$pypidir
@@ -139,7 +158,7 @@ projectdir=$tmpdir/projects
mkdir -p $projectdir
for PROJECT in $PROJECTS ; do
- SHORT_PROJECT=`basename $PROJECT`
+ SHORT_PROJECT=$(basename $PROJECT)
if ! grep 'pbr' $REPODIR/$SHORT_PROJECT/requirements.txt >/dev/null 2>&1
then
# project doesn't use pbr
@@ -154,6 +173,13 @@ for PROJECT in $PROJECTS ; do
continue
fi
shortprojectdir=$projectdir/$SHORT_PROJECT
+ 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
git clone $REPODIR/$SHORT_PROJECT $shortprojectdir
sdistvenv=$tmpdir/sdist