Alex Gaynor <alex.gaynor@gmail.com>
Alexander Makarov <amakarov@mirantis.com>
Alfredo Moralejo <amoralej@redhat.com>
+Andreas Jaeger <aj@suse.com>
Andreas Jaeger <aj@suse.de>
Andrew Bogott <abogott@wikimedia.org>
Angus Salkeld <asalkeld@redhat.com>
Erik M. Bray <embray@stsci.edu>
Eugene Kirpichov <ekirpichov@gmail.com>
Florian Wilhelm <Florian.Wilhelm@blue-yonder.com>
+Gaetan Semet <gaetan@xeberon.net>
Gage Hugo <gagehugo@gmail.com>
Gary Kotton <gkotton@redhat.com>
Giampaolo Lauria <lauria@us.ibm.com>
James E. Blair <jeblair@hp.com>
James Polley <jp@jamezpolley.com>
Jason Kölker <jason@koelker.net>
+Jason R. Coombs <jaraco@jaraco.com>
Jay Pipes <jaypipes@gmail.com>
Jeremy Stanley <fungi@yuggoth.org>
+Joe D'Andrea <jdandrea@research.att.com>
Joe Gordon <joe.gordon0@gmail.com>
Joe Gordon <jogo@cloudscaling.com>
Joe Heck <heckj@mac.com>
Ondřej Nový <ondrej.novy@firma.seznam.cz>
Paul Belanger <pabelanger@redhat.com>
Rajaram Mallya <rajarammallya@gmail.com>
+Rajath Agasthya <rajagast@cisco.com>
Ralf Haferkamp <rhafer@suse.de>
Randall Nortman <openstack@nortman.net>
Rick Harris <rconradharris@gmail.com>
Yaguang Tang <heut2008@gmail.com>
Yuriy Taraday <yorik.sar@gmail.com>
Zhongyue Luo <zhongyue.nah@intel.com>
+Zuul <zuul@review.openstack.org>
alexpilotti <ap@pilotti.it>
cbjchen@cn.ibm.com <cbjchen@cn.ibm.com>
dineshbhor <dinesh.bhor@nttdata.com>
melanie witt <melwitt@yahoo-inc.com>
nizam <abdul.nizamuddin@nectechnologies.in>
weiweigu <gu.weiwei@zte.com.cn>
+zhangyangyang <zhangyangyang@unionpay.com>
zhangyanxian <zhang.yanxian@zte.com.cn>
CHANGES
=======
+4.0.0
+-----
+
+* builddoc: Treat '[pbr] autodoc\_tree\_excludes' as a multi-line opt
+* update parse test to use reliable comparison
+* Make docs on env vars a little clearer
+* Updated from global requirements
+* Updated from global requirements
+* future-proof invocation of apidoc
+* emit warning correctly
+* Updated from global requirements
+* deprecations: Deprecate support for '-py{N}' requirements
+* doc: Minor rework of usage doc
+* doc: Rework features doc
+* Support v<semver> version
+* Deprecate testr and nose integration
+* tests: Increase coverage of requirements parsing
+* trivial: Move packaging tests to test\_packaging
+* Put test-requirements into an extra named 'test'
+* Support Description-Content-Type metadata
+* Avoid tox\_install.sh for constraints support
+* Test on Python 3.6
+* Support PEP 345 Project-URL metadata
+* Remove setting of version/release from releasenotes
+* Updated from global requirements
+* Use 'build\_reno' setuptools extension if available
+* Remove unnecessary 'if True'
+* Discover Distribution through the class hierarchy
+* Add reno for release notes management
+* Remove support for command hooks
+* Remove dead code
+* Deprecate support for Sphinx < 1.6
+* builddoc: Use '[sphinx\_build] builders' with Sphinx < 1.6
+* Remove win32/nt checks for wrapper script gen
+* Updated from global requirements
+* Remove py26 support
+* Updated from global requirements
+* Updated from global requirements
+* Updated from global requirements
+* Update URLs in documents according to document migration
+* Updated from global requirements
+* gitignore: Ignore .venv
+* switch from oslosphinx to openstackdocstheme
+* Trivial: Fix docstring
+* turn on warning-as-error flag for doc build
+* rearrange existing documentation using the new standard layout
+
3.1.1
-----
* Restore previous IP binding
+* docs: Don't specify pbr version in 'setup.py'
3.1.0
-----
-Metadata-Version: 1.1
+Metadata-Version: 2.1
Name: pbr
-Version: 3.1.1
+Version: 4.0.0
Summary: Python Build Reasonableness
-Home-page: http://docs.openstack.org/developer/pbr/
+Home-page: https://docs.openstack.org/pbr/latest/
Author: OpenStack
Author-email: openstack-dev@lists.openstack.org
License: UNKNOWN
+Project-URL: Bug Tracker, https://bugs.launchpad.net/pbr/
+Project-URL: Documentation, https://docs.openstack.org/pbr/
+Project-URL: Source Code, https://git.openstack.org/cgit/openstack-dev/pbr/
Description: Introduction
============
them as quickly as possible.
* License: Apache License, Version 2.0
- * Documentation: http://docs.openstack.org/developer/pbr
- * Source: http://git.openstack.org/cgit/openstack-dev/pbr
- * Bugs: http://bugs.launchpad.net/pbr
- * Change Log: https://docs.openstack.org/developer/pbr/history.html
+ * Documentation: https://docs.openstack.org/pbr/latest/
+ * Source: https://git.openstack.org/cgit/openstack-dev/pbr
+ * Bugs: https://bugs.launchpad.net/pbr
+ * Change Log: https://docs.openstack.org/pbr/latest/user/history.html
.. _d2to1: https://pypi.python.org/pypi/d2to1
.. _distutils2: https://pypi.python.org/pypi/Distutils2
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
+Description-Content-Type: text/x-rst; charset=UTF-8
them as quickly as possible.
* License: Apache License, Version 2.0
-* Documentation: http://docs.openstack.org/developer/pbr
-* Source: http://git.openstack.org/cgit/openstack-dev/pbr
-* Bugs: http://bugs.launchpad.net/pbr
-* Change Log: https://docs.openstack.org/developer/pbr/history.html
+* Documentation: https://docs.openstack.org/pbr/latest/
+* Source: https://git.openstack.org/cgit/openstack-dev/pbr
+* Bugs: https://bugs.launchpad.net/pbr
+* Change Log: https://docs.openstack.org/pbr/latest/user/history.html
.. _d2to1: https://pypi.python.org/pypi/d2to1
.. _distutils2: https://pypi.python.org/pypi/Distutils2
+++ /dev/null
-..
- The name of this document and the anchor in this document must be
- treated as a stable API. Links to this document are coded into
- pbr and deployed versions of pbr will refer users to this document
- in the case of certain errors.
- Ensure any link you use in PBR is defined via a ref with .. _name.
-
-
-===================
-Compatibility Notes
-===================
-
-Useful notes about errors users may encounter when features cannot be
-supported on older versions of setuptools / pip / wheel.
-
-
-setuptools
-==========
-
-
-.. _evaluate-marker:
-
-evaluate_marker
----------------
-
-evaluate_markers may run into issues with the '>', '>=', '<', and '<='
-operators if the installed version of setuptools is less than 17.1. Projects
-using these operators with markers should specify a minimum version of 17.1
-for setuptools.
-
-
-pip
-===
-
-markers
--------
-
-For versions of pip < 7 with pbr < 1.9, dependencies that use markers will not
-be installed. Projects using pbr and markers should set a minimum version of
-1.9 for pbr.
-
-
-Recommended setup.py
-====================
-
-:ref:`setup_py`.
-
-
-Sphinx
-======
-
-.. _sphinx-1.5:
-
-Version 1.5.0+
---------------
-
-The ``warning-is-error`` flag is only supported by Sphinx 1.5 and will cause
-errors when used with older versions.
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['sphinx.ext.autodoc']
-# make oslosphinx optional to not increase the needed dependencies
+extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo']
+# make openstackdocstheme optional to not increase the needed dependencies
try:
- import oslosphinx
+ import openstackdocstheme
+ extensions.append('openstackdocstheme')
except ImportError:
- pass
-else:
- extensions.append('oslosphinx')
+ openstackdocstheme = None
+
+# openstackdocstheme options
+repository_name = 'openstack/pbr'
+bug_project = 'pbr'
+bug_tag = ''
+html_last_updated_fmt = '%Y-%m-%d %H:%M'
# autodoc generation is a bit aggressive and a nuisance when doing heavy
# text edit cycles.
# The theme to use for HTML and HTML Help pages. Major themes that come with
# Sphinx are currently 'default' and 'sphinxdoc'.
-html_theme = 'default'
+if openstackdocstheme is not None:
+ html_theme = 'openstackdocs'
+else:
+ html_theme = 'default'
# Output file base name for HTML help builder.
htmlhelp_basename = '%sdoc' % project
--- /dev/null
+==============
+ Contributing
+==============
+
+Basic Details
+=============
+
+.. include:: ../../../CONTRIBUTING.rst
+
+Running the Tests for pbr
+=========================
+
+The testing system is based on a combination of `tox`_ and `testr`_. The canonical
+approach to running tests is to simply run the command ``tox``. This will
+create virtual environments, populate them with dependencies and run all of
+the tests that OpenStack CI systems run. Behind the scenes, tox is running
+``testr run --parallel``, but is set up such that you can supply any additional
+testr arguments that are needed to tox. For example, you can run:
+``tox -- --analyze-isolation`` to cause tox to tell testr to add
+``--analyze-isolation`` to its argument list.
+
+It is also possible to run the tests inside of a virtual environment
+you have created, or it is possible that you have all of the dependencies
+installed locally already. If you'd like to go this route, the requirements
+are listed in ``requirements.txt`` and the requirements for testing are in
+``test-requirements.txt``. Installing them via pip, for instance, is simply::
+
+ pip install -r requirements.txt -r test-requirements.txt
+
+In you go this route, you can interact with the testr command directly.
+Running ``testr run`` will run the entire test suite. ``testr run --parallel``
+will run it in parallel (this is the default incantation tox uses). More
+information about testr can be found at: http://wiki.openstack.org/testr
+
+.. _tox: http://tox.testrun.org/
+.. _testr: https://wiki.openstack.org/wiki/Testr
+++ /dev/null
-=================
- Release History
-=================
-
-.. include:: ../../ChangeLog
pbr - Python Build Reasonableness
=================================
-A library for managing setuptools packaging needs in a consistent manner.
+A library for managing *setuptools* packaging needs in a consistent manner.
-`pbr` reads and then filters the `setup.cfg` data through a setup hook to
-fill in default values and provide more sensible behaviors, and then feeds
-the results in as the arguments to a call to `setup.py` - so the heavy
-lifting of handling python packaging needs is still being done by
-`setuptools`.
+*pbr* reads and then filters the ``setup.cfg`` data through a setup hook to
+fill in default values and provide more sensible behaviors, and then feeds the
+results in as the arguments to a call to ``setup.py`` - so the heavy lifting of
+handling Python packaging needs is still being done by *setuptools*.
-Note that we don't support the `easy_install` aspects of setuptools: while
-we depend on setup_requires, for any install_requires we recommend that they
-be installed prior to running `setup.py install` - either by hand, or by using
-an install tool such as `pip`.
+Note that we don't support the ``easy_install`` aspects of *setuptools*: while
+we depend on ``setup_requires``, for any ``install_requires`` we recommend that
+they be installed prior to running ``setup.py install`` - either by hand, or by
+using an install tool such as *pip*.
-What It Does
-============
-
-PBR can and does do a bunch of things for you:
+*pbr* can and does do a bunch of things for you:
* **Version**: Manage version number based on git revisions and tags
* **AUTHORS**: Generate AUTHORS file from git log
* **ChangeLog**: Generate ChangeLog from git log
* **Manifest**: Generate a sensible manifest from git files and some standard
files
-* **Sphinx Autodoc**: Generate autodoc stub files for your whole module
* **Requirements**: Store your dependencies in a pip requirements file
* **long_description**: Use your README file as a long_description
* **Smart find_packages**: Smartly find packages under your root package
+* **Sphinx Autodoc**: Generate autodoc stub files for your whole module
-Version
--------
-
-Versions can be managed two ways - postversioning and preversioning.
-Postversioning is the default, and preversioning is enabled by setting
-``version`` in the setup.cfg ``metadata`` section. In both cases version
-strings are inferred from git.
-
-If the currently checked out revision is tagged, that tag is used as
-the version.
-
-If the currently checked out revision is not tagged, then we take the
-last tagged version number and increment it to get a minimum target
-version.
-
-We then walk git history back to the last release. Within each commit we look
-for a Sem-Ver: pseudo header, and if found parse it looking for keywords.
-Unknown symbols are not an error (so that folk can't wedge pbr or break their
-tree), but we will emit an info level warning message. Known symbols:
-``feature``, ``api-break``, ``deprecation``, ``bugfix``. A missing
-Sem-Ver line is equivalent to ``Sem-Ver: bugfix``. The ``bugfix`` symbol causes
-a patch level increment to the version. The ``feature`` and ``deprecation``
-symbols cause a minor version increment. The ``api-break`` symbol causes a
-major version increment.
-
-If postversioning is in use, we use the resulting version number as the target
-version.
-
-If preversioning is in use we check that the version set in the metadata
-section of `setup.cfg` is greater than the version we infer using the above
-method. If the inferred version is greater than the preversioning value we
-raise an error, otherwise we use the version from `setup.cfg` as the target.
-
-We then generate dev version strings based on the commits since the last
-release and include the current git sha to disambiguate multiple dev versions
-with the same number of commits since the release.
-
-.. note::
-
- `pbr` expects git tags to be signed for use in calculating versions
-
-The versions are expected to be compliant with :doc:`semver`.
-
-The ``version.SemanticVersion`` class can be used to query versions of a
-package and present it in various forms - ``debian_version()``,
-``release_string()``, ``rpm_string()``, ``version_string()``, or
-``version_tuple()``.
-
-AUTHORS and ChangeLog
----------------------
-
-Why keep an `AUTHORS` or a `ChangeLog` file when git already has all of the
-information you need? `AUTHORS` generation supports filtering/combining based
-on a standard `.mailmap` file.
-
-Manifest
---------
-
-Just like `AUTHORS` and `ChangeLog`, why keep a list of files you wish to
-include when you can find many of these in git. `MANIFEST.in` generation
-ensures almost all files stored in git, with the exception of `.gitignore`,
-`.gitreview` and `.pyc` files, are automatically included in your
-distribution. In addition, the generated `AUTHORS` and `ChangeLog` files are
-also included. In many cases, this removes the need for an explicit
-'MANIFEST.in' file
-
-Sphinx Autodoc
---------------
-
-Sphinx can produce auto documentation indexes based on signatures and
-docstrings of your project but you have to give it index files to tell it
-to autodoc each module: that's kind of repetitive and boring. PBR will scan
-your project, find all of your modules, and generate all of the stub files for
-you.
-
-Sphinx documentation setups are altered to generate man pages by default. They
-also have several pieces of information that are known to setup.py injected
-into the sphinx config.
-
-See the pbr_ section for details on configuring your project for autodoc.
-
-Requirements
-------------
-
-You may not have noticed, but there are differences in how pip
-`requirements.txt` files work and how distutils wants to be told about
-requirements. The pip way is nicer because it sure does make it easier to
-populate a virtualenv for testing or to just install everything you need.
-Duplicating the information, though, is super lame. To solve this issue, `pbr`
-will let you use `requirements.txt`-format files to describe the requirements
-for your project and will then parse these files, split them up appropriately,
-and inject them into the `install_requires`, `tests_require` and/or
-`dependency_links` arguments to `setup`. Voila!
-
-You can also have a requirement file for each specific major version of Python.
-If you want to have a different package list for Python 3 then just drop a
-`requirements-py3.txt` and it will be used instead.
-
-Finally, it is possible to specify groups of optional dependencies, or
-`"extra" requirements`_, in your `setup.cfg` rather than `setup.py`.
-
-long_description
-----------------
-
-There is no need to maintain two long descriptions- and your README file is
-probably a good long_description. So we'll just inject the contents of your
-README.rst, README.txt or README file into your empty long_description. Yay
-for you.
-
-Usage
-=====
-
-`pbr` is a setuptools plugin and so to use it you must use setuptools and call
-``setuptools.setup()``. While the normal setuptools facilities are available,
-pbr makes it possible to express them through static data files.
-
-.. _setup_py:
-
-setup.py
+Contents
--------
-`pbr` only requires a minimal `setup.py` file compared to a standard setuptools
-project. This is because most configuration is located in static configuration
-files. This recommended minimal `setup.py` file should look something like this::
-
- #!/usr/bin/env python
-
- from setuptools import setup
-
- setup(
- setup_requires=['pbr>=1.9', 'setuptools>=17.1'],
- pbr=True,
- )
-
-.. note::
-
- It is necessary to specify ``pbr=True`` to enabled `pbr` functionality.
-
-.. note::
-
- While one can pass any arguments supported by setuptools to `setup()`,
- any conflicting arguments supplied in `setup.cfg` will take precedence.
-
-setup.cfg
----------
-
-The `setup.cfg` file is an ini-like file that can mostly replace the `setup.py`
-file. It is based on the distutils2_ `setup.cfg` file. A simple sample can be
-found in `pbr`'s own `setup.cfg` (it uses its own machinery to install
-itself)::
-
- [metadata]
- name = pbr
- author = OpenStack Foundation
- author-email = openstack-dev@lists.openstack.org
- summary = OpenStack's setup automation in a reusable form
- description-file = README
- home-page = https://launchpad.net/pbr
- license = Apache-2
- classifier =
- Development Status :: 4 - Beta
- Environment :: Console
- Environment :: OpenStack
- Intended Audience :: Developers
- Intended Audience :: Information Technology
- License :: OSI Approved :: Apache Software License
- Operating System :: OS Independent
- Programming Language :: Python
- keywords =
- setup
- distutils
-
- [files]
- packages =
- pbr
- data_files =
- etc/pbr = etc/*
- etc/init =
- pbr.packaging.conf
- pbr.version.conf
-
- [entry_points]
- console_scripts =
- pbr = pbr.cmd:main
- pbr.config.drivers =
- plain = pbr.cfg.driver:Plain
-
-`pbr` provides its own section in these documents, ostensibly called ``pbr``,
-and provides a custom version of Sphinx's ``build_sphinx`` section. Most other
-sections are provided by setuptools and may influence either the build itself
-or the output of various `setuptools commands`__. The remaining sections are
-provided by libraries that provide setuptools extensions, such as
-``extract_mesages`` (provided by `Babel`__). Some of these are described below.
-
-__ https://setuptools.readthedocs.io/en/latest/setuptools.html#command-reference
-__ http://babel.pocoo.org/en/latest/setup.html
-__ http://www.sphinx-doc.org/en/stable/setuptools.html
-
-.. note::
-
- Comments may be used in `setup.cfg`, however all comments should start with
- a `#` and may be on a single line, or in line, with at least one white space
- character immediately preceding the `#`. Semicolons are not a supported
- comment delimiter. For instance::
-
- [section]
- # A comment at the start of a dedicated line
- key =
- value1 # An in line comment
- value2
- # A comment on a dedicated line
- value3
-
-files
-~~~~~
-
-The ``files`` section defines the install location of files in the package
-using three fundamental keys: ``packages``, ``namespace_packages``, and
-``data_files``.
-
-``packages``
-
- A list of top-level packages that should be installed. The behavior of
- packages is similar to ``setuptools.find_packages`` in that it recurses the
- python package hierarchy below the given top level and installs all of it. If
- ``packages`` is not specified, it defaults to the value of the ``name`` field
- given in the ``[metadata]`` section.
-
-``namespace_packages``
-
- Similar to ``packages``, but is a list of packages that provide namespace
- packages.
-
-``data_files``
-
- A list of files to be installed. The format is an indented block that
- contains key value pairs which specify target directory and source file to
- install there. More than one source file for a directory may be indicated
- with a further indented list. Source files are stripped of leading
- directories. Additionally, `pbr` supports a simple file globbing syntax for
- installing entire directory structures, thus::
-
- [files]
- data_files =
- etc/pbr = etc/pbr/*
- etc/neutron =
- etc/api-paste.ini
- etc/dhcp-agent.ini
- etc/init.d = neutron.init
-
- will result in `/etc/neutron` containing `api-paste.ini` and `dhcp-agent.ini`,
- both of which pbr will expect to find in the `etc` directory in the root of
- the source tree. Additionally, `neutron.init` from that dir will be installed
- in `/etc/init.d`. All of the files and directories located under `etc/pbr` in
- the source tree will be installed into `/etc/pbr`.
-
- Note that this behavior is relative to the effective root of the environment
- into which the packages are installed, so depending on available permissions
- this could be the actual system-wide `/etc` directory or just a top-level
- `etc` subdirectory of a virtualenv.
-
-pbr
-~~~
-
-The ``pbr`` section controls `pbr` specific options and behaviours.
-
-``autodoc_tree_index_modules``
-
- A boolean option controlling whether `pbr` should generate an index of
- modules using `sphinx-apidoc`. By default, all files except `setup.py` are
- included, but this can be overridden using the ``autodoc_tree_excludes``
- option.
-
-``autodoc_tree_excludes``
-
- A list of modules to exclude when building documentation using
- `sphinx-apidoc`. Defaults to ``[setup.py]``. Refer to the `sphinx-apidoc man
- page`_ for more information.
-
-``autodoc_index_modules``
-
- A boolean option controlling whether `pbr` should itself generates
- documentation for Python modules of the project. By default, all found Python
- modules are included; some of them can be excluded by listing them in
- ``autodoc_exclude_modules``.
-
-``autodoc_exclude_modules``
-
- A list of modules to exclude when building module documentation using `pbr`.
- `fnmatch` style pattern (e.g. `myapp.tests.*`) can be used.
-
-``api_doc_dir``
-
- A subdirectory inside the ``build_sphinx.source_dir`` where
- auto-generated API documentation should be written, if
- ``autodoc_index_modules`` is set to True. Defaults to ``"api"``.
-
-.. note::
-
- When using ``autodoc_tree_excludes`` or ``autodoc_index_modules`` you may
- also need to set ``exclude_patterns`` in your Sphinx configuration file
- (generally found at `doc/source/conf.py` in most OpenStack projects)
- otherwise Sphinx may complain about documents that are not in a toctree.
- This is especially true if the ``[sphinx_build] warning-is-error`` option is
- set. See the `Sphinx build configuration file`_ documentation for more
- information on configuring Sphinx.
-
-.. versionchanged:: 2.0
-
- The ``pbr`` section used to take a ``warnerrors`` option that would enable
- the ``-W`` (Turn warnings into errors.) option when building Sphinx. This
- feature was broken in 1.10 and was removed in pbr 2.0 in favour of the
- ``[build_sphinx] warning-is-error`` provided in Sphinx 1.5+.
-
-build_sphinx
-~~~~~~~~~~~~
-
-The ``build_sphinx`` section is a version of the ``build_sphinx`` setuptools
-plugin provided with Sphinx. This plugin extends the original plugin to add the
-following:
-
-- Automatic generation of module documentation using the apidoc__ tool
-
-- Automatic configuration of the `project`, `version` and `release` settings
- using information from `pbr` itself
-
-- Support for multiple builders using the ``builders`` configuration option
-
- .. note::
-
- Sphinx 1.6 adds support for multiple builders using the default `builder`
- option. You should refer to this file for more information.
-
-The version of ``build_sphinx`` provided by `pbr` provides a single additional
-option.
-
-``builders``
-
- A space or comma separated list of builders to run. For example, to build
- both HTML and man page documentation, you would define the following in your
- `setup.cfg`:
-
- .. code-block:: ini
-
- [build_sphinx]
- builders = html,man
- source-dir = doc/source
- build-dir = doc/build
- all-files = 1
-
-``source_dir``
-
- The path to the source directory where the Sphinx documentation tree
- is.
-
-For information on the remaining options, refer to the `Sphinx
-documentation`__. In addition, the ``autodoc_index_modules``,
-``autodoc_tree_index_modules``, ``autodoc_exclude_modules`` and
-``autodoc_tree_excludes`` options in the ``pbr`` section will affect the output
-of the automatic module documentation generation.
-
-.. versionchanged:: 3.0
-
- The ``build_sphinx`` plugin used to default to building both HTML and man
- page output. This is no longer the case, and you should explicitly set
- ``builders`` to ``html man`` if you wish to retain this behavior.
-
-__ http://www.sphinx-doc.org/en/stable/man/sphinx-apidoc.html
-__ http://www.sphinx-doc.org/en/stable/setuptools.html
-
-entry_points
-~~~~~~~~~~~~
-
-The ``entry_points`` section defines entry points for generated console scripts
-and python libraries. This is actually provided by `setuptools`__ but is
-documented here owing to its importance.
-
-The general syntax of specifying entry points is a top level name indicating
-the entry point group name, followed by one or more key value pairs naming
-the entry point to be installed. For instance::
-
- [entry_points]
- console_scripts =
- pbr = pbr.cmd:main
- pbr.config.drivers =
- plain = pbr.cfg.driver:Plain
- fancy = pbr.cfg.driver:Fancy
-
-Will cause a console script called `pbr` to be installed that executes the
-`main` function found in `pbr.cmd`. Additionally, two entry points will be
-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`.
-
-__ https://setuptools.readthedocs.io/en/latest/setuptools.html#options
-
-Requirements
-------------
-
-Requirement files should be given one of the below names. This order is also
-the order that the requirements are tried in (where `N` is the Python major
-version number used to install the package):
-
-* requirements-pyN.txt
-* tools/pip-requires-py3
-* requirements.txt
-* tools/pip-requires
-
-Only the first file found is used to install the list of packages it contains.
-
-.. note::
-
- The 'requirements-pyN.txt' file is deprecated - 'requirements.txt' should
- be universal. You can use `Environment markers`_ for this purpose.
-
-Extra requirements
-~~~~~~~~~~~~~~~~~~
-
-Groups of optional dependencies, or `"extra" requirements`_, 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`_ 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 defined in `setup.cfg`,
-but the format is slightly different for each.
-
-For ``requirements.txt``::
-
- argparse; python_version=='2.6'
-
-This will result in the package depending on ``argparse`` only if it's being
-installed into Python 2.6
-
-For extras specified 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_version=='3.2'
- gimel:python_version=='2.7'
- testing =
- quux:python_version=='2.7'
-
-
-Testing
--------
-
-`pbr` overrides the ``setuptools`` hook ``test`` (i.e. ``setup.py test``). The
-following sequence is followed:
-
-#. If a ``.testr.conf`` file exists and `testrepository
- <https://pypi.python.org/pypi/testrepository>`__ is installed, `pbr`
- will use it as the test runner. See the ``testr`` documentation
- for more details.
-
- .. note::
-
- This is separate to ``setup.py testr`` (note the extra ``r``) which
- is provided directly by the ``testrepository`` package. Be careful
- as there is some overlap of command arguments.
-
-#. Although deprecated, if ``[nosetests]`` is defined in ``setup.cfg``
- and `nose <http://nose.readthedocs.io/en/latest/>`__ is installed,
- the ``nose`` runner will be used.
-
-#. In other cases no override will be installed and the ``test``
- command will revert to `setuptools
- <http://setuptools.readthedocs.io/en/latest/setuptools.html#test-build-package-and-run-a-unittest-suite>`__.
-
-A typical usage would be in ``tox.ini`` such as::
-
- [tox]
- minversion = 2.0
- skipsdist = True
- envlist = py33,py34,py35,py26,py27,pypy,pep8,docs
-
- [testenv]
- usedevelop = True
- setenv =
- VIRTUAL_ENV={envdir}
- CLIENT_NAME=pbr
- deps = .
- -r{toxinidir}/test-requirements.txt
- commands =
- python setup.py test --testr-args='{posargs}'
-
-The argument ``--coverage`` will set ``PYTHON`` to ``coverage run`` to
-produce a coverage report. ``--coverage-package-name`` can be used to
-modify or narrow the packages traced.
-
-Additional Docs
-===============
-
.. toctree::
- :maxdepth: 1
-
- packagers
- semver
- testing
- compatibility
- api/modules
- history
-
-Indices and tables
-==================
-
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
+ :maxdepth: 2
-.. _"extra" requirements:
- https://www.python.org/dev/peps/pep-0426/#extras-optional-dependencies
-.. _conditional dependencies:
- https://www.python.org/dev/peps/pep-0426/#environment-markers
-.. _distutils2: http://alexis.notmyidea.org/distutils2/setupcfg.html
-.. _sphinx-apidoc man page: http://sphinx-doc.org/man/sphinx-apidoc.html
-.. _Sphinx build configuration file: http://sphinx-doc.org/config.html
+ user/index
+ reference/index
+ contributor/index
+++ /dev/null
-===============================
- Notes for Package maintainers
-===============================
-
-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 package maintainers
-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.
-
-Distribution version numbers
-============================
-
-`pbr` will automatically calculate upstream version numbers for dpkg and rpm
-using systems. Releases are easy (and obvious). When packaging preleases though
-things get more complex. Firstly, semver does not provide for any sort order
-between pre-releases and development snapshots, so it can be complex (perhaps
-intractable) to package both into one repository - we recommend with either
-packaging pre-release releases (alpha/beta/rc's) or dev snapshots but not both.
-Secondly, as pre-releases and snapshots have the same major/minor/patch version
-as the version they lead up to, but have to sort before it, we cannot map their
-version naturally into the rpm version namespace: instead we represent their
-versions as versions of the release before.
-
-Dependencies
-============
-
-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.
-
-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
-========
-
-`pbr` includes everything in a source tarball that is in the original `git`
-repository. This can again cause havoc if a package maintainer 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.
-
-AUTHORS and ChangeLog
-=====================
-
-`pbr` generates AUTHORS and ChangeLog files from git information. This
-can cause problem in distro packaging if package maintainer is using git
-repository for packaging source. If that is the case setting
-`SKIP_GENERATE_AUTHORS`
-
-::
-
- SKIP_GENERATE_AUTHORS=1
-
-will cause logic around generating AUTHORS using git information to be
-skipped. Similarly setting `SKIP_WRITE_GIT_CHANGELOG`
-
-::
-
- SKIP_WRITE_GIT_CHANGELOG=1
-
-will cause logic around generating ChangeLog file using git
-information to be skipped.
--- /dev/null
+===================
+ pbr API Reference
+===================
+
+.. toctree::
+ :glob:
+
+ api/*
+++ /dev/null
-Linux/Python Compatible Semantic Versioning 3.0.0
-=================================================
-
-This is a fork of Semantic Versioning 2.0. The specific changes have to do
-with the format of pre-release and build labels, specifically to make them
-not confusing when co-existing with Linux distribution packaging and Python
-packaging. Inspiration for the format of the pre-release and build labels
-came from Python's PEP440.
-
-Changes vs SemVer 2.0
----------------------
-
-#. dev versions are defined. These are extremely useful when
- dealing with CI and CD systems when 'every commit is a release' is not
- feasible.
-
-#. All versions have been made PEP-440 compatible, because of our deep
- roots in Python. Pre-release versions are now separated by . not -, and
- use a/b/c rather than alpha/beta etc.
-
-Summary
--------
-
-Given a version number MAJOR.MINOR.PATCH,
-increment the:
-
-#. MAJOR version when you make incompatible API changes,
-#. MINOR version when you add functionality in a backwards-compatible
- manner, and
-#. PATCH version when you make backwards-compatible bug fixes.
-
-Introduction
-------------
-
-In the world of software management there exists a dread place called
-"dependency hell." The bigger your system grows and the more packages
-you integrate into your software, the more likely you are to find
-yourself, one day, in this pit of despair.
-
-In systems with many dependencies, releasing new package versions can
-quickly become a nightmare. If the dependency specifications are too
-tight, you are in danger of version lock (the inability to upgrade a
-package without having to release new versions of every dependent
-package). If dependencies are specified too loosely, you will inevitably
-be bitten by version promiscuity (assuming compatibility with more
-future versions than is reasonable). Dependency hell is where you are
-when version lock and/or version promiscuity prevent you from easily and
-safely moving your project forward.
-
-As a solution to this problem, I propose a simple set of rules and
-requirements that dictate how version numbers are assigned and
-incremented. These rules are based on but not necessarily limited to
-pre-existing widespread common practices in use in both closed and
-open-source software. For this system to work, you first need to declare
-a public API. This may consist of documentation or be enforced by the
-code itself. Regardless, it is important that this API be clear and
-precise. Once you identify your public API, you communicate changes to
-it with specific increments to your version number. Consider a version
-format of X.Y.Z (Major.Minor.Patch). Bug fixes not affecting the API
-increment the patch version, backwards compatible API additions/changes
-increment the minor version, and backwards incompatible API changes
-increment the major version.
-
-I call this system "Semantic Versioning." Under this scheme, version
-numbers and the way they change convey meaning about the underlying code
-and what has been modified from one version to the next.
-
-Semantic Versioning Specification (SemVer)
-------------------------------------------
-
-The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
-"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
-document are to be interpreted as described in `RFC
-2119 <http://tools.ietf.org/html/rfc2119>`__.
-
-#. Software using Semantic Versioning MUST declare a public API. This
- API could be declared in the code itself or exist strictly in
- documentation. However it is done, it should be precise and
- comprehensive.
-
-#. A normal version number MUST take the form X.Y.Z where X, Y, and Z
- are non-negative integers, and MUST NOT contain leading zeroes. X is
- the major version, Y is the minor version, and Z is the patch
- version. Each element MUST increase numerically. For instance: 1.9.0
- -> 1.10.0 -> 1.11.0.
-
-#. Once a versioned package has been released, the contents of that
- version MUST NOT be modified. Any modifications MUST be released as
- a new version.
-
-#. Major version zero (0.y.z) is for initial development. Anything may
- change at any time. The public API should not be considered stable.
-
-#. Version 1.0.0 defines the public API. The way in which the version
- number is incremented after this release is dependent on this public
- API and how it changes.
-
-#. Patch version Z (x.y.Z \| x > 0) MUST be incremented if only
- backwards compatible bug fixes are introduced. A bug fix is defined
- as an internal change that fixes incorrect behavior.
-
-#. Minor version Y (x.Y.z \| x > 0) MUST be incremented if new,
- backwards compatible functionality is introduced to the public API.
- It MUST be incremented if any public API functionality is marked as
- deprecated. It MAY be incremented if substantial new functionality
- or improvements are introduced within the private code. It MAY
- include patch level changes. Patch version MUST be reset to 0 when
- minor version is incremented.
-
-#. Major version X (X.y.z \| X > 0) MUST be incremented if any
- backwards incompatible changes are introduced to the public API. It
- MAY also include minor and patch level changes. Patch and minor
- version MUST be reset to 0 when major version is incremented.
-
-#. A pre-release version MAY be denoted by appending a dot
- separated identifier immediately following the patch version.
- The identifier MUST comprise only a, b, c followed by non-negative
- integer value. The identifier MUST NOT be empty.
- Pre-release versions have a lower precedence than the associated normal
- version. A pre-release version indicates that
- the version is unstable and might not satisfy the intended
- compatibility requirements as denoted by its associated normal
- version. Examples: 1.0.0.a1, 1.0.0.b99, 1.0.0.c1000.
-
-#. A development version MAY be denoted by appending a dot separated
- identifier immediately following the patch version.
- The identifier MUST comprise the string dev followed by non-negative
- integer value. The identifier MUST NOT be empty. Development versions
- have a lower precedence than the associated normal version or pre-release
- version. A development version is a completely unsupported and conveys no
- API promises when related to other versions. They are more useful as
- communication vehicles between developers of a community, whereas
- pre-releases, while potentially prone to break still, are intended for
- externally facing communication of not-yet-released ideas. Dev versions
- are not public artifacts and should never be placed in public
- repositories: they are intended as developer-local resources. Examples:
- 1.0.0.dev1, 1.0.0.a1.dev1
-
-#. git version metadata MAY be denoted by appending a dot separated
- identifier immediately following a development or pre-release version.
- The identifier MUST comprise the character g followed by a seven
- character git short-sha. The sha MUST NOT be empty. git version
- metadata MUST be ignored when determining version precedence. Thus
- two versions that differ only in the git version, have the same
- precedence. Example: 1.0.0.a1.g95a9beb.
-
-#. Build metadata MAY be denoted by appending a plus sign and a series
- of dot separated identifiers immediately following the patch or
- pre-release version. Identifiers MUST comprise only ASCII
- alphanumerics [0-9A-Za-z]. Identifiers MUST NOT be empty. Build
- metadata MUST be ignored when determining version precedence. Thus
- two versions that differ only in the build metadata, have the same
- precedence. Examples: 1.0.0.a1+001, 1.0.0+20130313144700,
- 1.0.0.b1+exp.sha.5114f85.
-
-#. Precedence refers to how versions are compared to each other when
- ordered. Precedence MUST be calculated by separating the version
- into major, minor, patch, pre-release, and development identifiers in
- that order (Build metadata does not figure into precedence). Precedence
- is determined by the first difference when comparing each of these
- identifiers from left to right as follows: Major, minor, and patch
- versions are always compared numerically. Example: 1.0.0 < 2.0.0 <
- 2.1.0 < 2.1.1. When major, minor, and patch are equal, a pre-release
- version has lower precedence than a normal version. Example:
- 1.0.0.a1 < 1.0.0. When major, minor, patch and pre-release are equal, a
- development version has a lower precedence than a normal version and of a
- pre-release version. Example: 1.0.0.dev1 < 1.0.0 and 1.0.0.dev9 <
- 1.0.0.a1 and 1.0.0.a1 < 1.0.0.a2.dev4. Precedence for two pre-release
- versions with the same major, minor, and patch version MUST be determined
- by comparing the identifier to the right of the patch version as follows:
- if the alpha portion matches, the numeric portion is compared in
- numerical sort order. If the alpha portion does not match, the sort order
- is dev < a < b < c. Example: 1.0.0.dev8 < 1.0.0.dev9 < 1.0.0.a1.dev3 <
- 1.0.0.a1 < 1.0.0.b2 < 1.0.0.c1 < 1.0.0. Precedence for dev versions if
- all other components are equal is done by comparing their numeric
- component. If all other components are not equal, predence is determined
- by comparing the other components.
-
-Why Use Semantic Versioning?
-----------------------------
-
-This is not a new or revolutionary idea. In fact, you probably do
-something close to this already. The problem is that "close" isn't good
-enough. Without compliance to some sort of formal specification, version
-numbers are essentially useless for dependency management. By giving a
-name and clear definition to the above ideas, it becomes easy to
-communicate your intentions to the users of your software. Once these
-intentions are clear, flexible (but not too flexible) dependency
-specifications can finally be made.
-
-A simple example will demonstrate how Semantic Versioning can make
-dependency hell a thing of the past. Consider a library called
-"Firetruck." It requires a Semantically Versioned package named
-"Ladder." At the time that Firetruck is created, Ladder is at version
-3.1.0. Since Firetruck uses some functionality that was first introduced
-in 3.1.0, you can safely specify the Ladder dependency as greater than
-or equal to 3.1.0 but less than 4.0.0. Now, when Ladder version 3.1.1
-and 3.2.0 become available, you can release them to your package
-management system and know that they will be compatible with existing
-dependent software.
-
-As a responsible developer you will, of course, want to verify that any
-package upgrades function as advertised. The real world is a messy
-place; there's nothing we can do about that but be vigilant. What you
-can do is let Semantic Versioning provide you with a sane way to release
-and upgrade packages without having to roll new versions of dependent
-packages, saving you time and hassle.
-
-If all of this sounds desirable, all you need to do to start using
-Semantic Versioning is to declare that you are doing so and then follow
-the rules. Link to this website from your README so others know the
-rules and can benefit from them.
-
-FAQ
----
-
-How should I deal with revisions in the 0.y.z initial development phase?
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The simplest thing to do is start your initial development release at
-0.1.0 and then increment the minor version for each subsequent release.
-
-How do I know when to release 1.0.0?
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-If your software is being used in production, it should probably already
-be 1.0.0. If you have a stable API on which users have come to depend,
-you should be 1.0.0. If you're worrying a lot about backwards
-compatibility, you should probably already be 1.0.0.
-
-Doesn't this discourage rapid development and fast iteration?
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Major version zero is all about rapid development. If you're changing
-the API every day you should either still be in version 0.y.z or on a
-separate development branch working on the next major version.
-
-If even the tiniest backwards incompatible changes to the public API require a major version bump, won't I end up at version 42.0.0 very rapidly?
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-This is a question of responsible development and foresight.
-Incompatible changes should not be introduced lightly to software that
-has a lot of dependent code. The cost that must be incurred to upgrade
-can be significant. Having to bump major versions to release
-incompatible changes means you'll think through the impact of your
-changes, and evaluate the cost/benefit ratio involved.
-
-Documenting the entire public API is too much work!
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-It is your responsibility as a professional developer to properly
-document software that is intended for use by others. Managing software
-complexity is a hugely important part of keeping a project efficient,
-and that's hard to do if nobody knows how to use your software, or what
-methods are safe to call. In the long run, Semantic Versioning, and the
-insistence on a well defined public API can keep everyone and everything
-running smoothly.
-
-What do I do if I accidentally release a backwards incompatible change as a minor version?
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-As soon as you realize that you've broken the Semantic Versioning spec,
-fix the problem and release a new minor version that corrects the
-problem and restores backwards compatibility. Even under this
-circumstance, it is unacceptable to modify versioned releases. If it's
-appropriate, document the offending version and inform your users of the
-problem so that they are aware of the offending version.
-
-What should I do if I update my own dependencies without changing the public API?
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-That would be considered compatible since it does not affect the public
-API. Software that explicitly depends on the same dependencies as your
-package should have their own dependency specifications and the author
-will notice any conflicts. Determining whether the change is a patch
-level or minor level modification depends on whether you updated your
-dependencies in order to fix a bug or introduce new functionality. I
-would usually expect additional code for the latter instance, in which
-case it's obviously a minor level increment.
-
-What if I inadvertently alter the public API in a way that is not compliant with the version number change (i.e. the code incorrectly introduces a major breaking change in a patch release)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Use your best judgment. If you have a huge audience that will be
-drastically impacted by changing the behavior back to what the public
-API intended, then it may be best to perform a major version release,
-even though the fix could strictly be considered a patch release.
-Remember, Semantic Versioning is all about conveying meaning by how the
-version number changes. If these changes are important to your users,
-use the version number to inform them.
-
-How should I handle deprecating functionality?
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Deprecating existing functionality is a normal part of software
-development and is often required to make forward progress. When you
-deprecate part of your public API, you should do two things: (1) update
-your documentation to let users know about the change, (2) issue a new
-minor release with the deprecation in place. Before you completely
-remove the functionality in a new major release there should be at least
-one minor release that contains the deprecation so that users can
-smoothly transition to the new API.
-
-Does SemVer have a size limit on the version string?
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-No, but use good judgment. A 255 character version string is probably
-overkill, for example. Also, specific systems may impose their own
-limits on the size of the string.
-
-About
------
-
-The Linux/Python Compatible Semantic Versioning specification is maintained
-by the `OpenStack <http://openstack.org>`_ project.
-
-It is based on The Semantic Versioning specification, which was
-authored by `Tom Preston-Werner <http://tom.preston-werner.com>`__,
-with inputs from `PEP 440 <http://www.python.org/dev/peps/pep-0440/>`_
-
-If you'd like to leave feedback, please `open an issue
-<https://bugs.launchpad.net/pbr/+filebug>`_.
-
-License
--------
-
-Creative Commons - CC BY 3.0 http://creativecommons.org/licenses/by/3.0/
+++ /dev/null
-Running the Tests for pbr
-=========================
-
-The testing system is based on a combination of `tox`_ and `testr`_. The canonical
-approach to running tests is to simply run the command ``tox``. This will
-create virtual environments, populate them with dependencies and run all of
-the tests that OpenStack CI systems run. Behind the scenes, tox is running
-``testr run --parallel``, but is set up such that you can supply any additional
-testr arguments that are needed to tox. For example, you can run:
-``tox -- --analyze-isolation`` to cause tox to tell testr to add
-``--analyze-isolation`` to its argument list.
-
-It is also possible to run the tests inside of a virtual environment
-you have created, or it is possible that you have all of the dependencies
-installed locally already. If you'd like to go this route, the requirements
-are listed in ``requirements.txt`` and the requirements for testing are in
-``test-requirements.txt``. Installing them via pip, for instance, is simply::
-
- pip install -r requirements.txt -r test-requirements.txt
-
-In you go this route, you can interact with the testr command directly.
-Running ``testr run`` will run the entire test suite. ``testr run --parallel``
-will run it in parallel (this is the default incantation tox uses). More
-information about testr can be found at: http://wiki.openstack.org/testr
-
-.. _tox: http://tox.testrun.org/
-.. _testr: https://wiki.openstack.org/wiki/Testr
--- /dev/null
+..
+ The name of this document and the anchor in this document must be
+ treated as a stable API. Links to this document are coded into
+ pbr and deployed versions of pbr will refer users to this document
+ in the case of certain errors.
+ Ensure any link you use in PBR is defined via a ref with .. _name.
+
+
+===================
+Compatibility Notes
+===================
+
+Useful notes about errors users may encounter when features cannot be
+supported on older versions of setuptools / pip / wheel.
+
+
+setuptools
+==========
+
+
+.. _evaluate-marker:
+
+evaluate_marker
+---------------
+
+evaluate_markers may run into issues with the '>', '>=', '<', and '<='
+operators if the installed version of setuptools is less than 17.1. Projects
+using these operators with markers should specify a minimum version of 17.1
+for setuptools.
+
+
+pip
+===
+
+markers
+-------
+
+For versions of pip < 7 with pbr < 1.9, dependencies that use markers will not
+be installed. Projects using pbr and markers should set a minimum version of
+1.9 for pbr.
+
+
+Recommended setup.py
+====================
+
+:ref:`setup_py`.
+
+
+Sphinx
+======
+
+.. _sphinx-1.5:
+
+Version 1.5.0+
+--------------
+
+The ``warning-is-error`` flag is only supported by Sphinx 1.5 and will cause
+errors when used with older versions.
--- /dev/null
+==========
+ Features
+==========
+
+To understand what *pbr* can do for you, it's probably best to look at two
+projects: one using pure *setuptools*, and another using *pbr*. First, let's
+look at the *setuptools* project.
+
+.. code-block:: none
+
+ $ tree -L 1
+ .
+ ├── AUTHORS
+ ├── CHANGES
+ ├── LICENSE
+ ├── MANIFEST.in
+ ├── README.rst
+ ├── requirements.txt
+ ├── setup.cfg
+ ├── setup.py
+ └── somepackage
+
+ $ cat setup.py
+ setuptools.setup(
+ name='mypackage',
+ version='1.0.0',
+ description='A short description',
+ long_description="""A much longer description...""",
+ author="John Doe",
+ author_email='john.doe@example.com',
+ license='BSD',
+ )
+
+Here's a similar package using *pbr*:
+
+.. code-block:: none
+
+ $ tree -L 1
+ .
+ ├── LICENSE
+ ├── README.rst
+ ├── setup.cfg
+ ├── setup.py
+ └── somepackage
+
+ $ cat setup.py
+ setuptools.setup(
+ pbr=True
+ )
+
+ $ cat setup.cfg
+ [metadata]
+ name = mypackage
+ description = A short description
+ description-file = README.rst
+ author = John Doe
+ author-email = john.doe@example.com
+ license = BSD
+
+From this, we note a couple of the main features of *pbr*:
+
+- Extensive use of ``setup.cfg`` for configuration
+- Automatic package metadata generation (``version``)
+- Automatic metadata file generation (``AUTHOR``, ``ChangeLog``,
+ ``MANIFEST.in``)
+
+In addition, there are other things that you don't see here but which *pbr*
+will do for you:
+
+- Helpful extensions to *setuptools* commands
+
+setup.cfg
+---------
+
+.. admonition:: Summary
+
+ *pbr* uses ``setup.cfg`` for all configuration, though ``setup.py`` is
+ still required.
+
+One of the main features of *distutils2* was the use of a ``setup.cfg``
+INI-style configuration file. This was used to define a package's metadata and
+other options that were normally supplied to the ``setup()`` function.
+
+Recent versions of `setuptools`__ have implemented some of this support, but
+*pbr* still allows for the definition of the following sections in
+``setup.cfg``:
+
+- ``files``
+- ``entry_points``
+- ``backwards_compat``
+
+For more information on these sections, refer to :doc:`/user/using`.
+
+__ https://setuptools.readthedocs.io/en/latest/setuptools.html#configuring-setup-using-setup-cfg-files
+
+Package Metadata
+----------------
+
+.. admonition:: Summary
+
+ *pbr* removes the need to define a lot of configuration in either
+ ``setup.py`` or ``setup.cfg`` by extracting this information from Git.
+
+Version
+~~~~~~~
+
+.. admonition:: Summary
+
+ *pbr* will automatically configure your version for you by parsing
+ semantically-versioned Git tags.
+
+Versions can be managed two ways - *post-versioning* and *pre-versioning*.
+*Post-versioning* is the default while *pre-versioning* is enabled by setting
+``version`` in the ``setup.cfg`` ``metadata`` section. In both cases the actual
+version strings are inferred from Git.
+
+If the currently checked out revision is tagged, that tag is used as
+the version.
+
+If the currently checked out revision is not tagged, then we take the
+last tagged version number and increment it to get a minimum target
+version.
+
+.. note::
+
+ *pbr* supports both bare version tag (e.g. ``0.1.0``) and version prefixed
+ with ``v`` or ``V`` (e.g. ``v0.1.0``)
+
+We then walk Git history back to the last release. Within each commit we look
+for a ``Sem-Ver:`` pseudo header and, if found, parse it looking for keywords.
+Unknown symbols are not an error (so that folk can't wedge *pbr* or break their
+tree), but we will emit an info-level warning message. The following symbols
+are recognized:
+
+- ``feature``
+- ``api-break``
+- ``deprecation``
+- ``bugfix``
+
+A missing ``Sem-Ver`` line is equivalent to ``Sem-Ver: bugfix``. The ``bugfix``
+symbol causes a patch level increment to the version. The ``feature`` and
+``deprecation`` symbols cause a minor version increment. The ``api-break``
+symbol causes a major version increment.
+
+If *post-versioning* is in use, we use the resulting version number as the target
+version.
+
+If *pre-versioning* is in use, we check that the version set in the metadata
+section of ``setup.cfg`` is greater than the version we infer using the above
+method. If the inferred version is greater than the *pre-versioning* value we
+raise an error, otherwise we use the version from ``setup.cfg`` as the target.
+
+We then generate dev version strings based on the commits since the last
+release and include the current Git SHA to disambiguate multiple dev versions
+with the same number of commits since the release.
+
+.. note::
+
+ *pbr* expects Git tags to be signed for use in calculating versions.
+
+The versions are expected to be compliant with :doc:`semver`.
+
+The ``version.SemanticVersion`` class can be used to query versions of a
+package and present it in various forms - ``debian_version()``,
+``release_string()``, ``rpm_string()``, ``version_string()``, or
+``version_tuple()``.
+
+Long Description
+~~~~~~~~~~~~~~~~
+
+.. admonition:: Summary
+
+ *pbr* can extract the contents of a ``README`` and use this as your long
+ description
+
+There is no need to maintain two long descriptions and your ``README`` file is
+probably a good long_description. So we'll just inject the contents of your
+``README.rst``, ``README.txt`` or ``README`` file into your empty
+``long_description``.
+
+You can also specify the exact file you want to use using the
+``description-file`` parameter.
+
+Requirements
+~~~~~~~~~~~~
+
+.. admonition:: Summary
+
+ *pbr* will extract requirements from ``requirements.txt`` files and
+ automatically populate the ``install_requires``, ``tests_require`` and
+ ``dependency_links`` arguments to ``setup`` with them.
+
+You may not have noticed, but there are differences in how pip
+``requirements.txt`` files work and how *setuptools* wants to be told about
+requirements. The *pip* way is nicer because it sure does make it easier to
+populate a *virtualenv* for testing or to just install everything you need.
+Duplicating the information, though, is super lame. To solve this issue, *pbr*
+will let you use ``requirements.txt``-format files to describe the requirements
+for your project and will then parse these files, split them up appropriately,
+and inject them into the ``install_requires``, ``tests_require`` and/or
+``dependency_links`` arguments to ``setup``. Voila!
+
+You can also have a requirement file for each specific major version of Python.
+If you want to have a different package list for Python 3 then just drop a
+``requirements-py3.txt`` and it will be used instead.
+
+Finally, it is possible to specify groups of optional dependencies, or
+:ref:`"extra" requirements <extra-requirements>`, in your ``setup.cfg`` rather
+than ``setup.py``.
+
+Automatic File Generation
+-------------------------
+
+.. admonition:: Summary
+
+ *pbr* can automatically generate a couple of files, which would normally
+ have to be maintained manually, by using Git data.
+
+AUTHORS, ChangeLog
+~~~~~~~~~~~~~~~~~~
+
+.. admonition:: Summary
+
+ *pbr* will automatically generate an ``AUTHORS`` and a ``ChangeLog`` file
+ using Git logs.
+
+Why keep an ``AUTHORS`` or a ``ChangeLog`` file when Git already has all of the
+information you need? ``AUTHORS`` generation supports filtering/combining based
+on a standard ``.mailmap`` file.
+
+Manifest
+~~~~~~~~
+
+.. admonition:: Summary
+
+ *pbr* will automatically generate a ``MANIFEST.in`` file based on the files
+ Git is tracking.
+
+Just like ``AUTHORS`` and ``ChangeLog``, why keep a list of files you wish to
+include when you can find many of these in Git. ``MANIFEST.in`` generation
+ensures almost all files stored in Git, with the exception of ``.gitignore``,
+``.gitreview`` and ``.pyc`` files, are automatically included in your
+distribution. In addition, the generated ``AUTHORS`` and ``ChangeLog`` files
+are also included. In many cases, this removes the need for an explicit
+``MANIFEST.in`` file, though one can be provided to exclude files that are
+tracked via Git but which should not be included in the final release, such as
+test files.
+
+.. note::
+
+ ``MANIFEST.in`` files have no effect on binary distributions such as wheels.
+ Refer to the `Python packaging tutorial`__ for more information.
+
+__ https://packaging.python.org/tutorials/distributing-packages/#manifest-in
+
+Setup Commands
+--------------
+
+``build_sphinx``
+~~~~~~~~~~~~~~~~
+
+.. admonition:: Summary
+
+ *pbr* will override the Sphinx ``build_sphinx`` command to use
+ *pbr*-provided package metadata and automatically generate API
+ documentation.
+
+Sphinx can produce auto documentation indexes based on signatures and
+docstrings of your project but you have to give it index files to tell it to
+*autodoc* each module: that's kind of repetitive and boring. *pbr* will scan
+your project, find all of your modules, and generate all of the stub files for
+you.
+
+In addition, Sphinx documentation setups are altered to have several pieces of
+information that are known to ``setup.py`` injected into the Sphinx config.
+
+See the :ref:`pbr-setup-cfg` section of the configuration file for
+details on configuring your project for *autodoc*.
+
+``test``
+~~~~~~~~
+
+.. admonition:: Summary
+
+ *pbr* will automatically alias the ``test`` command to use the testing tool
+ of your choice.
+
+.. deprecated:: 4.0
+
+*pbr* overrides the *setuptools* ``test`` command if using `testrepository`__
+or `nose`__ (deprecated).
+
+- *pbr* will check for a ``.testr.conf`` file. If this exists and
+ *testrepository* is installed, the ``test`` command will alias the *testr*
+ test runner. If this is not the case...
+
+ .. note::
+
+ This is separate to ``setup.py testr`` (note the extra ``r``) which is
+ provided directly by the ``testrepository`` package. Be careful as there is
+ some overlap of command arguments.
+
+- *pbr* will check if ``[nosetests]`` is defined in ``setup.cfg``. If this
+ exists and *nose* is installed, the ``test`` command will alias the *nose*
+ runner. If this is not the case...
+
+- In other cases no override will be installed and the ``test`` command will
+ revert to the `setuptools default`__.
+
+__ https://testrepository.readthedocs.io/en/latest/
+__ https://nose.readthedocs.io/en/latest/
+__ https://setuptools.readthedocs.io/en/latest/setuptools.html#test-build-package-and-run-a-unittest-suite
--- /dev/null
+=================
+ Release History
+=================
+
+.. include:: ../../../ChangeLog
--- /dev/null
+===========
+ Using pbr
+===========
+
+.. toctree::
+
+ features
+ using
+ packagers
+ semver
+ compatibility
+ history
--- /dev/null
+===============================
+ Notes for Package maintainers
+===============================
+
+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 package maintainers
+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`:
+
+::
+
+ export PBR_VERSION=1.2.3
+
+and all version calculation logic will be completely skipped and the supplied
+version will be considered absolute.
+
+Distribution version numbers
+============================
+
+`pbr` will automatically calculate upstream version numbers for dpkg and rpm
+using systems. Releases are easy (and obvious). When packaging preleases though
+things get more complex. Firstly, semver does not provide for any sort order
+between pre-releases and development snapshots, so it can be complex (perhaps
+intractable) to package both into one repository - we recommend with either
+packaging pre-release releases (alpha/beta/rc's) or dev snapshots but not both.
+Secondly, as pre-releases and snapshots have the same major/minor/patch version
+as the version they lead up to, but have to sort before it, we cannot map their
+version naturally into the rpm version namespace: instead we represent their
+versions as versions of the release before.
+
+Dependencies
+============
+
+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.
+
+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
+========
+
+`pbr` includes everything in a source tarball that is in the original `git`
+repository. This can again cause havoc if a package maintainer 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`:
+
+::
+
+ export 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.
+
+AUTHORS and ChangeLog
+=====================
+
+`pbr` generates AUTHORS and ChangeLog files from git information. This
+can cause problem in distro packaging if package maintainer is using git
+repository for packaging source. If that is the case setting
+`SKIP_GENERATE_AUTHORS`
+
+::
+
+ export SKIP_GENERATE_AUTHORS=1
+
+will cause logic around generating AUTHORS using git information to be
+skipped. Similarly setting `SKIP_WRITE_GIT_CHANGELOG`
+
+::
+
+ export SKIP_WRITE_GIT_CHANGELOG=1
+
+will cause logic around generating ChangeLog file using git
+information to be skipped.
--- /dev/null
+Linux/Python Compatible Semantic Versioning 3.0.0
+=================================================
+
+This is a fork of Semantic Versioning 2.0. The specific changes have to do
+with the format of pre-release and build labels, specifically to make them
+not confusing when co-existing with Linux distribution packaging and Python
+packaging. Inspiration for the format of the pre-release and build labels
+came from Python's PEP440.
+
+Changes vs SemVer 2.0
+---------------------
+
+#. dev versions are defined. These are extremely useful when
+ dealing with CI and CD systems when 'every commit is a release' is not
+ feasible.
+
+#. All versions have been made PEP-440 compatible, because of our deep
+ roots in Python. Pre-release versions are now separated by . not -, and
+ use a/b/c rather than alpha/beta etc.
+
+Summary
+-------
+
+Given a version number MAJOR.MINOR.PATCH,
+increment the:
+
+#. MAJOR version when you make incompatible API changes,
+#. MINOR version when you add functionality in a backwards-compatible
+ manner, and
+#. PATCH version when you make backwards-compatible bug fixes.
+
+Introduction
+------------
+
+In the world of software management there exists a dread place called
+"dependency hell." The bigger your system grows and the more packages
+you integrate into your software, the more likely you are to find
+yourself, one day, in this pit of despair.
+
+In systems with many dependencies, releasing new package versions can
+quickly become a nightmare. If the dependency specifications are too
+tight, you are in danger of version lock (the inability to upgrade a
+package without having to release new versions of every dependent
+package). If dependencies are specified too loosely, you will inevitably
+be bitten by version promiscuity (assuming compatibility with more
+future versions than is reasonable). Dependency hell is where you are
+when version lock and/or version promiscuity prevent you from easily and
+safely moving your project forward.
+
+As a solution to this problem, I propose a simple set of rules and
+requirements that dictate how version numbers are assigned and
+incremented. These rules are based on but not necessarily limited to
+pre-existing widespread common practices in use in both closed and
+open-source software. For this system to work, you first need to declare
+a public API. This may consist of documentation or be enforced by the
+code itself. Regardless, it is important that this API be clear and
+precise. Once you identify your public API, you communicate changes to
+it with specific increments to your version number. Consider a version
+format of X.Y.Z (Major.Minor.Patch). Bug fixes not affecting the API
+increment the patch version, backwards compatible API additions/changes
+increment the minor version, and backwards incompatible API changes
+increment the major version.
+
+I call this system "Semantic Versioning." Under this scheme, version
+numbers and the way they change convey meaning about the underlying code
+and what has been modified from one version to the next.
+
+Semantic Versioning Specification (SemVer)
+------------------------------------------
+
+The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
+document are to be interpreted as described in `RFC
+2119 <http://tools.ietf.org/html/rfc2119>`__.
+
+#. Software using Semantic Versioning MUST declare a public API. This
+ API could be declared in the code itself or exist strictly in
+ documentation. However it is done, it should be precise and
+ comprehensive.
+
+#. A normal version number MUST take the form X.Y.Z where X, Y, and Z
+ are non-negative integers, and MUST NOT contain leading zeroes. X is
+ the major version, Y is the minor version, and Z is the patch
+ version. Each element MUST increase numerically. For instance: 1.9.0
+ -> 1.10.0 -> 1.11.0.
+
+#. Once a versioned package has been released, the contents of that
+ version MUST NOT be modified. Any modifications MUST be released as
+ a new version.
+
+#. Major version zero (0.y.z) is for initial development. Anything may
+ change at any time. The public API should not be considered stable.
+
+#. Version 1.0.0 defines the public API. The way in which the version
+ number is incremented after this release is dependent on this public
+ API and how it changes.
+
+#. Patch version Z (x.y.Z \| x > 0) MUST be incremented if only
+ backwards compatible bug fixes are introduced. A bug fix is defined
+ as an internal change that fixes incorrect behavior.
+
+#. Minor version Y (x.Y.z \| x > 0) MUST be incremented if new,
+ backwards compatible functionality is introduced to the public API.
+ It MUST be incremented if any public API functionality is marked as
+ deprecated. It MAY be incremented if substantial new functionality
+ or improvements are introduced within the private code. It MAY
+ include patch level changes. Patch version MUST be reset to 0 when
+ minor version is incremented.
+
+#. Major version X (X.y.z \| X > 0) MUST be incremented if any
+ backwards incompatible changes are introduced to the public API. It
+ MAY also include minor and patch level changes. Patch and minor
+ version MUST be reset to 0 when major version is incremented.
+
+#. A pre-release version MAY be denoted by appending a dot
+ separated identifier immediately following the patch version.
+ The identifier MUST comprise only a, b, c followed by non-negative
+ integer value. The identifier MUST NOT be empty.
+ Pre-release versions have a lower precedence than the associated normal
+ version. A pre-release version indicates that
+ the version is unstable and might not satisfy the intended
+ compatibility requirements as denoted by its associated normal
+ version. Examples: 1.0.0.a1, 1.0.0.b99, 1.0.0.c1000.
+
+#. A development version MAY be denoted by appending a dot separated
+ identifier immediately following the patch version.
+ The identifier MUST comprise the string dev followed by non-negative
+ integer value. The identifier MUST NOT be empty. Development versions
+ have a lower precedence than the associated normal version or pre-release
+ version. A development version is a completely unsupported and conveys no
+ API promises when related to other versions. They are more useful as
+ communication vehicles between developers of a community, whereas
+ pre-releases, while potentially prone to break still, are intended for
+ externally facing communication of not-yet-released ideas. Dev versions
+ are not public artifacts and should never be placed in public
+ repositories: they are intended as developer-local resources. Examples:
+ 1.0.0.dev1, 1.0.0.a1.dev1
+
+#. git version metadata MAY be denoted by appending a dot separated
+ identifier immediately following a development or pre-release version.
+ The identifier MUST comprise the character g followed by a seven
+ character git short-sha. The sha MUST NOT be empty. git version
+ metadata MUST be ignored when determining version precedence. Thus
+ two versions that differ only in the git version, have the same
+ precedence. Example: 1.0.0.a1.g95a9beb.
+
+#. Build metadata MAY be denoted by appending a plus sign and a series
+ of dot separated identifiers immediately following the patch or
+ pre-release version. Identifiers MUST comprise only ASCII
+ alphanumerics [0-9A-Za-z]. Identifiers MUST NOT be empty. Build
+ metadata MUST be ignored when determining version precedence. Thus
+ two versions that differ only in the build metadata, have the same
+ precedence. Examples: 1.0.0.a1+001, 1.0.0+20130313144700,
+ 1.0.0.b1+exp.sha.5114f85.
+
+#. Precedence refers to how versions are compared to each other when
+ ordered. Precedence MUST be calculated by separating the version
+ into major, minor, patch, pre-release, and development identifiers in
+ that order (Build metadata does not figure into precedence). Precedence
+ is determined by the first difference when comparing each of these
+ identifiers from left to right as follows: Major, minor, and patch
+ versions are always compared numerically. Example: 1.0.0 < 2.0.0 <
+ 2.1.0 < 2.1.1. When major, minor, and patch are equal, a pre-release
+ version has lower precedence than a normal version. Example:
+ 1.0.0.a1 < 1.0.0. When major, minor, patch and pre-release are equal, a
+ development version has a lower precedence than a normal version and of a
+ pre-release version. Example: 1.0.0.dev1 < 1.0.0 and 1.0.0.dev9 <
+ 1.0.0.a1 and 1.0.0.a1 < 1.0.0.a2.dev4. Precedence for two pre-release
+ versions with the same major, minor, and patch version MUST be determined
+ by comparing the identifier to the right of the patch version as follows:
+ if the alpha portion matches, the numeric portion is compared in
+ numerical sort order. If the alpha portion does not match, the sort order
+ is dev < a < b < c. Example: 1.0.0.dev8 < 1.0.0.dev9 < 1.0.0.a1.dev3 <
+ 1.0.0.a1 < 1.0.0.b2 < 1.0.0.c1 < 1.0.0. Precedence for dev versions if
+ all other components are equal is done by comparing their numeric
+ component. If all other components are not equal, predence is determined
+ by comparing the other components.
+
+Why Use Semantic Versioning?
+----------------------------
+
+This is not a new or revolutionary idea. In fact, you probably do
+something close to this already. The problem is that "close" isn't good
+enough. Without compliance to some sort of formal specification, version
+numbers are essentially useless for dependency management. By giving a
+name and clear definition to the above ideas, it becomes easy to
+communicate your intentions to the users of your software. Once these
+intentions are clear, flexible (but not too flexible) dependency
+specifications can finally be made.
+
+A simple example will demonstrate how Semantic Versioning can make
+dependency hell a thing of the past. Consider a library called
+"Firetruck." It requires a Semantically Versioned package named
+"Ladder." At the time that Firetruck is created, Ladder is at version
+3.1.0. Since Firetruck uses some functionality that was first introduced
+in 3.1.0, you can safely specify the Ladder dependency as greater than
+or equal to 3.1.0 but less than 4.0.0. Now, when Ladder version 3.1.1
+and 3.2.0 become available, you can release them to your package
+management system and know that they will be compatible with existing
+dependent software.
+
+As a responsible developer you will, of course, want to verify that any
+package upgrades function as advertised. The real world is a messy
+place; there's nothing we can do about that but be vigilant. What you
+can do is let Semantic Versioning provide you with a sane way to release
+and upgrade packages without having to roll new versions of dependent
+packages, saving you time and hassle.
+
+If all of this sounds desirable, all you need to do to start using
+Semantic Versioning is to declare that you are doing so and then follow
+the rules. Link to this website from your README so others know the
+rules and can benefit from them.
+
+FAQ
+---
+
+How should I deal with revisions in the 0.y.z initial development phase?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The simplest thing to do is start your initial development release at
+0.1.0 and then increment the minor version for each subsequent release.
+
+How do I know when to release 1.0.0?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If your software is being used in production, it should probably already
+be 1.0.0. If you have a stable API on which users have come to depend,
+you should be 1.0.0. If you're worrying a lot about backwards
+compatibility, you should probably already be 1.0.0.
+
+Doesn't this discourage rapid development and fast iteration?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Major version zero is all about rapid development. If you're changing
+the API every day you should either still be in version 0.y.z or on a
+separate development branch working on the next major version.
+
+If even the tiniest backwards incompatible changes to the public API require a major version bump, won't I end up at version 42.0.0 very rapidly?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This is a question of responsible development and foresight.
+Incompatible changes should not be introduced lightly to software that
+has a lot of dependent code. The cost that must be incurred to upgrade
+can be significant. Having to bump major versions to release
+incompatible changes means you'll think through the impact of your
+changes, and evaluate the cost/benefit ratio involved.
+
+Documenting the entire public API is too much work!
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+It is your responsibility as a professional developer to properly
+document software that is intended for use by others. Managing software
+complexity is a hugely important part of keeping a project efficient,
+and that's hard to do if nobody knows how to use your software, or what
+methods are safe to call. In the long run, Semantic Versioning, and the
+insistence on a well defined public API can keep everyone and everything
+running smoothly.
+
+What do I do if I accidentally release a backwards incompatible change as a minor version?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+As soon as you realize that you've broken the Semantic Versioning spec,
+fix the problem and release a new minor version that corrects the
+problem and restores backwards compatibility. Even under this
+circumstance, it is unacceptable to modify versioned releases. If it's
+appropriate, document the offending version and inform your users of the
+problem so that they are aware of the offending version.
+
+What should I do if I update my own dependencies without changing the public API?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+That would be considered compatible since it does not affect the public
+API. Software that explicitly depends on the same dependencies as your
+package should have their own dependency specifications and the author
+will notice any conflicts. Determining whether the change is a patch
+level or minor level modification depends on whether you updated your
+dependencies in order to fix a bug or introduce new functionality. I
+would usually expect additional code for the latter instance, in which
+case it's obviously a minor level increment.
+
+What if I inadvertently alter the public API in a way that is not compliant with the version number change (i.e. the code incorrectly introduces a major breaking change in a patch release)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Use your best judgment. If you have a huge audience that will be
+drastically impacted by changing the behavior back to what the public
+API intended, then it may be best to perform a major version release,
+even though the fix could strictly be considered a patch release.
+Remember, Semantic Versioning is all about conveying meaning by how the
+version number changes. If these changes are important to your users,
+use the version number to inform them.
+
+How should I handle deprecating functionality?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Deprecating existing functionality is a normal part of software
+development and is often required to make forward progress. When you
+deprecate part of your public API, you should do two things: (1) update
+your documentation to let users know about the change, (2) issue a new
+minor release with the deprecation in place. Before you completely
+remove the functionality in a new major release there should be at least
+one minor release that contains the deprecation so that users can
+smoothly transition to the new API.
+
+Does SemVer have a size limit on the version string?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+No, but use good judgment. A 255 character version string is probably
+overkill, for example. Also, specific systems may impose their own
+limits on the size of the string.
+
+About
+-----
+
+The Linux/Python Compatible Semantic Versioning specification is maintained
+by the `OpenStack <http://openstack.org>`_ project.
+
+It is based on The Semantic Versioning specification, which was
+authored by `Tom Preston-Werner <http://tom.preston-werner.com>`__,
+with inputs from `PEP 440 <http://www.python.org/dev/peps/pep-0440/>`_
+
+If you'd like to leave feedback, please `open an issue
+<https://bugs.launchpad.net/pbr/+filebug>`_.
+
+License
+-------
+
+Creative Commons - CC BY 3.0 http://creativecommons.org/licenses/by/3.0/
--- /dev/null
+=======
+ Usage
+=======
+
+*pbr* is a *setuptools* plugin and so to use it you must use *setuptools* and
+call ``setuptools.setup()``. While the normal *setuptools* facilities are
+available, *pbr* makes it possible to express them through static data files.
+
+.. _setup_py:
+
+``setup.py``
+------------
+
+*pbr* only requires a minimal ``setup.py`` file compared to a standard
+*setuptools* project. This is because most configuration is located in static
+configuration files. This recommended minimal ``setup.py`` file should look
+something like this::
+
+ #!/usr/bin/env python
+
+ from setuptools import setup
+
+ setup(
+ setup_requires=['pbr'],
+ pbr=True,
+ )
+
+.. note::
+
+ It is necessary to specify ``pbr=True`` to enabled *pbr* functionality.
+
+.. note::
+
+ While one can pass any arguments supported by setuptools to ``setup()``,
+ any conflicting arguments supplied in ``setup.cfg`` will take precedence.
+
+.. _setup_cfg:
+
+``setup.cfg``
+-------------
+
+The ``setup.cfg`` file is an INI-like file that can mostly replace the
+``setup.py`` file. It is similar to the ``setup.cfg`` file found in recent
+versions of `setuptools`__. A simple sample can be found in *pbr*'s own
+``setup.cfg`` (it uses its own machinery to install itself):
+
+::
+
+ [metadata]
+ name = pbr
+ author = OpenStack Foundation
+ author-email = openstack-dev@lists.openstack.org
+ summary = OpenStack's setup automation in a reusable form
+ description-file = README.rst
+ description-content-type = text/x-rst; charset=UTF-8
+ home-page = https://launchpad.net/pbr
+ project_urls =
+ Bug Tracker = https://bugs.launchpad.net/pbr/
+ Documentation = https://docs.openstack.org/pbr/
+ Source Code = https://git.openstack.org/cgit/openstack-dev/pbr/
+ license = Apache-2
+ classifier =
+ Development Status :: 4 - Beta
+ Environment :: Console
+ Environment :: OpenStack
+ Intended Audience :: Developers
+ Intended Audience :: Information Technology
+ License :: OSI Approved :: Apache Software License
+ Operating System :: OS Independent
+ Programming Language :: Python
+ keywords =
+ setup
+ distutils
+
+ [files]
+ packages =
+ pbr
+ data_files =
+ etc/pbr = etc/*
+ etc/init =
+ pbr.packaging.conf
+ pbr.version.conf
+
+ [entry_points]
+ console_scripts =
+ pbr = pbr.cmd:main
+ pbr.config.drivers =
+ plain = pbr.cfg.driver:Plain
+
+Recent versions of `setuptools`_ provide many of the same sections as *pbr*.
+However, *pbr* does provide a number of additional sections:
+
+- ``files``
+- ``entry_points``
+- ``backwards_compat``
+- ``pbr``
+
+In addition, there are some modifications to other sections:
+
+- ``metadata``
+- ``build_sphinx``
+
+For all other sections, you should refer to either the `setuptools`_
+documentation or the documentation of the package that provides the section,
+such as the ``extract_mesages`` section provided by Babel__.
+
+.. note::
+
+ Comments may be used in ``setup.cfg``, however all comments should start
+ with a ``#`` and may be on a single line, or in line, with at least one
+ white space character immediately preceding the ``#``. Semicolons are not a
+ supported comment delimiter. For instance::
+
+ [section]
+ # A comment at the start of a dedicated line
+ key =
+ value1 # An in line comment
+ value2
+ # A comment on a dedicated line
+ value3
+
+__ http://setuptools.readthedocs.io/en/latest/setuptools.html#configuring-setup-using-setup-cfg-files
+__ http://babel.pocoo.org/en/latest/setup.html
+
+``files``
+~~~~~~~~~
+
+The ``files`` section defines the install location of files in the package
+using three fundamental keys: ``packages``, ``namespace_packages``, and
+``data_files``.
+
+``packages``
+ A list of top-level packages that should be installed. The behavior of
+ packages is similar to ``setuptools.find_packages`` in that it recurses the
+ Python package hierarchy below the given top level and installs all of it. If
+ ``packages`` is not specified, it defaults to the value of the ``name`` field
+ given in the ``[metadata]`` section.
+
+``namespace_packages``
+ Similar to ``packages``, but is a list of packages that provide namespace
+ packages.
+
+``data_files``
+ A list of files to be installed. The format is an indented block that
+ contains key value pairs which specify target directory and source file to
+ install there. More than one source file for a directory may be indicated
+ with a further indented list. Source files are stripped of leading
+ directories. Additionally, *pbr* supports a simple file globbing syntax for
+ installing entire directory structures. For example::
+
+ [files]
+ data_files =
+ etc/pbr = etc/pbr/*
+ etc/neutron =
+ etc/api-paste.ini
+ etc/dhcp-agent.ini
+ etc/init.d = neutron.init
+
+ This will result in ``/etc/neutron`` containing ``api-paste.ini`` and
+ ``dhcp-agent.ini``, both of which *pbr* will expect to find in the ``etc``
+ directory in the root of the source tree. Additionally, ``neutron.init`` from
+ that directory will be installed in ``/etc/init.d``. All of the files and
+ directories located under ``etc/pbr`` in the source tree will be installed
+ into ``/etc/pbr``.
+
+ Note that this behavior is relative to the effective root of the environment
+ into which the packages are installed, so depending on available permissions
+ this could be the actual system-wide ``/etc`` directory or just a top-level
+ ``etc`` subdirectory of a *virtualenv*.
+
+``entry_points``
+~~~~~~~~~~~~~~~~
+
+The ``entry_points`` section defines entry points for generated console scripts
+and Python libraries. This is actually provided by *setuptools* but is
+documented here owing to its importance.
+
+The general syntax of specifying entry points is a top level name indicating
+the entry point group name, followed by one or more key value pairs naming
+the entry point to be installed. For instance::
+
+ [entry_points]
+ console_scripts =
+ pbr = pbr.cmd:main
+ pbr.config.drivers =
+ plain = pbr.cfg.driver:Plain
+ fancy = pbr.cfg.driver:Fancy
+
+Will cause a console script called *pbr* to be installed that executes the
+``main`` function found in ``pbr.cmd``. Additionally, two entry points will be
+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``.
+
+``backwards_compat``
+~~~~~~~~~~~~~~~~~~~~~
+
+.. todo:: Describe this section
+
+.. _pbr-setup-cfg:
+
+``pbr``
+~~~~~~~
+
+The ``pbr`` section controls *pbr*-specific options and behaviours.
+
+``autodoc_tree_index_modules``
+
+ A boolean option controlling whether *pbr* should generate an index of
+ modules using ``sphinx-apidoc``. By default, all files except ``setup.py``
+ are included, but this can be overridden using the ``autodoc_tree_excludes``
+ option.
+
+``autodoc_tree_excludes``
+
+ A list of modules to exclude when building documentation using
+ ``sphinx-apidoc``. Defaults to ``[setup.py]``. Refer to the
+ `sphinx-apidoc man page`__ for more information.
+
+__ http://sphinx-doc.org/man/sphinx-apidoc.html
+
+``autodoc_index_modules``
+
+ A boolean option controlling whether *pbr* should itself generates
+ documentation for Python modules of the project. By default, all found Python
+ modules are included; some of them can be excluded by listing them in
+ ``autodoc_exclude_modules``.
+
+``autodoc_exclude_modules``
+
+ A list of modules to exclude when building module documentation using *pbr*.
+ *fnmatch* style pattern (e.g. ``myapp.tests.*``) can be used.
+
+``api_doc_dir``
+
+ A subdirectory inside the ``build_sphinx.source_dir`` where auto-generated
+ API documentation should be written, if ``autodoc_index_modules`` is set to
+ True. Defaults to ``"api"``.
+
+.. note::
+
+ When using ``autodoc_tree_excludes`` or ``autodoc_index_modules`` you may
+ also need to set ``exclude_patterns`` in your Sphinx configuration file
+ (generally found at ``doc/source/conf.py`` in most OpenStack projects)
+ otherwise Sphinx may complain about documents that are not in a toctree.
+ This is especially true if the ``[sphinx_build] warning-is-error`` option is
+ set. See the `Sphinx build configuration file`__ documentation for more
+ information on configuring Sphinx.
+
+__ http://sphinx-doc.org/config.html
+
+.. versionchanged:: 2.0
+
+ The ``pbr`` section used to take a ``warnerrors`` option that would enable
+ the ``-W`` (Turn warnings into errors.) option when building Sphinx. This
+ feature was broken in 1.10 and was removed in pbr 2.0 in favour of the
+ ``[build_sphinx] warning-is-error`` provided in Sphinx 1.5+.
+
+``metadata``
+~~~~~~~~~~~~
+
+.. todo:: Describe this section
+
+.. _build_sphinx-setup-cfg:
+
+``build_sphinx``
+~~~~~~~~~~~~~~~~
+
+.. versionchanged:: 3.0
+
+ The ``build_sphinx`` plugin used to default to building both HTML and man
+ page output. This is no longer the case, and you should explicitly set
+ ``builders`` to ``html man`` if you wish to retain this behavior.
+
+The ``build_sphinx`` section is a version of the ``build_sphinx`` *setuptools*
+plugin provided with Sphinx. This plugin extends the original plugin to add the
+following:
+
+- Automatic generation of module documentation using the ``sphinx-apidoc`` tool
+
+- Automatic configuration of the ``project``, ``version`` and ``release``
+ settings using information from *pbr* itself
+
+- Support for multiple builders using the ``builders`` configuration option
+
+ .. note::
+
+ Only applies to Sphinx < 1.6. See documentation on ``builders`` below.
+
+The version of ``build_sphinx`` provided by *pbr* provides a single additional
+option.
+
+``builders``
+ A comma separated list of builders to run. For example, to build both HTML
+ and man page documentation, you would define the following in your
+ ``setup.cfg``:
+
+ .. code-block:: ini
+
+ [build_sphinx]
+ builders = html,man
+ source-dir = doc/source
+ build-dir = doc/build
+ all-files = 1
+ warning-is-error = 1
+
+ .. deprecated:: 3.2.0
+
+ Sphinx 1.6+ adds support for specifying multiple builders in the default
+ ``builder`` option. You should use this option instead. Refer to the
+ `Sphinx documentation`_ for more information.
+
+For information on the remaining options, refer to the `Sphinx documentation`_.
+In addition, the ``autodoc_index_modules``, ``autodoc_tree_index_modules``,
+``autodoc_exclude_modules`` and ``autodoc_tree_excludes`` options :ref:`in the
+pbr section <pbr-setup-cfg>` will affect the output of the automatic module
+documentation generation.
+
+.. _Sphinx documentation: http://www.sphinx-doc.org/en/stable/setuptools.html
+
+Requirements
+------------
+
+Requirements files are used in place of the ``install_requires`` and
+``extras_require`` attributes. Requirement files should be given one of the
+below names. This order is also the order that the requirements are tried in
+(where ``N`` is the Python major version number used to install the package):
+
+* ``requirements-pyN.txt``
+* ``tools/pip-requires-py3``
+* ``requirements.txt``
+* ``tools/pip-requires``
+
+Only the first file found is used to install the list of packages it contains.
+
+.. note::
+
+ The ``requirements-pyN.txt`` file is deprecated - ``requirements.txt``
+ should be universal. You can use `Environment markers`_ for this purpose.
+
+.. _extra-requirements:
+
+Extra requirements
+~~~~~~~~~~~~~~~~~~
+
+Groups of optional dependencies, or `"extra" requirements`__, 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.
+
+__ https://www.python.org/dev/peps/pep-0426/#extras-optional-dependencies
+
+Environment markers
+~~~~~~~~~~~~~~~~~~~
+
+Environment markers are `conditional dependencies`__ 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 defined in ``setup.cfg``, but the format
+is slightly different for each.
+
+For ``requirements.txt``::
+
+ argparse; python_version=='2.6'
+
+This will result in the package depending on ``argparse`` only if it's being
+installed into Python 2.6.
+
+For extras specified 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_version=='3.2'
+ gimel:python_version=='2.7'
+ testing =
+ quux:python_version=='2.7'
+
+__ https://www.python.org/dev/peps/pep-0426/#environment-markers
+
+Testing
+-------
+
+.. deprecated:: 4.0
+
+As described in :doc:`/user/features`, *pbr* may override the ``test`` command
+depending on the test runner used.
+
+A typical usage would be in ``tox.ini`` such as::
+
+ [tox]
+ minversion = 2.0
+ skipsdist = True
+ envlist = py33,py34,py35,py26,py27,pypy,pep8,docs
+
+ [testenv]
+ usedevelop = True
+ setenv =
+ VIRTUAL_ENV={envdir}
+ CLIENT_NAME=pbr
+ deps = .
+ -r{toxinidir}/test-requirements.txt
+ commands =
+ python setup.py test --testr-args='{posargs}'
+
+The argument ``--coverage`` will set ``PYTHON`` to ``coverage run`` to produce
+a coverage report. ``--coverage-package-name`` can be used to modify or narrow
+the packages traced.
+
+.. _setuptools: http://www.sphinx-doc.org/en/stable/setuptools.html
-Metadata-Version: 1.1
+Metadata-Version: 2.1
Name: pbr
-Version: 3.1.1
+Version: 4.0.0
Summary: Python Build Reasonableness
-Home-page: http://docs.openstack.org/developer/pbr/
+Home-page: https://docs.openstack.org/pbr/latest/
Author: OpenStack
Author-email: openstack-dev@lists.openstack.org
License: UNKNOWN
+Project-URL: Bug Tracker, https://bugs.launchpad.net/pbr/
+Project-URL: Documentation, https://docs.openstack.org/pbr/
+Project-URL: Source Code, https://git.openstack.org/cgit/openstack-dev/pbr/
Description: Introduction
============
them as quickly as possible.
* License: Apache License, Version 2.0
- * Documentation: http://docs.openstack.org/developer/pbr
- * Source: http://git.openstack.org/cgit/openstack-dev/pbr
- * Bugs: http://bugs.launchpad.net/pbr
- * Change Log: https://docs.openstack.org/developer/pbr/history.html
+ * Documentation: https://docs.openstack.org/pbr/latest/
+ * Source: https://git.openstack.org/cgit/openstack-dev/pbr
+ * Bugs: https://bugs.launchpad.net/pbr
+ * Change Log: https://docs.openstack.org/pbr/latest/user/history.html
.. _d2to1: https://pypi.python.org/pypi/d2to1
.. _distutils2: https://pypi.python.org/pypi/Distutils2
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
+Description-Content-Type: text/x-rst; charset=UTF-8
setup.py
test-requirements.txt
tox.ini
-doc/source/compatibility.rst
doc/source/conf.py
-doc/source/history.rst
doc/source/index.rst
-doc/source/packagers.rst
-doc/source/semver.rst
-doc/source/testing.rst
+doc/source/contributor/index.rst
+doc/source/reference/index.rst
+doc/source/user/compatibility.rst
+doc/source/user/features.rst
+doc/source/user/history.rst
+doc/source/user/index.rst
+doc/source/user/packagers.rst
+doc/source/user/semver.rst
+doc/source/user/using.rst
pbr/__init__.py
pbr/builddoc.py
pbr/core.py
pbr/tests/testpackage/pbr_testpackage/package_data/1.txt
pbr/tests/testpackage/pbr_testpackage/package_data/2.txt
pbr/tests/testpackage/src/testext.c
+releasenotes/notes/deprecate-pyN-requirements-364655c38fa5b780.yaml
+releasenotes/notes/deprecate-testr-nose-integration-56e3e11248d946fc.yaml
+releasenotes/notes/remove-command-hooks-907d9c2325f306ca.yaml
+releasenotes/notes/v_version-457b38c8679c5868.yaml
+releasenotes/source/conf.py
+releasenotes/source/index.rst
+releasenotes/source/unreleased.rst
tools/integration.sh
-tools/tox_install.sh
\ No newline at end of file
+tools/tox_releasenotes.sh
\ No newline at end of file
import io as cStringIO
try:
- from sphinx import apidoc
+ import sphinx
+ # NOTE(dhellmann): Newer versions of Sphinx have moved the apidoc
+ # module into sphinx.ext and the API is slightly different (the
+ # function expects sys.argv[1:] instead of sys.argv[:]. So, figure
+ # out where we can import it from and set a flag so we can invoke
+ # it properly. See this change in sphinx for details:
+ # https://github.com/sphinx-doc/sphinx/commit/87630c8ae8bff8c0e23187676e6343d8903003a6
+ try:
+ from sphinx.ext import apidoc
+ apidoc_use_padding = False
+ except ImportError:
+ from sphinx import apidoc
+ apidoc_use_padding = True
from sphinx import application
from sphinx import setup_command
except Exception as e:
raise ImportError(str(e))
from pbr import git
from pbr import options
+from pbr import version
_rst_template = """%(heading)s
def _sphinx_tree(self):
source_dir = self._get_source_dir()
- cmd = ['apidoc', '.', '-H', 'Modules', '-o', source_dir]
+ cmd = ['-H', 'Modules', '-o', source_dir, '.']
+ if apidoc_use_padding:
+ cmd.insert(0, 'apidoc')
apidoc.main(cmd + self.autodoc_tree_excludes)
def _sphinx_run(self):
"autodoc_exclude_modules",
[None, ""])[1].split()))
- # TODO(stephenfin): Deprecate this functionality once we depend on
- # Sphinx 1.6, which includes a similar feature, in g-r
- # https://github.com/sphinx-doc/sphinx/pull/3476
self.finalize_options()
- if hasattr(self, "builder_target_dirs"):
- # Sphinx >= 1.6.1
+
+ is_multibuilder_sphinx = version.SemanticVersion.from_pip_string(
+ sphinx.__version__) >= version.SemanticVersion(1, 6)
+
+ # TODO(stephenfin): Remove support for Sphinx < 1.6 in 4.0
+ if not is_multibuilder_sphinx:
+ log.warn('[pbr] Support for Sphinx < 1.6 will be dropped in '
+ 'pbr 4.0. Upgrade to Sphinx 1.6+')
+
+ # TODO(stephenfin): Remove this at the next MAJOR version bump
+ if self.builders != ['html']:
+ log.warn("[pbr] Sphinx 1.6 added native support for "
+ "specifying multiple builders in the "
+ "'[sphinx_build] builder' configuration option, "
+ "found in 'setup.cfg'. As a result, the "
+ "'[sphinx_build] builders' option has been "
+ "deprecated and will be removed in pbr 4.0. Migrate "
+ "to the 'builder' configuration option.")
+ if is_multibuilder_sphinx:
+ self.builder = self.builders
+
+ if is_multibuilder_sphinx:
+ # Sphinx >= 1.6
return setup_command.BuildDoc.run(self)
+
# Sphinx < 1.6
- for builder in self.builders:
+ for builder in self.builder:
self.builder = builder
self.finalize_options()
self._sphinx_run()
self.autodoc_tree_excludes = ['setup.py']
def finalize_options(self):
+ from pbr import util
+
# Not a new style class, super keyword does not work.
setup_command.BuildDoc.finalize_options(self)
opt = 'autodoc_tree_excludes'
option_dict = self.distribution.get_option_dict('pbr')
if opt in option_dict:
- self.autodoc_tree_excludes = option_dict[opt][1]
- self.ensure_string_list(opt)
+ self.autodoc_tree_excludes = util.split_multiline(
+ option_dict[opt][1])
# handle Sphinx < 1.5.0
if not hasattr(self, 'warning_is_error'):
import sys
import warnings
-from setuptools import dist
-
from pbr import util
-_saved_core_distribution = core.Distribution
-
-
-def _monkeypatch_distribution():
- core.Distribution = dist._get_unpatched(core.Distribution)
-
-
-def _restore_distribution_monkeypatch():
- core.Distribution = _saved_core_distribution
-
-
if sys.version_info[0] == 3:
string_type = str
integer_types = (int,)
not work well with distributions that do use a `Distribution` subclass.
"""
+ if not value:
+ return
+ if isinstance(value, string_type):
+ path = os.path.abspath(value)
+ else:
+ path = os.path.abspath('setup.cfg')
+ if not os.path.exists(path):
+ raise errors.DistutilsFileError(
+ 'The setup.cfg file %s does not exist.' % path)
+
+ # Converts the setup.cfg file to setup() arguments
try:
- _monkeypatch_distribution()
- if not value:
- return
- if isinstance(value, string_type):
- path = os.path.abspath(value)
- else:
- path = os.path.abspath('setup.cfg')
- if not os.path.exists(path):
- raise errors.DistutilsFileError(
- 'The setup.cfg file %s does not exist.' % path)
-
- # Converts the setup.cfg file to setup() arguments
- try:
- attrs = util.cfg_to_args(path, dist.script_args)
- except Exception:
- e = sys.exc_info()[1]
- # NB: This will output to the console if no explicit logging has
- # been setup - but thats fine, this is a fatal distutils error, so
- # being pretty isn't the #1 goal.. being diagnosable is.
- logging.exception('Error parsing')
- raise errors.DistutilsSetupError(
- 'Error parsing %s: %s: %s' % (path, e.__class__.__name__, e))
-
- # Repeat some of the Distribution initialization code with the newly
- # provided attrs
- if attrs:
- # Skips 'options' and 'licence' support which are rarely used; may
- # add back in later if demanded
- for key, val in attrs.items():
- if hasattr(dist.metadata, 'set_' + key):
- getattr(dist.metadata, 'set_' + key)(val)
- elif hasattr(dist.metadata, key):
- setattr(dist.metadata, key, val)
- elif hasattr(dist, key):
- setattr(dist, key, val)
- else:
- msg = 'Unknown distribution option: %s' % repr(key)
- warnings.warn(msg)
-
- # Re-finalize the underlying Distribution
- core.Distribution.finalize_options(dist)
-
- # This bit comes out of distribute/setuptools
- if isinstance(dist.metadata.version, integer_types + (float,)):
- # Some people apparently take "version number" too literally :)
- dist.metadata.version = str(dist.metadata.version)
-
- # This bit of hackery is necessary so that the Distribution will ignore
- # normally unsupport command options (namely pre-hooks and post-hooks).
- # dist.command_options is normally a dict mapping command names to
- # dicts of their options. Now it will be a defaultdict that returns
- # IgnoreDicts for the each command's options so we can pass through the
- # unsupported options
- ignore = ['pre_hook.*', 'post_hook.*']
- dist.command_options = util.DefaultGetDict(
- lambda: util.IgnoreDict(ignore)
- )
- finally:
- _restore_distribution_monkeypatch()
+ attrs = util.cfg_to_args(path, dist.script_args)
+ except Exception:
+ e = sys.exc_info()[1]
+ # NB: This will output to the console if no explicit logging has
+ # been setup - but thats fine, this is a fatal distutils error, so
+ # being pretty isn't the #1 goal.. being diagnosable is.
+ logging.exception('Error parsing')
+ raise errors.DistutilsSetupError(
+ 'Error parsing %s: %s: %s' % (path, e.__class__.__name__, e))
+
+ # Repeat some of the Distribution initialization code with the newly
+ # provided attrs
+ if attrs:
+ # Skips 'options' and 'licence' support which are rarely used; may
+ # add back in later if demanded
+ for key, val in attrs.items():
+ if hasattr(dist.metadata, 'set_' + key):
+ getattr(dist.metadata, 'set_' + key)(val)
+ elif hasattr(dist.metadata, key):
+ setattr(dist.metadata, key, val)
+ elif hasattr(dist, key):
+ setattr(dist, key, val)
+ else:
+ msg = 'Unknown distribution option: %s' % repr(key)
+ warnings.warn(msg)
+
+ # Re-finalize the underlying Distribution
+ try:
+ super(dist.__class__, dist).finalize_options()
+ except TypeError:
+ # If dist is not declared as a new-style class (with object as
+ # a subclass) then super() will not work on it. This is the case
+ # for Python 2. In that case, fall back to doing this the ugly way
+ dist.__class__.__bases__[-1].finalize_options(dist)
+
+ # This bit comes out of distribute/setuptools
+ if isinstance(dist.metadata.version, integer_types + (float,)):
+ # Some people apparently take "version number" too literally :)
+ dist.metadata.version = str(dist.metadata.version)
import os
import re
import sys
+import warnings
import pkg_resources
import setuptools
from pbr import version
REQUIREMENTS_FILES = ('requirements.txt', 'tools/pip-requires')
+PY_REQUIREMENTS_FILES = [x % sys.version_info[0] for x in (
+ 'requirements-py%d.txt', 'tools/pip-requires-py%d')]
TEST_REQUIREMENTS_FILES = ('test-requirements.txt', 'tools/test-requires')
# - REQUIREMENTS_FILES with -py2 or -py3 in the name
# (e.g. requirements-py3.txt)
# - REQUIREMENTS_FILES
- return (list(map(('-py' + str(sys.version_info[0])).join,
- map(os.path.splitext, REQUIREMENTS_FILES)))
- + list(REQUIREMENTS_FILES))
+
+ return PY_REQUIREMENTS_FILES + list(REQUIREMENTS_FILES)
def append_text_list(config, key, text_list):
# Get requirements from the first file that exists
def get_reqs_from_files(requirements_files):
- for requirements_file in _any_existing(requirements_files):
+ existing = _any_existing(requirements_files)
+
+ deprecated = [f for f in existing if f in PY_REQUIREMENTS_FILES]
+ if deprecated:
+ warnings.warn('Support for \'-pyN\'-suffixed requirements files is '
+ 'deprecated in pbr 4.0 and will be removed in 5.0. '
+ 'Use environment markers instead. Conflicting files: '
+ '%r' % deprecated,
+ DeprecationWarning)
+
+ for requirements_file in existing:
with open(requirements_file, 'r') as fil:
return fil.read().split('\n')
+
return []
"""Fallback test runner if testr is a no-go."""
command_name = 'test'
+ description = 'DEPRECATED: Run unit tests using nose'
def run(self):
+ warnings.warn('nose integration in pbr is deprecated. Please use '
+ 'the native nose setuptools configuration or call '
+ 'nose directly',
+ DeprecationWarning)
+
# Can't use super - base class old-style class
commands.nosetests.run(self)
command_name = 'develop'
def install_wrapper_scripts(self, dist):
- if sys.platform == 'win32':
- return develop.develop.install_wrapper_scripts(self, dist)
if not self.exclude_scripts:
for args in override_get_script_args(dist):
self.write_script(*args)
# entry-points listed for this package.
return
- if os.name != 'nt':
- get_script_args = override_get_script_args
- else:
- get_script_args = easy_install.get_script_args
- executable = '"%s"' % executable
-
- for args in get_script_args(dist, executable, is_wininst):
+ for args in override_get_script_args(dist, executable, is_wininst):
self.write_script(*args)
command_name = 'sdist'
+ def checking_reno(self):
+ """Ensure reno is installed and configured.
+
+ We can't run reno-based commands if reno isn't installed/available, and
+ don't want to if the user isn't using it.
+ """
+ if hasattr(self, '_has_reno'):
+ return self._has_reno
+
+ try:
+ # versions of reno witout this module will not have the required
+ # feature, hence the import
+ from reno import setup_command # noqa
+ except ImportError:
+ log.info('[pbr] reno was not found or is too old. Skipping '
+ 'release notes')
+ self._has_reno = False
+ return False
+
+ conf, output_file, cache_file = setup_command.load_config(
+ self.distribution)
+
+ if not os.path.exists(os.path.join(conf.reporoot, conf.notespath)):
+ log.info('[pbr] reno does not appear to be configured. Skipping '
+ 'release notes')
+ self._has_reno = False
+ return False
+
+ self._files = [output_file, cache_file]
+
+ log.info('[pbr] Generating release notes')
+ self._has_reno = True
+
+ return True
+
+ sub_commands = [('build_reno', checking_reno)] + sdist.sdist.sub_commands
+
def run(self):
_from_git(self.distribution)
# sdist.sdist is an old style class, can't use super()
sdist.sdist.run(self)
+ def make_distribution(self):
+ # This is included in make_distribution because setuptools doesn't use
+ # 'get_file_list'. As such, this is the only hook point that runs after
+ # the commands in 'sub_commands'
+ if self.checking_reno():
+ self.filelist.extend(self._files)
+ self.filelist.sort()
+ sdist.sdist.make_distribution(self)
+
try:
from pbr import builddoc
_have_sphinx = True
import logging
import os
import sys
+import warnings
logger = logging.getLogger(__name__)
class TestrReal(cmd.Command):
- description = "Run unit tests using testr"
+ description = "DEPRECATED: Run unit tests using testr"
user_options = [
('coverage', None, "Replace PYTHON with coverage and merge coverage "
def run(self):
"""Set up testr repo, then run testr."""
logger.debug("run called")
+
+ warnings.warn('testr integration in pbr is deprecated. Please use '
+ 'the \'testr\' setup command or call testr directly',
+ DeprecationWarning)
+
if not os.path.isdir(".testrepository"):
self._run_testr("init")
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
import os
-import textwrap
-from testtools import content
from testtools import matchers
from pbr.tests import base
cfg.set('global', 'setup-hooks',
'pbr_testpackage._setup_hooks.test_hook_1\n'
'pbr_testpackage._setup_hooks.test_hook_2')
- cfg.set('build_ext', 'pre-hook.test_pre_hook',
- 'pbr_testpackage._setup_hooks.test_pre_hook')
- cfg.set('build_ext', 'post-hook.test_post_hook',
- 'pbr_testpackage._setup_hooks.test_post_hook')
def test_global_setup_hooks(self):
"""Test setup_hooks.
assert 'test_hook_1\ntest_hook_2' in stdout
assert return_code == 0
- def test_command_hooks(self):
- """Test command hooks.
-
- Simple test that the appropriate command hooks run at the
- beginning/end of the appropriate command.
- """
-
- stdout, _, return_code = self.run_setup('egg_info')
- assert 'build_ext pre-hook' not in stdout
- assert 'build_ext post-hook' not in stdout
- assert return_code == 0
-
- stdout, stderr, return_code = self.run_setup('build_ext')
- self.addDetailUniqueName('stderr', content.text_content(stderr))
- assert textwrap.dedent("""
- running build_ext
- running pre_hook pbr_testpackage._setup_hooks.test_pre_hook for command build_ext
- build_ext pre-hook
- """) in stdout # flake8: noqa
- self.expectThat(stdout, matchers.EndsWith('build_ext post-hook'))
- assert return_code == 0
-
def test_custom_commands_known(self):
stdout, _, return_code = self.run_setup('--help-commands')
self.assertFalse(return_code)
import imp
import os
import re
+import sys
import sysconfig
import tempfile
import textwrap
import mock
import pkg_resources
import six
+import testscenarios
import testtools
from testtools import matchers
import virtualenv
self.assertEqual(False, git._git_is_installed())
-class TestIndexInRequirements(base.BaseTestCase):
+class ParseRequirementsTest(base.BaseTestCase):
- def test_index_in_requirement(self):
+ def test_empty_requirements(self):
+ actual = packaging.parse_requirements([])
+ self.assertEqual([], actual)
+
+ def test_default_requirements(self):
+ """Ensure default files used if no files provided."""
+ tempdir = tempfile.mkdtemp()
+ requirements = os.path.join(tempdir, 'requirements.txt')
+ with open(requirements, 'w') as f:
+ f.write('pbr')
+ # the defaults are relative to where pbr is called from so we need to
+ # override them. This is OK, however, as we want to validate that
+ # defaults are used - not what those defaults are
+ with mock.patch.object(packaging, 'REQUIREMENTS_FILES', (
+ requirements,)):
+ result = packaging.parse_requirements()
+ self.assertEqual(['pbr'], result)
+
+ def test_override_with_env(self):
+ """Ensure environment variable used if no files provided."""
+ _, tmp_file = tempfile.mkstemp(prefix='openstack', suffix='.setup')
+ with open(tmp_file, 'w') as fh:
+ fh.write("foo\nbar")
+ self.useFixture(
+ fixtures.EnvironmentVariable('PBR_REQUIREMENTS_FILES', tmp_file))
+ self.assertEqual(['foo', 'bar'],
+ packaging.parse_requirements())
+
+ def test_override_with_env_multiple_files(self):
+ _, tmp_file = tempfile.mkstemp(prefix='openstack', suffix='.setup')
+ with open(tmp_file, 'w') as fh:
+ fh.write("foo\nbar")
+ self.useFixture(
+ fixtures.EnvironmentVariable('PBR_REQUIREMENTS_FILES',
+ "no-such-file," + tmp_file))
+ self.assertEqual(['foo', 'bar'],
+ packaging.parse_requirements())
+
+ def test_index_present(self):
tempdir = tempfile.mkdtemp()
requirements = os.path.join(tempdir, 'requirements.txt')
with open(requirements, 'w') as f:
result = packaging.parse_requirements([requirements])
self.assertEqual([], result)
-
-class TestNestedRequirements(base.BaseTestCase):
-
- def test_nested_requirement(self):
+ def test_nested_requirements(self):
tempdir = tempfile.mkdtemp()
requirements = os.path.join(tempdir, 'requirements.txt')
nested = os.path.join(tempdir, 'nested.txt')
result = packaging.parse_requirements([requirements])
self.assertEqual(['pbr'], result)
+ @mock.patch('warnings.warn')
+ def test_python_version(self, mock_warn):
+ with open("requirements-py%d.txt" % sys.version_info[0],
+ "w") as fh:
+ fh.write("# this is a comment\nfoobar\n# and another one\nfoobaz")
+ self.assertEqual(['foobar', 'foobaz'],
+ packaging.parse_requirements())
+ mock_warn.assert_called_once_with(mock.ANY, DeprecationWarning)
+
+ @mock.patch('warnings.warn')
+ def test_python_version_multiple_options(self, mock_warn):
+ with open("requirements-py1.txt", "w") as fh:
+ fh.write("thisisatrap")
+ with open("requirements-py%d.txt" % sys.version_info[0],
+ "w") as fh:
+ fh.write("# this is a comment\nfoobar\n# and another one\nfoobaz")
+ self.assertEqual(['foobar', 'foobaz'],
+ packaging.parse_requirements())
+ # even though we have multiple offending files, this should only be
+ # called once
+ mock_warn.assert_called_once_with(mock.ANY, DeprecationWarning)
+
+
+class ParseRequirementsTestScenarios(base.BaseTestCase):
+
+ versioned_scenarios = [
+ ('non-versioned', {'versioned': False, 'expected': ['bar']}),
+ ('versioned', {'versioned': True, 'expected': ['bar>=1.2.3']})
+ ]
+
+ scenarios = [
+ ('normal', {'url': "foo\nbar", 'expected': ['foo', 'bar']}),
+ ('normal_with_comments', {
+ 'url': "# this is a comment\nfoo\n# and another one\nbar",
+ 'expected': ['foo', 'bar']}),
+ ('removes_index_lines', {'url': '-f foobar', 'expected': []}),
+ ]
+
+ scenarios = scenarios + testscenarios.multiply_scenarios([
+ ('ssh_egg_url', {'url': 'git+ssh://foo.com/zipball#egg=bar'}),
+ ('git_https_egg_url', {'url': 'git+https://foo.com/zipball#egg=bar'}),
+ ('http_egg_url', {'url': 'https://foo.com/zipball#egg=bar'}),
+ ], versioned_scenarios)
+
+ scenarios = scenarios + testscenarios.multiply_scenarios(
+ [
+ ('git_egg_url',
+ {'url': 'git://foo.com/zipball#egg=bar', 'name': 'bar'})
+ ], [
+ ('non-editable', {'editable': False}),
+ ('editable', {'editable': True}),
+ ],
+ versioned_scenarios)
+
+ def test_parse_requirements(self):
+ tmp_file = tempfile.NamedTemporaryFile()
+ req_string = self.url
+ if hasattr(self, 'editable') and self.editable:
+ req_string = ("-e %s" % req_string)
+ if hasattr(self, 'versioned') and self.versioned:
+ req_string = ("%s-1.2.3" % req_string)
+ with open(tmp_file.name, 'w') as fh:
+ fh.write(req_string)
+ self.assertEqual(self.expected,
+ packaging.parse_requirements([tmp_file.name]))
+
+
+class ParseDependencyLinksTest(base.BaseTestCase):
+
+ def setUp(self):
+ super(ParseDependencyLinksTest, self).setUp()
+ _, self.tmp_file = tempfile.mkstemp(prefix="openstack",
+ suffix=".setup")
+
+ def test_parse_dependency_normal(self):
+ with open(self.tmp_file, "w") as fh:
+ fh.write("http://test.com\n")
+ self.assertEqual(
+ ["http://test.com"],
+ packaging.parse_dependency_links([self.tmp_file]))
+
+ def test_parse_dependency_with_git_egg_url(self):
+ with open(self.tmp_file, "w") as fh:
+ fh.write("-e git://foo.com/zipball#egg=bar")
+ self.assertEqual(
+ ["git://foo.com/zipball#egg=bar"],
+ packaging.parse_dependency_links([self.tmp_file]))
+
class TestVersions(base.BaseTestCase):
expected_requirements = {
None: ['bar', 'requests-aws>=0.1.4'],
":(python_version=='2.6')": ['quux<1.0'],
- ":(python_version=='2.7')": ['Routes>=1.12.3,!=2.0,!=2.1',
+ ":(python_version=='2.7')": ['Routes!=2.0,!=2.1,>=1.12.3',
'requests-kerberos>=0.6'],
'test': ['foo'],
"test:(python_version=='2.7')": ['baz>3.2', 'bar>3.3']
generated_requirements = dict(
pkg_resources.split_sections(requires))
- self.assertEqual(expected_requirements, generated_requirements)
+ # NOTE(dhellmann): We have to spell out the comparison because
+ # the rendering for version specifiers in a range is not
+ # consistent across versions of setuptools.
+
+ for section, expected in expected_requirements.items():
+ exp_parsed = [
+ pkg_resources.Requirement.parse(s)
+ for s in expected
+ ]
+ gen_parsed = [
+ pkg_resources.Requirement.parse(s)
+ for s in generated_requirements[section]
+ ]
+ self.assertEqual(exp_parsed, gen_parsed)
def get_soabi():
from __future__ import print_function
import os
-import sys
-import tempfile
-import testscenarios
try:
import cStringIO as io
self.assertTrue(
os.path.exists(
"contributor/api/fake_package.fake_private_module.rst"))
-
-
-class ParseRequirementsTestScenarios(base.BaseTestCase):
-
- versioned_scenarios = [
- ('non-versioned', {'versioned': False, 'expected': ['bar']}),
- ('versioned', {'versioned': True, 'expected': ['bar>=1.2.3']})
- ]
-
- scenarios = [
- ('normal', {'url': "foo\nbar", 'expected': ['foo', 'bar']}),
- ('normal_with_comments', {
- 'url': "# this is a comment\nfoo\n# and another one\nbar",
- 'expected': ['foo', 'bar']}),
- ('removes_index_lines', {'url': '-f foobar', 'expected': []}),
- ]
-
- scenarios = scenarios + testscenarios.multiply_scenarios([
- ('ssh_egg_url', {'url': 'git+ssh://foo.com/zipball#egg=bar'}),
- ('git_https_egg_url', {'url': 'git+https://foo.com/zipball#egg=bar'}),
- ('http_egg_url', {'url': 'https://foo.com/zipball#egg=bar'}),
- ], versioned_scenarios)
-
- scenarios = scenarios + testscenarios.multiply_scenarios(
- [
- ('git_egg_url',
- {'url': 'git://foo.com/zipball#egg=bar', 'name': 'bar'})
- ], [
- ('non-editable', {'editable': False}),
- ('editable', {'editable': True}),
- ],
- versioned_scenarios)
-
- def test_parse_requirements(self):
- tmp_file = tempfile.NamedTemporaryFile()
- req_string = self.url
- if hasattr(self, 'editable') and self.editable:
- req_string = ("-e %s" % req_string)
- if hasattr(self, 'versioned') and self.versioned:
- req_string = ("%s-1.2.3" % req_string)
- with open(tmp_file.name, 'w') as fh:
- fh.write(req_string)
- self.assertEqual(self.expected,
- packaging.parse_requirements([tmp_file.name]))
-
-
-class ParseRequirementsTest(base.BaseTestCase):
-
- def setUp(self):
- super(ParseRequirementsTest, self).setUp()
- (fd, self.tmp_file) = tempfile.mkstemp(prefix='openstack',
- suffix='.setup')
-
- def test_parse_requirements_override_with_env(self):
- with open(self.tmp_file, 'w') as fh:
- fh.write("foo\nbar")
- self.useFixture(
- fixtures.EnvironmentVariable('PBR_REQUIREMENTS_FILES',
- self.tmp_file))
- self.assertEqual(['foo', 'bar'],
- packaging.parse_requirements())
-
- def test_parse_requirements_override_with_env_multiple_files(self):
- with open(self.tmp_file, 'w') as fh:
- fh.write("foo\nbar")
- self.useFixture(
- fixtures.EnvironmentVariable('PBR_REQUIREMENTS_FILES',
- "no-such-file," + self.tmp_file))
- self.assertEqual(['foo', 'bar'],
- packaging.parse_requirements())
-
- def test_get_requirement_from_file_empty(self):
- actual = packaging.get_reqs_from_files([])
- self.assertEqual([], actual)
-
- def test_parse_requirements_python_version(self):
- with open("requirements-py%d.txt" % sys.version_info[0],
- "w") as fh:
- fh.write("# this is a comment\nfoobar\n# and another one\nfoobaz")
- self.assertEqual(['foobar', 'foobaz'],
- packaging.parse_requirements())
-
- def test_parse_requirements_right_python_version(self):
- with open("requirements-py1.txt", "w") as fh:
- fh.write("thisisatrap")
- with open("requirements-py%d.txt" % sys.version_info[0],
- "w") as fh:
- fh.write("# this is a comment\nfoobar\n# and another one\nfoobaz")
- self.assertEqual(['foobar', 'foobaz'],
- packaging.parse_requirements())
-
-
-class ParseDependencyLinksTest(base.BaseTestCase):
-
- def setUp(self):
- super(ParseDependencyLinksTest, self).setUp()
- (fd, self.tmp_file) = tempfile.mkstemp(prefix="openstack",
- suffix=".setup")
-
- def test_parse_dependency_normal(self):
- with open(self.tmp_file, "w") as fh:
- fh.write("http://test.com\n")
- self.assertEqual(
- ["http://test.com"],
- packaging.parse_dependency_links([self.tmp_file]))
-
- def test_parse_dependency_with_git_egg_url(self):
- with open(self.tmp_file, "w") as fh:
- fh.write("-e git://foo.com/zipball#egg=bar")
- self.assertEqual(
- ["git://foo.com/zipball#egg=bar"],
- packaging.parse_dependency_links([self.tmp_file]))
baz>=3.2
foo
""",
- 'expected_extra_requires': {'first': ['foo', 'bar==1.0'],
- 'second': ['baz>=3.2', 'foo']}
+ 'expected_extra_requires': {
+ 'first': ['foo', 'bar==1.0'],
+ 'second': ['baz>=3.2', 'foo'],
+ 'test': ['requests-mock'],
+ "test:(python_version=='2.6')": ['ordereddict'],
+ }
}),
('with_markers', {
'config_text': """
lambda: from_pip_string('1.2.3.post5.dev6'),
matchers.raises(ValueError))
+ def test_from_pip_string_v_version(self):
+ parsed = from_pip_string('v1.2.3')
+ expected = version.SemanticVersion(1, 2, 3)
+ self.expectThat(expected, matchers.Equals(parsed))
+
+ expected = version.SemanticVersion(1, 2, 3, 'a', 5, dev_count=6)
+ parsed = from_pip_string('V1.2.3.0a4.post6')
+ self.expectThat(expected, matchers.Equals(parsed))
+
+ self.expectThat(
+ lambda: from_pip_string('x1.2.3'),
+ matchers.raises(ValueError))
+
def test_from_pip_string_legacy_nonzero_lead_in(self):
# reported in bug 1361251
expected = version.SemanticVersion(
author = OpenStack
author-email = openstack-dev@lists.openstack.org
home-page = http://pypi.python.org/pypi/pbr
+project_urls =
+ Bug Tracker = https://bugs.launchpad.net/pbr/
+ Documentation = https://docs.openstack.org/pbr/
+ Source Code = https://git.openstack.org/cgit/openstack-dev/pbr/
summary = Test package for testing pbr
description-file =
README.txt
CHANGES.txt
+description-content-type = text/plain; charset=UTF-8
requires-python = >=2.5
requires-dist =
# pbr_testpackage._setup_hooks.test_hook_1
# pbr_testpackage._setup_hooks.test_hook_2
commands = pbr_testpackage._setup_hooks.test_command
-
-[build_ext]
-#pre-hook.test_pre_hook = pbr_testpackage._setup_hooks.test_pre_hook
-#post-hook.test_post_hook = pbr_testpackage._setup_hooks.test_post_hook
ordereddict;python_version=='2.6'
+requests-mock
"maintainer": ("metadata",),
"maintainer_email": ("metadata",),
"url": ("metadata", "home_page"),
+ "project_urls": ("metadata",),
"description": ("metadata", "summary"),
"keywords": ("metadata",),
"long_description": ("metadata", "description"),
+ "long_description_content_type": ("metadata", "description_content_type"),
"download_url": ("metadata",),
"classifiers": ("metadata", "classifier"),
"platforms": ("metadata", "platform"), # **
"tests_require",
"cmdclass")
+# setup() arguments that can have mapping values in setup.cfg
+MAP_FIELDS = ("project_urls",)
+
# setup() arguments that contain boolean values
BOOL_FIELDS = ("use_2to3", "zip_safe", "include_package_data")
This method uses an existing setup.cfg to generate a dictionary of
keywords that can be used by distutils.core.setup(kwargs**).
- :param file:
+ :param path:
The setup.cfg path.
- :parm script_args:
+ :param script_args:
List of commands setup.py was called with.
:raises DistutilsFileError:
When the setup.cfg file is not found.
if entry_points:
kwargs['entry_points'] = entry_points
- wrap_commands(kwargs)
-
# Handle the [files]/extra_files option
files_extra_files = has_get_option(config, 'files', 'extra_files')
if files_extra_files:
in_cfg_value = split_csv(in_cfg_value)
if arg in MULTI_FIELDS:
in_cfg_value = split_multiline(in_cfg_value)
+ elif arg in MAP_FIELDS:
+ in_cfg_map = {}
+ for i in split_multiline(in_cfg_value):
+ k, v = i.split('=')
+ in_cfg_map[k.strip()] = v.strip()
+ in_cfg_value = in_cfg_map
elif arg in BOOL_FIELDS:
# Provide some flexibility here...
if in_cfg_value.lower() in ('true', 't', '1', 'yes', 'y'):
if 'extras' in config:
requirement_pattern = '(?P<package>[^:]*):?(?P<env_marker>[^#]*?)(?:\s*#.*)?$'
extras = config['extras']
+ # Add contents of test-requirements, if any, into an extra named
+ # 'test' if one does not already exist.
+ if 'test' not in extras:
+ from pbr import packaging
+ extras['test'] = "\n".join(packaging.parse_requirements(
+ packaging.TEST_REQUIREMENTS_FILES)).replace(';', ':')
+
for extra in extras:
extra_requirements = []
requirements = split_multiline(extras[extra])
for option, value in config['entry_points'].items())
-def wrap_commands(kwargs):
- dist = st_dist.Distribution()
-
- # This should suffice to get the same config values and command classes
- # that the actual Distribution will see (not counting cmdclass, which is
- # handled below)
- dist.parse_config_files()
-
- # Setuptools doesn't patch get_command_list, and as such we do not get
- # extra commands from entry_points. As we need to be compatable we deal
- # with this here.
- for ep in pkg_resources.iter_entry_points('distutils.commands'):
- if ep.name not in dist.cmdclass:
- if hasattr(ep, 'resolve'):
- cmdclass = ep.resolve()
- else:
- # Old setuptools does not have ep.resolve, and load with
- # arguments is depricated in 11+. Use resolve, 12+, if we
- # can, otherwise fall back to load.
- # Setuptools 11 will throw a deprication warning, as it
- # uses _load instead of resolve.
- cmdclass = ep.load(False)
- dist.cmdclass[ep.name] = cmdclass
-
- for cmd, _ in dist.get_command_list():
- hooks = {}
- for opt, val in dist.get_option_dict(cmd).items():
- val = val[1]
- if opt.startswith('pre_hook.') or opt.startswith('post_hook.'):
- hook_type, alias = opt.split('.', 1)
- hook_dict = hooks.setdefault(hook_type, {})
- hook_dict[alias] = val
- if not hooks:
- continue
-
- if 'cmdclass' in kwargs and cmd in kwargs['cmdclass']:
- cmdclass = kwargs['cmdclass'][cmd]
- else:
- cmdclass = dist.get_command_class(cmd)
-
- new_cmdclass = wrap_command(cmd, cmdclass, hooks)
- kwargs.setdefault('cmdclass', {})[cmd] = new_cmdclass
-
-
-def wrap_command(cmd, cmdclass, hooks):
- def run(self, cmdclass=cmdclass):
- self.run_command_hooks('pre_hook')
- cmdclass.run(self)
- self.run_command_hooks('post_hook')
-
- return type(cmd, (cmdclass, object),
- {'run': run, 'run_command_hooks': run_command_hooks,
- 'pre_hook': hooks.get('pre_hook'),
- 'post_hook': hooks.get('post_hook')})
-
-
-def run_command_hooks(cmd_obj, hook_kind):
- """Run hooks registered for that command and phase.
-
- *cmd_obj* is a finalized command object; *hook_kind* is either
- 'pre_hook' or 'post_hook'.
- """
-
- if hook_kind not in ('pre_hook', 'post_hook'):
- raise ValueError('invalid hook kind: %r' % hook_kind)
-
- hooks = getattr(cmd_obj, hook_kind, None)
-
- if hooks is None:
- return
-
- for hook in hooks.values():
- if isinstance(hook, str):
- try:
- hook_obj = resolve_name(hook)
- except ImportError:
- err = sys.exc_info()[1] # For py3k
- raise errors.DistutilsModuleError('cannot find hook %s: %s' %
- (hook,err))
- else:
- hook_obj = hook
-
- if not hasattr(hook_obj, '__call__'):
- raise errors.DistutilsOptionError('hook %r is not callable' % hook)
-
- log.info('running %s %s for command %s',
- hook_kind, hook, cmd_obj.get_command_name())
-
- try :
- hook_obj(cmd_obj)
- except:
- e = sys.exc_info()[1]
- log.error('hook %s raised exception: %s\n' % (hook, e))
- log.error(traceback.format_exc())
- sys.exit(1)
-
-
def has_get_option(config, section, option):
if section in config and option in config[section]:
return config[section][option]
value = [element for element in
(line.strip() for line in value.split('\n'))
- if element]
+ if element and not element.startswith('#')]
return value
return value
-def monkeypatch_method(cls):
- """A function decorator to monkey-patch a method of the same name on the
- given class.
- """
-
- def wrapper(func):
- orig = getattr(cls, func.__name__, None)
- if orig and not hasattr(orig, '_orig'): # Already patched
- setattr(func, '_orig', orig)
- setattr(cls, func.__name__, func)
- return func
-
- return wrapper
-
-
# The following classes are used to hack Distribution.command_options a bit
class DefaultGetDict(defaultdict):
"""Like defaultdict, but the get() method also sets and returns the default
if default is None:
default = self.default_factory()
return super(DefaultGetDict, self).setdefault(key, default)
-
-
-class IgnoreDict(dict):
- """A dictionary that ignores any insertions in which the key is a string
- matching any string in `ignore`. The ignore list can also contain wildcard
- patterns using '*'.
- """
-
- def __init__(self, ignore):
- self.__ignore = re.compile(r'(%s)' % ('|'.join(
- [pat.replace('*', '.*')
- for pat in ignore])))
-
- def __setitem__(self, key, val):
- if self.__ignore.match(key):
- return
- super(IgnoreDict, self).__setitem__(key, val)
@classmethod
def _from_pip_string_unsafe(klass, version_string):
# Versions need to start numerically, ignore if not
+ version_string = version_string.lstrip('vV')
if not version_string[:1].isdigit():
raise ValueError("Invalid version %r" % version_string)
input_components = version_string.split('.')
--- /dev/null
+---
+deprecations:
+ - |
+ Support for ``pyN``-suffixed requirement files has been deprecated:
+ environment markers should be used instead.
--- /dev/null
+---
+deprecations:
+ - |
+ *testr* and *nose* integration has been deprecated. This feature allowed
+ *pbr* to dynamically configure the test runner used when running
+ ``setup.py test``. However, this target has fallen out of favour in both
+ the OpenStack and broader Python ecosystem, and both *testr* and *nose*
+ offer native setuptools commands that can be manually aliased to ``test``
+ on a per-project basis, if necessary. This feature will be removed in a
+ future release.
--- /dev/null
+---
+upgrade:
+ - |
+ Support for entry point command hooks has been removed. This feature was
+ poorly tested, poorly documented, and broken in some environments.
+ Support for global hooks is not affected.
--- /dev/null
+---
+features:
+ - |
+ Support version parsing of git tag with the ``v<semver>`` pattern
+ (or ``V<semver>``), in addition to ``<semver>``.
--- /dev/null
+# -*- coding: utf-8 -*-
+# 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.
+
+# pbr Release Notes documentation build configuration file
+
+
+# -- General configuration ------------------------------------------------
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+ 'openstackdocstheme',
+ 'reno.sphinxext',
+]
+
+# The master toctree document.
+master_doc = 'index'
+
+# Release notes are version independent
+# The short X.Y version.
+version = ''
+# The full version, including alpha/beta/rc tags.
+release = ''
+
+
+# -- Options for HTML output ----------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+html_theme = 'openstackdocs'
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+html_last_updated_fmt = '%Y-%m-%d %H:%M'
+
+
+# -- Options for openstackdocstheme ---------------------------------------
+
+repository_name = 'openstack-dev/pbr'
+bug_project = 'pbr'
+bug_tag = ''
--- /dev/null
+=================
+pbr Release Notes
+=================
+
+.. toctree::
+ :maxdepth: 1
+
+ unreleased
--- /dev/null
+============================
+Current Series Release Notes
+============================
+
+.. release-notes::
summary = Python Build Reasonableness
description-file =
README.rst
-home-page = http://docs.openstack.org/developer/pbr/
+description-content-type = text/x-rst; charset=UTF-8
+home-page = https://docs.openstack.org/pbr/latest/
+project_urls =
+ Bug Tracker = https://bugs.launchpad.net/pbr/
+ Documentation = https://docs.openstack.org/pbr/
+ Source Code = https://git.openstack.org/cgit/openstack-dev/pbr/
requires-python = >=2.6
classifier =
Development Status :: 5 - Production/Stable
Operating System :: OS Independent
Programming Language :: Python
Programming Language :: Python :: 2
- Programming Language :: Python :: 2.6
Programming Language :: Python :: 2.7
Programming Language :: Python :: 3
Programming Language :: Python :: 3.3
autodoc_tree_excludes =
setup.py
pbr/tests/
+api_doc_dir = reference/api
[entry_points]
distutils.setup_keywords =
all-files = 1
build-dir = doc/build
source-dir = doc/source
+warning-is-error = 1
[wheel]
universal = 1
coverage!=4.4,>=4.0 # Apache-2.0
fixtures>=3.0.0 # Apache-2.0/BSD
hacking!=0.13.0,<0.14,>=0.12.0 # Apache-2.0
-mock>=2.0 # BSD
-python-subunit>=0.0.18 # Apache-2.0/BSD
-sphinx!=1.6.1,>=1.5.1 # BSD
-oslosphinx>=4.7.0 # Apache-2.0
-six>=1.9.0 # MIT
+mock>=2.0.0 # BSD
+python-subunit>=1.0.0 # Apache-2.0/BSD
+sphinx!=1.6.6,!=1.6.7,>=1.6.2 # BSD
+openstackdocstheme>=1.18.1 # Apache-2.0
+reno>=2.5.0 # Apache-2.0
+six>=1.10.0 # MIT
testrepository>=0.0.18 # Apache-2.0/BSD
-testresources>=0.2.4 # Apache-2.0/BSD
+testresources>=2.0.0 # Apache-2.0/BSD
testscenarios>=0.4 # Apache-2.0/BSD
-testtools>=1.4.0 # MIT
-virtualenv>=13.1.0 # MIT
+testtools>=2.2.0 # MIT
+virtualenv>=14.0.6 # MIT
+++ /dev/null
-#!/usr/bin/env bash
-
-# Client constraint file contains this client version pin that is in conflict
-# with installing the client from source. We should remove the version pin in
-# the constraints file before applying it for from-source installation.
-
-CONSTRAINTS_FILE="$1"
-shift 1
-
-set -e
-
-# NOTE(tonyb): Place this in the tox enviroment's log dir so it will get
-# published to logs.openstack.org for easy debugging.
-localfile="$VIRTUAL_ENV/log/upper-constraints.txt"
-
-if [[ "$CONSTRAINTS_FILE" != http* ]]; then
- CONSTRAINTS_FILE="file://$CONSTRAINTS_FILE"
-fi
-# NOTE(tonyb): need to add curl to bindep.txt if the project supports bindep
-curl "$CONSTRAINTS_FILE" --insecure --progress-bar --output "$localfile"
-
-pip install -c"$localfile" openstack-requirements
-
-# This is the main purpose of the script: Allow local installation of
-# the current repo. It is listed in constraints file and thus any
-# install will be constrained and we need to unconstrain it.
-edit-constraints "$localfile" -- "$CLIENT_NAME"
-
-pip install -c"$localfile" -U "$@"
-exit $?
--- /dev/null
+#!/usr/bin/env bash
+
+rm -rf releasenotes/build
+
+sphinx-build -a -E -W \
+ -d releasenotes/build/doctrees \
+ -b html \
+ releasenotes/source releasenotes/build/html
+BUILD_RESULT=$?
+
+UNCOMMITTED_NOTES=$(git status --porcelain | \
+ awk '$1 ~ "M|A|??" && $2 ~ /releasenotes\/notes/ {print $2}')
+
+if [ "${UNCOMMITTED_NOTES}" ]
+then
+ cat <<EOF
+
+REMINDER: The following changes to release notes have not been committed:
+
+${UNCOMMITTED_NOTES}
+
+While that may be intentional, keep in mind that release notes are built from
+committed changes, not the working directory.
+
+EOF
+fi
+
+exit ${BUILD_RESULT}
[tox]
minversion = 2.0
-envlist = py33,py34,py35,py26,py27,pypy,pep8,docs
+envlist = py33,py34,py35,py36,py27,pypy,pep8,docs
[testenv]
usedevelop = True
-install_command = {toxinidir}/tools/tox_install.sh {env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} {opts} {packages}
+whitelist_externals = bash
+install_command = pip install {opts} {packages}
passenv = PBR_INTEGRATION PIPFLAGS PIPVERSION PBRVERSION REPODIR WHEELHOUSE PROJECTS OS_TEST_TIMEOUT OS_STDOUT_CAPTURE OS_STDERR_CAPTURE
-setenv =
- VIRTUAL_ENV={envdir}
- CLIENT_NAME=pbr
-deps = -r{toxinidir}/test-requirements.txt
+deps =
+ -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
+ -r{toxinidir}/test-requirements.txt
commands =
python setup.py test --testr-args='{posargs}'
[testenv:docs]
commands = python setup.py build_sphinx
+[testenv:releasenotes]
+commands = bash -c {toxinidir}/tools/tox_releasenotes.sh
+
[testenv:cover]
commands =
python setup.py test --coverage