Merge "Integrate a setuptools command"
This commit is contained in:
commit
52d4c1961d
|
@ -48,6 +48,9 @@ doc/build
|
||||||
AUTHORS
|
AUTHORS
|
||||||
ChangeLog
|
ChangeLog
|
||||||
|
|
||||||
|
# reno generates these
|
||||||
|
RELEASENOTES.rst
|
||||||
|
|
||||||
# Editors
|
# Editors
|
||||||
*~
|
*~
|
||||||
.*.swp
|
.*.swp
|
||||||
|
|
|
@ -8,4 +8,5 @@
|
||||||
design
|
design
|
||||||
usage
|
usage
|
||||||
sphinxext
|
sphinxext
|
||||||
|
setuptools
|
||||||
examples
|
examples
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
==============================
|
||||||
|
Python Packaging Integration
|
||||||
|
==============================
|
||||||
|
|
||||||
|
*reno* supports integration with `setuptools`_ and *setuptools* derivatives
|
||||||
|
like *pbr* through a custom command - ``build_reno``.
|
||||||
|
|
||||||
|
.. _pbr: http://docs.openstack.org/developer/pbr/
|
||||||
|
.. _setuptools: https://setuptools.readthedocs.io/en/latest/
|
||||||
|
|
||||||
|
Using setuptools integration
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
To enable the ``build_reno`` command, you simply need to install *reno*. Once
|
||||||
|
done, simply run:
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
python setup.py build_reno
|
||||||
|
|
||||||
|
You can configure the command in ``setup.py`` or ``setup.cfg``. To configure it
|
||||||
|
from ``setup.py``, add a ``build_reno`` section to ``command_options`` like so:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from setuptools import setup
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name='mypackage',
|
||||||
|
version='0.1',
|
||||||
|
...
|
||||||
|
command_options={
|
||||||
|
'build_reno': {
|
||||||
|
'output_file': ('setup.py', 'RELEASENOTES.txt'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
To configure the command from ``setup.cfg``, add a ``build_reno`` section. For
|
||||||
|
example:
|
||||||
|
|
||||||
|
.. code-block:: ini
|
||||||
|
|
||||||
|
[build_reno]
|
||||||
|
output-file = RELEASENOTES.txt
|
||||||
|
|
||||||
|
Options for setuptools integration
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
These options related to the *setuptools* integration only. For general
|
||||||
|
configuration of *reno*, refer to :ref:`configuration`.
|
||||||
|
|
||||||
|
``repo-root``
|
||||||
|
The root directory of the Git repository; defaults to ``.``
|
||||||
|
|
||||||
|
``rel-notes-dir``
|
||||||
|
The parent directory; defaults to ``releasenotes``
|
||||||
|
|
||||||
|
``output-file``
|
||||||
|
The filename of the release notes file; defaults to ``RELEASENOTES.rst``
|
|
@ -176,6 +176,8 @@ mistakes. The command exits with an error code if there are any
|
||||||
mistakes, so it can be used in a build pipeline to force some
|
mistakes, so it can be used in a build pipeline to force some
|
||||||
correctness.
|
correctness.
|
||||||
|
|
||||||
|
.. _configuration:
|
||||||
|
|
||||||
Configuring Reno
|
Configuring Reno
|
||||||
================
|
================
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Add a ``build_reno`` setuptools command that allows users to generate a
|
||||||
|
release notes document and a reno cache file that can be used to build
|
||||||
|
release notes documents without the full Git history present.
|
|
@ -11,8 +11,11 @@
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
RELEASE_NOTES_SUBDIR = 'releasenotes'
|
RELEASE_NOTES_SUBDIR = 'releasenotes'
|
||||||
|
|
||||||
NOTES_SUBDIR = 'notes'
|
NOTES_SUBDIR = 'notes'
|
||||||
|
|
||||||
PRELUDE_SECTION_NAME = 'prelude'
|
PRELUDE_SECTION_NAME = 'prelude'
|
||||||
|
|
||||||
# This is a format string, so it needs to be formatted wherever it is used.
|
# This is a format string, so it needs to be formatted wherever it is used.
|
||||||
TEMPLATE = """\
|
TEMPLATE = """\
|
||||||
---
|
---
|
||||||
|
@ -81,3 +84,9 @@ other:
|
||||||
available in another section, such as the prelude. This may mean repeating
|
available in another section, such as the prelude. This may mean repeating
|
||||||
some details.
|
some details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# default filename of a release notes file generated by the setuptool extension
|
||||||
|
RELEASE_NOTES_FILENAME = 'RELEASENOTES.rst'
|
||||||
|
|
||||||
|
# default path to the root of the repo, used by the setuptools extension
|
||||||
|
REPO_ROOT = '.'
|
||||||
|
|
|
@ -0,0 +1,138 @@
|
||||||
|
# Copyright 2017, Red Hat, Inc.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
"""Custom distutils command.
|
||||||
|
|
||||||
|
For more information, refer to the distutils and setuptools source:
|
||||||
|
|
||||||
|
- https://github.com/python/cpython/blob/3.6/Lib/distutils/cmd.py
|
||||||
|
- https://github.com/pypa/setuptools/blob/v36.0.0/setuptools/command/sdist.py
|
||||||
|
"""
|
||||||
|
|
||||||
|
from distutils import cmd
|
||||||
|
from distutils import errors
|
||||||
|
from distutils import log
|
||||||
|
|
||||||
|
import six
|
||||||
|
|
||||||
|
from reno import cache
|
||||||
|
from reno import config
|
||||||
|
from reno import defaults
|
||||||
|
from reno import formatter
|
||||||
|
from reno import loader
|
||||||
|
|
||||||
|
COMMAND_NAME = 'build_reno' # duplicates what's found in setup.cfg
|
||||||
|
|
||||||
|
|
||||||
|
def load_config(distribution):
|
||||||
|
"""Utility method to parse distutils/setuptools configuration.
|
||||||
|
|
||||||
|
This is for use by other libraries to extract the command configuration.
|
||||||
|
|
||||||
|
:param distribution: A :class:`distutils.dist.Distribution` object
|
||||||
|
:returns: A tuple of a :class:`reno.config.Config` object, the output path
|
||||||
|
of the human-readable release notes file, and the output file of the
|
||||||
|
reno cache file
|
||||||
|
"""
|
||||||
|
option_dict = distribution.get_option_dict(COMMAND_NAME)
|
||||||
|
|
||||||
|
if option_dict.get('repo_root') is not None:
|
||||||
|
repo_root = option_dict.get('repo_root')[1]
|
||||||
|
else:
|
||||||
|
repo_root = defaults.REPO_ROOT
|
||||||
|
|
||||||
|
if option_dict.get('rel_notes_dir') is not None:
|
||||||
|
rel_notes_dir = option_dict.get('rel_notes_dir')[1]
|
||||||
|
else:
|
||||||
|
rel_notes_dir = defaults.RELEASE_NOTES_SUBDIR
|
||||||
|
|
||||||
|
if option_dict.get('output_file') is not None:
|
||||||
|
output_file = option_dict.get('output_file')[1]
|
||||||
|
else:
|
||||||
|
output_file = defaults.RELEASE_NOTES_FILENAME
|
||||||
|
|
||||||
|
conf = config.Config(repo_root, rel_notes_dir)
|
||||||
|
cache_file = loader.get_cache_filename(conf)
|
||||||
|
|
||||||
|
return (conf, output_file, cache_file)
|
||||||
|
|
||||||
|
|
||||||
|
class BuildReno(cmd.Command):
|
||||||
|
"""Distutils command to build reno release notes.
|
||||||
|
|
||||||
|
The release note build can be triggered from distutils, and some
|
||||||
|
configuration can be included in ``setup.py`` or ``setup.cfg`` instead of
|
||||||
|
being specified from the command-line.
|
||||||
|
"""
|
||||||
|
description = 'Build reno release notes'
|
||||||
|
user_options = [
|
||||||
|
('repo-root=', None, 'the root directory of the Git repository; '
|
||||||
|
'defaults to "."'),
|
||||||
|
('rel-notes-dir=', None, 'the parent directory; defaults to '
|
||||||
|
'"releasenotes"'),
|
||||||
|
('output-file=', None, 'the filename of the release notes file'),
|
||||||
|
]
|
||||||
|
|
||||||
|
def initialize_options(self):
|
||||||
|
self.repo_root = None
|
||||||
|
self.rel_notes_dir = None
|
||||||
|
self.output_file = None
|
||||||
|
|
||||||
|
def finalize_options(self):
|
||||||
|
if self.repo_root is None:
|
||||||
|
self.repo_root = defaults.REPO_ROOT
|
||||||
|
|
||||||
|
if self.rel_notes_dir is None:
|
||||||
|
self.rel_notes_dir = defaults.RELEASE_NOTES_SUBDIR
|
||||||
|
|
||||||
|
if self.output_file is None:
|
||||||
|
self.output_file = defaults.RELEASE_NOTES_FILENAME
|
||||||
|
|
||||||
|
# Overriding distutils' Command._ensure_stringlike which doesn't support
|
||||||
|
# unicode, causing finalize_options to fail if invoked again. Workaround
|
||||||
|
# for http://bugs.python.org/issue19570
|
||||||
|
def _ensure_stringlike(self, option, what, default=None):
|
||||||
|
# type: (unicode, unicode, Any) -> Any
|
||||||
|
val = getattr(self, option)
|
||||||
|
if val is None:
|
||||||
|
setattr(self, option, default)
|
||||||
|
return default
|
||||||
|
elif not isinstance(val, six.string_types):
|
||||||
|
raise errors.DistutilsOptionError("'%s' must be a %s (got `%s`)"
|
||||||
|
% (option, what, val))
|
||||||
|
return val
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
conf = config.Config(self.repo_root, self.rel_notes_dir)
|
||||||
|
|
||||||
|
# Generate the cache using the configuration options found
|
||||||
|
# in the release notes directory and the default output
|
||||||
|
# filename.
|
||||||
|
cache_filename = cache.write_cache_db(
|
||||||
|
conf=conf,
|
||||||
|
versions_to_include=[], # include all versions
|
||||||
|
outfilename=None, # generate the default name
|
||||||
|
)
|
||||||
|
log.info('wrote cache file to %s', cache_filename)
|
||||||
|
|
||||||
|
ldr = loader.Loader(conf)
|
||||||
|
text = formatter.format_report(
|
||||||
|
ldr,
|
||||||
|
conf,
|
||||||
|
ldr.versions,
|
||||||
|
title=self.distribution.metadata.name,
|
||||||
|
)
|
||||||
|
with open(self.output_file, 'w') as f:
|
||||||
|
f.write(text)
|
||||||
|
log.info('wrote release notes to %s', self.output_file)
|
|
@ -25,6 +25,8 @@ packages =
|
||||||
[entry_points]
|
[entry_points]
|
||||||
console_scripts =
|
console_scripts =
|
||||||
reno = reno.main:main
|
reno = reno.main:main
|
||||||
|
distutils.commands =
|
||||||
|
build_reno = reno.setup_command:BuildReno
|
||||||
|
|
||||||
[extras]
|
[extras]
|
||||||
sphinx =
|
sphinx =
|
||||||
|
|
Loading…
Reference in New Issue