doc: Rework features doc
Break this document into sections and expand upon some of these. Change-Id: Ia6a3eed984ce4257cce9df0997e6be2d8d3bc683 Signed-off-by: Stephen Finucane <sfinucan@redhat.com>
This commit is contained in:
parent
4c775e7890
commit
2493b3ad70
|
@ -2,32 +2,32 @@
|
||||||
pbr - Python Build Reasonableness
|
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
|
*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
|
fill in default values and provide more sensible behaviors, and then feeds the
|
||||||
the results in as the arguments to a call to `setup.py` - so the heavy
|
results in as the arguments to a call to ``setup.py`` - so the heavy lifting of
|
||||||
lifting of handling python packaging needs is still being done by
|
handling Python packaging needs is still being done by *setuptools*.
|
||||||
`setuptools`.
|
|
||||||
|
|
||||||
Note that we don't support the `easy_install` aspects of setuptools: while
|
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
|
we depend on ``setup_requires``, for any ``install_requires`` we recommend that
|
||||||
be installed prior to running `setup.py install` - either by hand, or by using
|
they be installed prior to running ``setup.py install`` - either by hand, or by
|
||||||
an install tool such as `pip`.
|
using an install tool such as *pip*.
|
||||||
|
|
||||||
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
|
* **Version**: Manage version number based on git revisions and tags
|
||||||
* **AUTHORS**: Generate AUTHORS file from git log
|
* **AUTHORS**: Generate AUTHORS file from git log
|
||||||
* **ChangeLog**: Generate ChangeLog from git log
|
* **ChangeLog**: Generate ChangeLog from git log
|
||||||
* **Manifest**: Generate a sensible manifest from git files and some standard
|
* **Manifest**: Generate a sensible manifest from git files and some standard
|
||||||
files
|
files
|
||||||
* **Sphinx Autodoc**: Generate autodoc stub files for your whole module
|
|
||||||
* **Requirements**: Store your dependencies in a pip requirements file
|
* **Requirements**: Store your dependencies in a pip requirements file
|
||||||
* **long_description**: Use your README file as a long_description
|
* **long_description**: Use your README file as a long_description
|
||||||
* **Smart find_packages**: Smartly find packages under your root package
|
* **Smart find_packages**: Smartly find packages under your root package
|
||||||
|
* **Sphinx Autodoc**: Generate autodoc stub files for your whole module
|
||||||
|
|
||||||
Contents:
|
Contents
|
||||||
|
--------
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
|
@ -35,10 +35,3 @@ Contents:
|
||||||
user/index
|
user/index
|
||||||
reference/index
|
reference/index
|
||||||
contributor/index
|
contributor/index
|
||||||
|
|
||||||
.. rubric:: Indices and tables
|
|
||||||
|
|
||||||
* :ref:`genindex`
|
|
||||||
* :ref:`modindex`
|
|
||||||
* :ref:`search`
|
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,117 @@
|
||||||
Features
|
Features
|
||||||
==========
|
==========
|
||||||
|
|
||||||
Version
|
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.
|
||||||
|
|
||||||
Versions can be managed two ways - postversioning and preversioning.
|
.. code-block:: none
|
||||||
Postversioning is the default, and preversioning is enabled by setting
|
|
||||||
``version`` in the setup.cfg ``metadata`` section. In both cases version
|
$ tree -L 1
|
||||||
strings are inferred from git.
|
.
|
||||||
|
├── 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
|
If the currently checked out revision is tagged, that tag is used as
|
||||||
the version.
|
the version.
|
||||||
|
@ -19,35 +123,40 @@ version.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
``pbr`` support bare version tag (ex: ``0.1.0``) and version prefixed with
|
*pbr* supports both bare version tag (e.g. ``0.1.0``) and version prefixed
|
||||||
``v`` or ``V`` (ex: ``v0.1.0``)
|
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:
|
||||||
|
|
||||||
We then walk git history back to the last release. Within each commit we look
|
- ``feature``
|
||||||
for a Sem-Ver: pseudo header, and if found parse it looking for keywords.
|
- ``api-break``
|
||||||
Unknown symbols are not an error (so that folk can't wedge pbr or break their
|
- ``deprecation``
|
||||||
tree), but we will emit an info level warning message. Known symbols:
|
- ``bugfix``
|
||||||
``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
|
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.
|
version.
|
||||||
|
|
||||||
If preversioning is in use we check that the version set in the metadata
|
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
|
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
|
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.
|
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
|
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
|
release and include the current Git SHA to disambiguate multiple dev versions
|
||||||
with the same number of commits since the release.
|
with the same number of commits since the release.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
`pbr` expects git tags to be signed for use in calculating versions
|
*pbr* expects Git tags to be signed for use in calculating versions.
|
||||||
|
|
||||||
The versions are expected to be compliant with :doc:`semver`.
|
The versions are expected to be compliant with :doc:`semver`.
|
||||||
|
|
||||||
|
@ -56,65 +165,148 @@ package and present it in various forms - ``debian_version()``,
|
||||||
``release_string()``, ``rpm_string()``, ``version_string()``, or
|
``release_string()``, ``rpm_string()``, ``version_string()``, or
|
||||||
``version_tuple()``.
|
``version_tuple()``.
|
||||||
|
|
||||||
AUTHORS and ChangeLog
|
Long Description
|
||||||
---------------------
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Why keep an `AUTHORS` or a `ChangeLog` file when git already has all of the
|
.. admonition:: Summary
|
||||||
information you need? `AUTHORS` generation supports filtering/combining based
|
|
||||||
on a standard `.mailmap` file.
|
|
||||||
|
|
||||||
Manifest
|
*pbr* can extract the contents of a ``README`` and use this as your long
|
||||||
--------
|
description
|
||||||
|
|
||||||
Just like `AUTHORS` and `ChangeLog`, why keep a list of files you wish to
|
There is no need to maintain two long descriptions and your ``README`` file is
|
||||||
include when you can find many of these in git. `MANIFEST.in` generation
|
probably a good long_description. So we'll just inject the contents of your
|
||||||
ensures almost all files stored in git, with the exception of `.gitignore`,
|
``README.rst``, ``README.txt`` or ``README`` file into your empty
|
||||||
`.gitreview` and `.pyc` files, are automatically included in your
|
``long_description``.
|
||||||
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
|
You can also specify the exact file you want to use using the
|
||||||
--------------
|
``description-file`` parameter.
|
||||||
|
|
||||||
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 :ref:`pbr-setup-cfg` section of the configuration file for
|
|
||||||
details on configuring your project for autodoc.
|
|
||||||
|
|
||||||
Requirements
|
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
|
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.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
|
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.
|
populate a *virtualenv* for testing or to just install everything you need.
|
||||||
Duplicating the information, though, is super lame. To solve this issue, `pbr`
|
Duplicating the information, though, is super lame. To solve this issue, *pbr*
|
||||||
will let you use `requirements.txt`-format files to describe the requirements
|
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,
|
for your project and will then parse these files, split them up appropriately,
|
||||||
and inject them into the `install_requires`, `tests_require` and/or
|
and inject them into the ``install_requires``, ``tests_require`` and/or
|
||||||
`dependency_links` arguments to `setup`. Voila!
|
``dependency_links`` arguments to ``setup``. Voila!
|
||||||
|
|
||||||
You can also have a requirement file for each specific major version of Python.
|
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
|
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.
|
``requirements-py3.txt`` and it will be used instead.
|
||||||
|
|
||||||
Finally, it is possible to specify groups of optional dependencies, or
|
Finally, it is possible to specify groups of optional dependencies, or
|
||||||
:ref:`"extra" requirements <extra-requirements>`, in your `setup.cfg`
|
:ref:`"extra" requirements <extra-requirements>`, in your ``setup.cfg`` rather
|
||||||
rather than `setup.py`.
|
than ``setup.py``.
|
||||||
|
|
||||||
long_description
|
Automatic File Generation
|
||||||
----------------
|
-------------------------
|
||||||
|
|
||||||
There is no need to maintain two long descriptions- and your README file is
|
.. admonition:: Summary
|
||||||
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
|
*pbr* can automatically generate a couple of files, which would normally
|
||||||
for you.
|
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
|
||||||
|
|
|
@ -10,4 +10,3 @@
|
||||||
semver
|
semver
|
||||||
compatibility
|
compatibility
|
||||||
history
|
history
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue