diff --git a/doc/source/_exts/rst.jinja b/doc/source/_exts/rst.jinja new file mode 100644 index 0000000..94a27af --- /dev/null +++ b/doc/source/_exts/rst.jinja @@ -0,0 +1,69 @@ +============= +{{ 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 %} diff --git a/doc/source/_exts/vmt.py b/doc/source/_exts/vmt.py new file mode 100644 index 0000000..078b6ad --- /dev/null +++ b/doc/source/_exts/vmt.py @@ -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) diff --git a/doc/source/conf.py b/doc/source/conf.py index 25cf7bc..7b7ee32 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -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 # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [ - 'oslosphinx', + 'vmt', + 'oslosphinx' ] todo_include_todos = True diff --git a/doc/source/index.rst b/doc/source/index.rst index 0bb2b7a..0346ffd 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -8,7 +8,7 @@ These pages contain published OpenStack Security Advisories. :maxdepth: 2 :glob: - ossa/index + ./ossa/* .. seealso:: diff --git a/ossa/index.rst b/ossa/index.rst deleted file mode 100644 index e268873..0000000 --- a/ossa/index.rst +++ /dev/null @@ -1,6 +0,0 @@ -=============================== - OpenStack Security Advisories -=============================== - -Published OpenStack Security Advisories. - diff --git a/test-requirements.txt b/test-requirements.txt index 8e7314b..9d515c0 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,3 +1,5 @@ # needed for doc build +Jinja2>=2.7.3 +PyYAML==3.11 sphinx>=1.1.2,!=1.2.0,<1.3 oslosphinx>=2.2.0 # Apache-2.0 diff --git a/tox.ini b/tox.ini index d16e0f4..930acfe 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = docs +envlist = venv minversion = 1.6 skipsdist = True @@ -7,10 +7,7 @@ skipsdist = True usedevelop = True install_command = pip install -U {opts} {packages} setenv = VIRTUAL_ENV={envdir} -deps = -r{toxinidir}/test-requirements.txt [testenv:venv] -commands = {posargs} - -[testenv:docs] -commands = python setup.py build_sphinx +deps = -r{toxinidir}/test-requirements.txt +commands =python setup.py build_sphinx