Creates a lfdocs-conf package that is pip installable.
The minimal conf.yaml consists of only a project_cfg configuration
with the name of the project eg opendaylight, opnfv, lfdocs:
---
project_cfg: lfdocs
Limitations:
intersphinx_mapping is not currently mappable via yaml due to
it being a complex data set of a tuple + data type (None). Projects
can override this by setting it in their local conf.py or accept the
defaults provided by the lfdocs-conf project.
Change-Id: Ia695047dc92adc00e4e9ec1f6d3ed824d10c0959
Co-authored-by: Thanh Ha <thanh.ha@linuxfoundation.org>
Signed-off-by: Trevor Bramwell <tbramwell@linuxfoundation.org>
Signed-off-by: Thanh Ha <thanh.ha@linuxfoundation.org>
.tox/
docs/_build/
MANIFEST
+build
+dist
+*.egg-info
+*.pyc
+.cache
--- /dev/null
+LF Docs Config
+==============
+
+The purpose of this project is to allow LF projects a centralized location for
+storing common project configuration.
+
+To use this a project should create a conf.yaml file in the same
+directory as their conf.py. Conf.py should contain at minimum::
+
+ from docs_conf import *
+
+The conf.yaml file should contain at minimum::
+
+ ---
+ project_cfg=myproject
+
+If defaults for 'myproject' exist, they will be loaded from this
+package, otherwise the basic Sphinx defaults will be set.
+
+Configuration precedence for configuration is as follows:
+
+#. project/conf.py
+#. project/conf.yaml
+#. docs_conf/{project_cfg}.yaml
+#. docs_conf/default.yaml
+#. docs_conf/__init__.py
+
+conf.py structure and documentation:
+ http://www.sphinx-doc.org/en/stable/config.html
+
+TODO
+----
+
+- [ ] Define the minimum set of config values to release initial version.
+ These can probably come from ODL/OPNFV site conf.py files.
+
+- [ ] Use sane defaults, and don't error out if something is not set.
+ Each config needs to be imported gracefully (if it doesn't
+ exist, set None or something; similar to dict.get
+
+- [ ] Create own documentation for project detailing use of 'conf.cfg'
+ file as some values will require subkeys given that they're
+ dictionaries or expect a list of tuples.
+
+- [ ] Setup and document section. The documentation already is organized
+ by section, so the config should also contain these section and look
+ for their values under them.
+
+ Sections:
+
+ - general (aka sphinx)
+ - project
+ - i18n
+ - html_output
+ - apple_help
+ - epub_output
+ - latex_output
+ - text_output
+ - manpage_output
+ - texinfo_output
+ - linkcheck
+ - xml
+ - cplusplus
+
+- [ ] Configure pre-plugin sections, and reference by plugin listing.
--- /dev/null
+"""
+Sphinx Docs Config
+
+Configure sphinx-doc through an ini file.
+"""
+
+import imp
+import os.path
+import pkg_resources
+
+import sphinx_bootstrap_theme
+import yaml
+
+
+def _merge_yaml(x, y):
+ """Merges dictionary 'y' into 'x'
+
+ This transaction will overwrite existing data values in "y" with values
+ from "x".
+ """
+ z = x.copy()
+ z.update(y)
+ return z
+
+
+def collect_project_and_config():
+ """Pull project and configuration by merging all config sources
+
+ Order of precedence:
+
+ 1) local conf.yaml
+ 2) defaults/PROJECT.yaml
+ 3) defaults/default.yaml
+
+ Return the project name and merged configs from the calling project
+ and per-project defaults.
+ """
+ if not os.path.isfile('conf.yaml'):
+ raise IOError("No conf.yaml file found at: {}".format(os.getcwd()))
+
+ with open('conf.yaml', 'r') as f:
+ local_config = yaml.load(f)
+
+ project_cfg = local_config.get('project_cfg', None)
+
+ _, docs_path, _ = imp.find_module('docs_conf')
+
+ default_cfg = os.path.join(docs_path, 'defaults', 'default.yaml')
+ with open(os.path.join(docs_path, default_cfg), 'r') as f:
+ effective_config = yaml.load(f)
+
+ project_cfg_file = os.path.join(docs_path, 'defaults', '{}.yaml'.format(project_cfg))
+ if os.path.isfile(project_cfg_file):
+ with open(os.path.join(docs_path, project_cfg_file), 'r') as f:
+ _project_cfg_data = yaml.load(f)
+ effective_config = _merge_yaml(effective_config, _project_cfg_data)
+
+ effective_config = _merge_yaml(effective_config, local_config)
+
+ return effective_config
+
+cfg = collect_project_and_config()
+
+# Parse the config and pull in sphinx conf.py settings
+project = cfg.get('project')
+release = cfg.get('release')
+version = cfg.get('version')
+author = cfg.get('author')
+copyright = cfg.get('copyright')
+
+needs_sphinx = cfg.get('needs_sphinx', '1.0')
+exclude_patterns = cfg.get('exclude_patterns', [])
+extensions = cfg.get('extensions', [])
+language = cfg.get('language', None)
+master_doc = cfg.get('master_doc', 'index')
+pygments_style = cfg.get('pygments_style', 'sphinx')
+source_suffix = cfg.get('source_suffix', '.rst')
+templates_path = cfg.get('templates_path', ['_templates'])
+todo_include_todos = cfg.get('todo_include_todos', False)
+
+html_extra_path = cfg.get('html_extra_path', [])
+html_favicon = cfg.get('html_favicon', 'favicon.ico')
+html_logo = cfg.get('html_logo', '_static/logo.png')
+html_sidebars = cfg.get('html_sidebars', {'**': ['localtoc.html', 'relations.html'],})
+html_static_path = cfg.get('html_static_path', ['_static'])
+html_theme = cfg.get('html_theme', 'bootstrap')
+html_theme_options = cfg.get('html_theme_options', {
+ 'bootswatch_theme': "cerulean",
+ 'navbar_sidebarrel': False,
+ 'source_link_position': "footer",
+})
+html_theme_path = cfg.get('html_theme_path', sphinx_bootstrap_theme.get_html_theme_path())
+htmlhelp_basename = cfg.get('htmlhelp_basename', 'DocsConf')
+
+intersphinx_mapping = {
+ 'global-jjb': ('http://global-jjb.releng.linuxfoundation.org/en/latest/', None),
+ 'lftools': ('http://lftools.releng.linuxfoundation.org/en/latest/', None),
+ 'python': ('https://docs.python.org/', None),
+}
--- /dev/null
+---
+project: DEFAULT_PROJECT
+release: master
+version: master
+author: DEFAULT_AUTHOR
+copyright: 2018, DEFAULT_PROJECT
+
+needs_sphinx: '1.6.6'
+extensions:
+ - sphinx.ext.autodoc
+ - sphinx.ext.doctest
+ - sphinx.ext.intersphinx
+ - sphinx.ext.todo
+ - sphinx.ext.coverage
+ - sphinx.ext.viewcode
+exclude_patterns:
+ - .DS_Store
+ - _build
+ - Thumbs.db
+todo_include_todos: False
+
+html_theme: bootstrap
+html_theme_options:
+ bootswatch_theme: cerulean
+ navbar_sidebarrel: False
+ source_link_position: footer
--- /dev/null
+---
+project: lf-releng-docs
+release: master
+version: master
+author: Linux Foundation Releng
+copyright: 2017-2018, The Linux Foundation
+
+needs_sphinx: '1.6.6'
+extensions:
+ - sphinx.ext.autodoc
+ - sphinx.ext.doctest
+ - sphinx.ext.intersphinx
+ - sphinx.ext.todo
+ - sphinx.ext.coverage
+ - sphinx.ext.viewcode
+exclude_patterns:
+ - .DS_Store
+ - _build
+ - Thumbs.db
+todo_include_todos: False
+
+html_logo: _static/lf-logo-small.png
+html_theme: bootstrap
+html_theme_options:
+ bootswatch_theme: cerulean
+ navbar_sidebarrel: False
+ source_link_position: footer
--- /dev/null
+---
+project: OPNFV
+release: Latest
+version: Latest
+author: Open Platform for NFV
+copyright: 2017, Open Platform for NFV. Licensed under CC BY 4.0
+
+needs_sphinx: '1.3'
+extensions:
+ - sphinxcontrib.httpdomain
+ - sphinx.ext.autodoc
+ - sphinx.ext.napoleon
+ - sphinx.ext.viewcode
+version: Latest
+release: Latest
+todo_include_todos: False
+
+html_theme: bootstrap
+html_theme_options:
+ bootswatch_theme: journal
+ navbar_sidebarrel: False
+html_logo: _static/opnfv-logo.png
+html_favicon: _static/favicon.ico
+html_static_path:
+ - _static
+htmlhelp_basename: OPNFV
--- /dev/null
+pytest
+pyyaml
+sphinx>=1.6.6
+sphinx_bootstrap_theme>=0.6.2
--- /dev/null
+"""
+Setup for Docs Configuration
+"""
+from setuptools import setup, find_packages
+
+setup(
+ name='lfdocs_conf',
+ packages=['docs_conf'],
+ version='0.1.2',
+ author="Linux Foundation Releng",
+ author_email="releng@linuxfoundation.org",
+ url="https://gerrit.linuxfoundation.org/docs-conf",
+ package_data={
+ 'docs_conf': ['defaults/*']
+ },
+ install_requires=[
+ 'pyyaml',
+ 'sphinx',
+ 'sphinx_bootstrap_theme'
+ ]
+)
--- /dev/null
+"""
+Docs Conf Tests
+"""
+import importlib
+import os
+import pytest
+import sys
+
+@pytest.fixture()
+def config(tmpdir):
+ """
+ Create a basic conf.py and conf.cfg file for each test
+ """
+ # Create the base 'conf.py'
+ confpy = tmpdir.join('conf.py')
+ confpy.write("from docs_conf import *")
+
+ # Create conf.cfg file with test defaults
+ # TODO: Make this dynamic so each test can set their own conf.cfg
+ # config.
+ confcfg = tmpdir.join('conf.yaml')
+ confcfg.write("---\nproject: myproject\nauthor: Pythonista")
+
+ # Change to the tmpdir location so relative file lookups succeed
+ os.chdir(str(tmpdir))
+
+ # Import the 'conf.py' file
+ sys.path.append(str(tmpdir))
+ conf_module = importlib.import_module('conf')
+
+ return conf_module
+
+def test_config(config):
+ """
+ Assert some basic assumption about how configurations are pulled in
+ """
+ assert config.project == 'myproject'
+ assert config.author == 'Pythonista'
+ #assert 'latex_documents' in dir(config)
+
+def test_defaults(config):
+ """
+ Test the defaults are set and the only thing required is a conf.py
+ w/import *
+ """
+ # TODO
+ assert True
+
+def test_project_override(config):
+ """
+ Test that setting sphinx.project pulls in the project specific
+ defaults
+ """
+ # TODO
+ assert True
+
+def test_theme_import(config):
+ """
+ Test setting sphinx.html_theme_module imports the correct theme
+ """
+ # TODO
+ pass
envlist =
coala,
docs,
- docs-linkcheck
-skipsdist=true
+ docs-linkcheck,
+ py27
+
+[testenv]
+deps = -rrequirements.txt
+commands =
+ pytest --basetemp={envtmpdir} {posargs}
[testenv:coala]
basepython = python3
commands =
nodeenv -p
coala --non-interactive
-