Merge "Integrate a setuptools command"
This commit is contained in:
commit
52d4c1961d
|
@ -48,6 +48,9 @@ doc/build
|
|||
AUTHORS
|
||||
ChangeLog
|
||||
|
||||
# reno generates these
|
||||
RELEASENOTES.rst
|
||||
|
||||
# Editors
|
||||
*~
|
||||
.*.swp
|
||||
|
|
|
@ -8,4 +8,5 @@
|
|||
design
|
||||
usage
|
||||
sphinxext
|
||||
setuptools
|
||||
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
|
||||
correctness.
|
||||
|
||||
.. _configuration:
|
||||
|
||||
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.
|
||||
|
||||
RELEASE_NOTES_SUBDIR = 'releasenotes'
|
||||
|
||||
NOTES_SUBDIR = 'notes'
|
||||
|
||||
PRELUDE_SECTION_NAME = 'prelude'
|
||||
|
||||
# This is a format string, so it needs to be formatted wherever it is used.
|
||||
TEMPLATE = """\
|
||||
---
|
||||
|
@ -81,3 +84,9 @@ other:
|
|||
available in another section, such as the prelude. This may mean repeating
|
||||
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]
|
||||
console_scripts =
|
||||
reno = reno.main:main
|
||||
distutils.commands =
|
||||
build_reno = reno.setup_command:BuildReno
|
||||
|
||||
[extras]
|
||||
sphinx =
|
||||
|
|
Loading…
Reference in New Issue