diff --git a/docs/Makefile b/docs/Makefile index 58c91383e5..b8e3c14390 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -29,6 +29,9 @@ stories: spec/lint.rst: $(SCRIPTSDIR)/generate-lint-checks.py $(TEMPLATESDIR)/lint-checks.rst.j2 $(TMTDIR)/base.py $(SCRIPTSDIR)/generate-lint-checks.py $(TEMPLATESDIR)/lint-checks.rst.j2 $@ +spec/hardware-matrix.rst: spec $(TEMPLATESDIR)/hardware-matrix.rst.j2 + $(SCRIPTSDIR)/generate-hardware-matrix.py $(TEMPLATESDIR)/hardware-matrix.rst.j2 $@ + code/template-filters.rst: $(SCRIPTSDIR)/generate-template-filters.py $(TEMPLATESDIR)/template-filters.rst.j2 $(TMTDIR)/utils.py $(SCRIPTSDIR)/generate-template-filters.py $(TEMPLATESDIR)/template-filters.rst.j2 $@ @@ -57,7 +60,9 @@ generate-lint-checks: spec spec/lint.rst ## Generate documentation sources for generate-template-filters: code/template-filters.rst ## Generate documentation sources for Jinja2 template filters -generate-stories: stories $(TEMPLATESDIR)/story.rst.j2 ## Generate documentation sources for stories +generate-hardware-matrix: spec/hardware-matrix.rst ## Generate HW requirement support matrix + +generate-stories: stories $(TEMPLATESDIR)/story.rst.j2 generate-hardware-matrix ## Generate documentation sources for stories $(SCRIPTSDIR)/generate-stories.py $(TEMPLATESDIR)/story.rst.j2 generate-plugins: plugins/discover.rst plugins/execute.rst plugins/finish.rst plugins/prepare.rst plugins/provision.rst plugins/report.rst plugins/test-checks.rst ## Generate documentation sources for plugins diff --git a/docs/_static/.empty b/docs/_static/.empty deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs/_static/custom.css b/docs/_static/custom.css new file mode 100644 index 0000000000..342d30adbd --- /dev/null +++ b/docs/_static/custom.css @@ -0,0 +1,5 @@ +@import 'css/theme.css'; + +/* Used for HW requirement support matrix */ +.supported { color: green; } +.unsupported { color: red; } diff --git a/docs/conf.py b/docs/conf.py index a106153062..1ec9e1d4de 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -229,6 +229,9 @@ def _load_theme( # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] +# Include custom style. +html_style = 'custom.css' + # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. diff --git a/docs/scripts/generate-hardware-matrix.py b/docs/scripts/generate-hardware-matrix.py new file mode 100755 index 0000000000..acc3741907 --- /dev/null +++ b/docs/scripts/generate-hardware-matrix.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python3 + +import sys +import textwrap + +import tmt.plugins +import tmt.steps.provision +from tmt.utils import Path, render_template_file + +HELP = textwrap.dedent(""" +Usage: generate-hardware-matrix.py + +Generate page with HW requirement support matrix from stories. +""").strip() + + +def main() -> None: + if len(sys.argv) != 3: + print(HELP) + + sys.exit(1) + + template_filepath = Path(sys.argv[1]) + output_filepath = Path(sys.argv[2]) + + # We will need a logger... + logger = tmt.Logger.create() + logger.add_console_handler() + + # Explore available *export* plugins - do not import other plugins, we don't need them. + tmt.plugins._explore_packages(logger) + + known_methods = sorted( + tmt.steps.provision.ProvisionPlugin._supported_methods.iter_plugin_ids()) + + tree = tmt.Tree(logger=logger, path=Path.cwd()) + + logger.info('Generating reST file for HW requirement support matrix') + + matrix: dict[str, dict[str, tuple[bool, str]]] = {} + notes: list[str] = [] + + for story in tree.stories(logger=logger, names=['^/spec/hardware/.*'], whole=True): + hw_requirement = story.name.replace('/spec/hardware/', '') + + if hw_requirement == 'arch': + continue + + matrix[hw_requirement] = { + method: (False, int) for method in known_methods + } + + if not story.link: + pass + + for link in story.link.get(relation='implemented-by'): + implemented_by_method = Path(link.target).stem + + if implemented_by_method == 'mrack': + implemented_by_method = 'beaker' + + elif implemented_by_method == 'testcloud': + implemented_by_method = 'virtual.testcloud' + + if implemented_by_method not in matrix[hw_requirement]: + raise Exception(f'{implemented_by_method} unknown') + + if link.note: + notes.append(link.note) + + matrix[hw_requirement][implemented_by_method] = (True, len(notes)) + + else: + matrix[hw_requirement][implemented_by_method] = (True, None) + + output_filepath.write_text(render_template_file( + template_filepath, + LOGGER=logger, + MATRIX=matrix, + NOTES=notes)) + + +if __name__ == '__main__': + main() diff --git a/docs/templates/hardware-matrix.rst.j2 b/docs/templates/hardware-matrix.rst.j2 new file mode 100644 index 0000000000..12b430d20f --- /dev/null +++ b/docs/templates/hardware-matrix.rst.j2 @@ -0,0 +1,42 @@ +{# + A Jinja2 template for rendering HW requirement support matrix in tmt's own docs. +#} + +Support matrix +^^^^^^^^^^^^^^ + +Below you can find a matrix documenting which hardware requirement are +supported by plugins bundled with tmt. + +.. role:: supported + +.. role:: unsupported + +.. list-table:: + :header-rows: 1 + + * - Requirement + {% for plugin in MATRIX['memory'].keys() %} + {% if plugin == 'virtual.testcloud' %} + - ``virtual`` + {% else %} + - ``{{ plugin }}`` + {% endif %} + {% endfor %} + +{% for requirement, plugins in MATRIX.items() %} + * - :ref:`{{ requirement }}` + {% for plugin, (enabled, note_id) in plugins.items() %} + {% if enabled %} + - :supported:`yes`{% if note_id %} [{{ note_id }}]_{% endif %} + + {% else %} + - :unsupported:`no` + + {% endif %} + {% endfor %} +{% endfor %} + +{% for note in NOTES %} +.. [{{ loop.index}}] {{ note }} +{% endfor %} diff --git a/docs/templates/story.rst.j2 b/docs/templates/story.rst.j2 index 4e01aeedd4..2ddf67990e 100644 --- a/docs/templates/story.rst.j2 +++ b/docs/templates/story.rst.j2 @@ -226,3 +226,8 @@ * {{ printable_relation(link) }} ``{{ link.target }}`` {% endif %} {% endfor %} + +{# Include HW requirement matrix when generating the main HW story #} +{% if STORY.name == '/spec/hardware'%} +.. include:: hardware-matrix.rst +{% endif %}