diff --git a/doc/source/conf.py b/doc/source/conf.py index bfabc63e..cffb26b7 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -3,7 +3,6 @@ # openstackdocstheme documentation build configuration file import openstackdocstheme -from openstackdocstheme.version import version_info # Release name for PDF documents latex_custom_template = r""" @@ -29,22 +28,9 @@ source_suffix = '.rst' # The master toctree document. master_doc = 'index' -# "project" contains the name of the book, such as -# 'security guide' or 'network guide' -# It's used by the "log-a-bug" button on each page -# and should ultimately be set automatically by the build process -project = u'OpenStack Documentation Theme' +# General information about the project. copyright = u'2015-2017, OpenStack Contributors' -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The full version, including alpha/beta/rc tags. -release = version_info.release_string() -# The short X.Y version. -version = version_info.version_string() - # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ['_build'] diff --git a/openstackdocstheme/ext.py b/openstackdocstheme/ext.py index d33c4007..1b0d62aa 100644 --- a/openstackdocstheme/ext.py +++ b/openstackdocstheme/ext.py @@ -20,12 +20,14 @@ import os import subprocess import dulwich.repo +from pbr import packaging from sphinx.ext import extlinks from sphinx.util import logging from openstackdocstheme import paths _series = None +_project = None _giturl = 'https://git.openstack.org/cgit/{}/tree/{}' _html_context_data = None @@ -123,6 +125,7 @@ def _get_series_name(): global _series if _series is None: parser = configparser.ConfigParser() + # TODO(stephenfin): Should this be relative to some directory? parser.read('.gitreview') try: branch = parser.get('gerrit', 'defaultbranch') @@ -143,11 +146,79 @@ def _setup_link_roles(app): app.add_role(role_name, extlinks.make_link_role(url, project_name)) +def _find_setup_cfg(srcdir): + """Find the 'setup.cfg' file, if it exists. + + This assumes we're using 'doc/source' for documentation, but also allows + for single level 'doc' paths. + """ + # TODO(stephenfin): Are we sure that this will always exist, e.g. for + # an sdist or wheel? Perhaps we should check for 'PKG-INFO' or + # 'METADATA' files, a la 'pbr.packaging._get_version_from_pkg_metadata' + for path in [ + os.path.join(srcdir, os.pardir, 'setup.cfg'), + os.path.join(srcdir, os.pardir, os.pardir, 'setup.cfg')]: + if os.path.exists(path): + return path + + return None + + +def _get_project_name(srcdir): + """Return string name of project name, or None. + + This assumes every project is using 'pbr' and, therefore, the metadata can + be extracted from 'setup.cfg'. + + We don't rely on distutils/setuptools as we don't want to actually install + the package simply to build docs. + """ + global _project + if _project is None: + parser = configparser.ConfigParser() + + path = _find_setup_cfg(srcdir) + if not path or not parser.read(path): + logger.info('Could not find a setup.cfg to extract project name ' + 'from') + return None + + try: + project = parser.get('metadata', 'name') + except configparser.Error: + logger.info('Could not extract project name from setup.cfg') + return None + _project = project + return _project + + def _builder_inited(app): theme_dir = paths.get_html_theme_path() logger.info('Using openstackdocstheme Sphinx theme from %s' % theme_dir) _setup_link_roles(app) + # we only override configuration if the theme has been configured, meaning + # users are using these features + if app.config.html_theme != 'openstackdocs': + return + + # TODO(stephenfin): Once Sphinx 1.8 is released, we should move the below + # to a 'config-inited' handler + + project_name = _get_project_name(app.srcdir) + version = packaging.get_version(project_name) + + # NOTE(stephenfin): Chances are that whatever's in 'conf.py' is probably + # wrong/outdated so, if we can, we intentionally overwrite it... + if project_name: + app.config.project = project_name + + # ...except for version/release which, if blank, should remain that way to + # cater for unversioned documents + if app.config.version != '': + app.config.version = version + app.config.release = version + def setup(app): logger.info('connecting events for openstackdocstheme') diff --git a/releasenotes/notes/autoconfigure-settings-7083fdeeb121da89.yaml b/releasenotes/notes/autoconfigure-settings-7083fdeeb121da89.yaml new file mode 100644 index 00000000..3310c002 --- /dev/null +++ b/releasenotes/notes/autoconfigure-settings-7083fdeeb121da89.yaml @@ -0,0 +1,14 @@ +--- +features: + - | + The following configuration variables, normally defined in ``conf.py``, + can now be configured automatically. + + - ``project`` + - ``version`` + - ``release`` + + It is not necessary to retain any configuration in ``conf.py`` and, in most + cases, such configuration will be ignored. The sole exceptions to this rule + are ``version`` and ``release`` which, if set to ``''`` will not be + overridden. This allows for unversioned documentation.