docs: autogenerate documentation from YAML files

The documentation is based on mkdocs. This commit contains plugin that
creates a documentation page for each YAML file in this repository. The
file needs to follow the schema and include all metadata fields.

Signed-off-by: Milosz Wasilewski <milosz.wasilewski@linaro.org>
diff --git a/mkdocs_plugin/__init__.py b/mkdocs_plugin/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/mkdocs_plugin/__init__.py
diff --git a/mkdocs_plugin/requirements.txt b/mkdocs_plugin/requirements.txt
new file mode 100644
index 0000000..d0081da
--- /dev/null
+++ b/mkdocs_plugin/requirements.txt
@@ -0,0 +1 @@
+mkdocs-test-definitions-plugin
diff --git a/mkdocs_plugin/setup.py b/mkdocs_plugin/setup.py
new file mode 100644
index 0000000..49aa861
--- /dev/null
+++ b/mkdocs_plugin/setup.py
@@ -0,0 +1,35 @@
+from setuptools import setup, find_packages
+
+
+setup(
+    name='mkdocs-test-definitions-plugin',
+    version='1.0.0',
+    description='An MkDocs plugin that converts LAVA test definitions to documentation',
+    long_description='',
+    keywords='mkdocs python markdown wiki',
+    url='https://github.com/linaro/test-definitions',
+    author='Milosz Wasilewski',
+    author_email='milosz.wasilewski@linaro.org',
+    license='GPL',
+    python_requires='>=3.5',
+    install_requires=[
+        'mkdocs>=1'
+    ],
+    classifiers=[
+        'Development Status :: 5 - Production/Stable',
+        'Intended Audience :: Developers',
+        'Intended Audience :: Information Technology',
+        'License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)',
+        'Programming Language :: Python',
+        'Programming Language :: Python :: 3 :: Only',
+        'Programming Language :: Python :: 3.5',
+        'Programming Language :: Python :: 3.6',
+        'Programming Language :: Python :: 3.7'
+    ],
+    packages=find_packages(),
+    entry_points={
+        'mkdocs.plugins': [
+            'linaro-test-definitions = testdefinitionsmkdocs:LinaroTestDefinitionsMkDocsPlugin'
+        ]
+    }
+)
diff --git a/mkdocs_plugin/testdefinitionsmkdocs/__init__.py b/mkdocs_plugin/testdefinitionsmkdocs/__init__.py
new file mode 100644
index 0000000..c2953d6
--- /dev/null
+++ b/mkdocs_plugin/testdefinitionsmkdocs/__init__.py
@@ -0,0 +1,63 @@
+import errno
+import mdutils
+import os
+import yaml
+
+from mkdocs.plugins import BasePlugin
+from mkdocs.structure.files import File
+
+
+class LinaroTestDefinitionsMkDocsPlugin(BasePlugin):
+    def generate_yaml_markdown(self, filename, config):
+        # remove leading ./
+        new_filename = filename.split("/", 1)[1]
+        # remove .yaml
+        new_filename = new_filename.rsplit(".", 1)[0]
+        new_filename = os.path.join(config['docs_dir'], new_filename)
+        filecontent = None
+        try:
+            with open(filename, "r") as f:
+                filecontent = f.read()
+        except FileNotFoundError:
+            return None
+        try:
+            content = yaml.load(filecontent)
+            if "metadata" in content.keys():
+                metadata = content["metadata"]
+                mdFile = mdutils.MdUtils(file_name=new_filename, title=metadata['name'])
+                mdFile.new_header(level=1, title="Test name: %s" % metadata['name'])
+                mdFile.new_header(level=1, title="Description")
+                mdFile.new_paragraph(metadata['description'])
+                mdFile.new_header(level=1, title="Maintainer")
+                maintainer_list = metadata.get("maintainer", None)
+                if maintainer_list is not None:
+                    for item in maintainer_list:
+                        mdFile.new_line(" * %s" % item)
+                mdFile.new_header(level=1, title="Scope")
+                scope_list = metadata.get("scope", None)
+                if scope_list is not None:
+                    for item in scope_list:
+                        mdFile.new_line(" * %s" % item)
+                try:
+                    os.makedirs(os.path.dirname(new_filename))
+                except OSError as exc:  # Guard against race condition
+                    if exc.errno != errno.EEXIST:
+                        raise
+                mdFile.create_md_file()
+                return mdFile.file_name + ".md"
+        except yaml.YAMLError:
+            return None
+        except KeyError:
+            return None
+
+    def on_files(self, files, config):
+        for root, dirs, filenames in os.walk("."):
+            for filename in filenames:
+                if filename.endswith(".yaml"):
+                    new_filename = os.path.join(root, filename)
+                    markdown_filename = self.generate_yaml_markdown(new_filename, config)
+                    if markdown_filename is not None:
+                        f = File(markdown_filename, "./docs", "./docs", False)
+                        files.append(f)
+
+        return files