Use templates to generate rst documentation
Using Jinja2 to generate ReSTructured text documents via a Sphinx Extension. Change-Id: I384971732166fbeb123d572d3ccbcde6bad39dfc
This commit is contained in:
parent
ea154bc92d
commit
dd2fa571be
|
@ -2,3 +2,5 @@
|
||||||
doc/build
|
doc/build
|
||||||
*.egg-info
|
*.egg-info
|
||||||
pbr*.egg
|
pbr*.egg
|
||||||
|
*.pyc
|
||||||
|
ossa/*.rst
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
==============={% for _ in title %}={% endfor %}
|
||||||
|
|
||||||
|
{{ id }}: {{ title }}
|
||||||
|
==============={% for _ in title %}={% endfor %}
|
||||||
|
|
||||||
|
|
||||||
|
Date
|
||||||
|
~~~~
|
||||||
|
{{ date | ossa_date }}
|
||||||
|
|
||||||
|
|
||||||
|
Affects
|
||||||
|
~~~~~~~
|
||||||
|
{% for affected in affected_products %}
|
||||||
|
- {{ affected['product'].capitalize() }}: {{ affected['version'] }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
|
||||||
|
Description
|
||||||
|
~~~~~~~~~~~
|
||||||
|
{{ description }}
|
||||||
|
|
||||||
|
{% if errata %}
|
||||||
|
Errata
|
||||||
|
~~~~~~
|
||||||
|
{{ errata_text }}
|
||||||
|
{% endif %}
|
||||||
|
{% if notes %}
|
||||||
|
Notes
|
||||||
|
~~~~~
|
||||||
|
{{ notes }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
Credits
|
||||||
|
~~~~~~~
|
||||||
|
{% for reporter in reporters %}
|
||||||
|
{% if 'affiliation' in reporter and reporter['affiliation'] and reporter['affiliation'] != 'UNKNOWN' %}
|
||||||
|
- {{ reporter['name'] | trim | indent }} from {{ reporter ['affiliation'] }} ({{ reporter['reported'] | csv_list }})
|
||||||
|
{% else %}
|
||||||
|
- {{ reporter['name'] | trim | indent }} ({{ reporter['reported'] | csv_list }})
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
|
||||||
|
References
|
||||||
|
~~~~~~~~~~
|
||||||
|
{% for link in issues['links'] %}
|
||||||
|
- {{ link }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
|
||||||
|
Patches
|
||||||
|
~~~~~~~
|
||||||
|
{% for release in reviews %}
|
||||||
|
{% if release != 'type' %}
|
||||||
|
{% for link in reviews[release] %}
|
||||||
|
- {{ link | trim }} ({{ release.capitalize() | trim }})
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% if errata %}
|
||||||
|
OSSA History
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
{% for change in errata_history %}
|
||||||
|
- {{ change }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,75 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
import glob
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import textwrap
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
from docutils import nodes
|
||||||
|
from docutils.parsers import rst
|
||||||
|
from docutils.statemachine import ViewList
|
||||||
|
from jinja2 import FileSystemLoader
|
||||||
|
from jinja2.environment import Environment
|
||||||
|
from sphinx.util.nodes import nested_parse_with_titles
|
||||||
|
from sphinx.addnodes import toctree
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
reload(sys)
|
||||||
|
sys.setdefaultencoding("utf-8")
|
||||||
|
|
||||||
|
|
||||||
|
def to_snake_case(d):
|
||||||
|
for k in d:
|
||||||
|
v = d[k]
|
||||||
|
del d[k]
|
||||||
|
d[k.replace('-', '_')] = v
|
||||||
|
if type(k) == dict:
|
||||||
|
to_snake_case(d)
|
||||||
|
|
||||||
|
|
||||||
|
def to_paragraphs(d, *args):
|
||||||
|
for k in args:
|
||||||
|
if type(d[k]) == str:
|
||||||
|
d[k] = '\n'.join(textwrap.wrap(d[k]))
|
||||||
|
|
||||||
|
|
||||||
|
def ossa_date_formatter(value):
|
||||||
|
return "{:%B %d, %Y}".format(value)
|
||||||
|
|
||||||
|
|
||||||
|
def csv_list_formatter(value):
|
||||||
|
return ", ".join(value)
|
||||||
|
|
||||||
|
|
||||||
|
def render_template(template, data, **kwargs):
|
||||||
|
template_dir = kwargs.get('template_dir', os.getcwd())
|
||||||
|
loader = FileSystemLoader(template_dir)
|
||||||
|
env = Environment(trim_blocks=True, loader=loader)
|
||||||
|
env.filters["ossa_date"] = ossa_date_formatter
|
||||||
|
env.filters["csv_list"] = csv_list_formatter
|
||||||
|
template = env.get_template(template)
|
||||||
|
return template.render(**data)
|
||||||
|
|
||||||
|
|
||||||
|
def render(source, template, **kwargs):
|
||||||
|
vals = yaml.safe_load(open(source).read())
|
||||||
|
to_snake_case(vals)
|
||||||
|
to_paragraphs(vals, 'description')
|
||||||
|
return render_template(template, vals, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def build_advisories(app):
|
||||||
|
|
||||||
|
template_name = "rst.jinja"
|
||||||
|
template_files = os.path.join(".", "doc", "source", "_exts")
|
||||||
|
yaml_files = os.path.join(".", "ossa")
|
||||||
|
input_files = glob.glob(os.path.join(yaml_files, "*.yaml"))
|
||||||
|
output_files = [x.replace(".yaml", ".rst") for x in input_files]
|
||||||
|
for old, new in zip(input_files, output_files):
|
||||||
|
with open(new, "w") as out:
|
||||||
|
out.write(render(old, template_name, template_dir=template_files))
|
||||||
|
|
||||||
|
|
||||||
|
def setup(app):
|
||||||
|
app.info('Loading the vmt extension')
|
||||||
|
app.connect('builder-inited', build_advisories)
|
|
@ -27,7 +27,8 @@ sys.path.insert(0, os.path.join(os.path.abspath('.'), '_exts'))
|
||||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||||
extensions = [
|
extensions = [
|
||||||
'oslosphinx',
|
'vmt',
|
||||||
|
'oslosphinx'
|
||||||
]
|
]
|
||||||
|
|
||||||
todo_include_todos = True
|
todo_include_todos = True
|
||||||
|
|
|
@ -8,7 +8,7 @@ These pages contain published OpenStack Security Advisories.
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
:glob:
|
:glob:
|
||||||
|
|
||||||
ossa/index
|
./ossa/*
|
||||||
|
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
===============================
|
|
||||||
OpenStack Security Advisories
|
|
||||||
===============================
|
|
||||||
|
|
||||||
Published OpenStack Security Advisories.
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
# needed for doc build
|
# needed for doc build
|
||||||
|
Jinja2>=2.7.3
|
||||||
|
PyYAML==3.11
|
||||||
sphinx>=1.1.2,!=1.2.0,<1.3
|
sphinx>=1.1.2,!=1.2.0,<1.3
|
||||||
oslosphinx>=2.2.0 # Apache-2.0
|
oslosphinx>=2.2.0 # Apache-2.0
|
||||||
|
|
9
tox.ini
9
tox.ini
|
@ -1,5 +1,5 @@
|
||||||
[tox]
|
[tox]
|
||||||
envlist = docs
|
envlist = venv
|
||||||
minversion = 1.6
|
minversion = 1.6
|
||||||
skipsdist = True
|
skipsdist = True
|
||||||
|
|
||||||
|
@ -7,10 +7,7 @@ skipsdist = True
|
||||||
usedevelop = True
|
usedevelop = True
|
||||||
install_command = pip install -U {opts} {packages}
|
install_command = pip install -U {opts} {packages}
|
||||||
setenv = VIRTUAL_ENV={envdir}
|
setenv = VIRTUAL_ENV={envdir}
|
||||||
deps = -r{toxinidir}/test-requirements.txt
|
|
||||||
|
|
||||||
[testenv:venv]
|
[testenv:venv]
|
||||||
commands = {posargs}
|
deps = -r{toxinidir}/test-requirements.txt
|
||||||
|
commands =python setup.py build_sphinx
|
||||||
[testenv:docs]
|
|
||||||
commands = python setup.py build_sphinx
|
|
||||||
|
|
Loading…
Reference in New Issue