From ca7ed176a44c80eabdd3ec90d918799f09ee2d0c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hugo=20H=C3=B6rnquist?= <hugo@lysator.liu.se>
Date: Sat, 17 Jun 2023 03:18:26 +0200
Subject: [PATCH] Include module documentation files.

---
 muppet/gather.py            | 10 ++++++-
 muppet/output.py            | 54 +++++++++++++++++++++++++++++++++----
 templates/module_index.html |  6 +++++
 3 files changed, 64 insertions(+), 6 deletions(-)

diff --git a/muppet/gather.py b/muppet/gather.py
index 3f326e3..e8f59ce 100644
--- a/muppet/gather.py
+++ b/muppet/gather.py
@@ -13,6 +13,7 @@ from typing import (
 import json
 import os.path
 import hashlib
+from glob import glob
 from .puppet.strings import puppet_strings
 from .cache import Cache
 
@@ -34,6 +35,7 @@ class ModuleEntry:
     path: str
     strings_output: bytes
     metadata: dict[str, Any]
+    doc_files: list[str]
 
     def file(self, path: str) -> str:
         """Return the absolute path of a path inside the module."""
@@ -96,7 +98,13 @@ def get_module(cache: Cache,
     except FileNotFoundError:
         metadata = {}
 
-    return ModuleEntry(name, path, strings_data, metadata)
+    doc_files = glob(os.path.join(path, '*.md'))
+
+    return ModuleEntry(name=name,
+                       path=path,
+                       strings_output=strings_data,
+                       metadata=metadata,
+                       doc_files=doc_files)
 
 
 def get_modules(cache: Cache, dir: str) -> list[ModuleEntry]:
diff --git a/muppet/output.py b/muppet/output.py
index 5c2e549..9887ef3 100644
--- a/muppet/output.py
+++ b/muppet/output.py
@@ -31,6 +31,7 @@ from .util import group_by
 from .puppet.strings import isprivate
 
 
+# TODO replace 'output' with base, or put this somewhere else
 pathlib.Path('output').mkdir(exist_ok=True)
 jinja = Environment(
     loader=FileSystemLoader('templates'),
@@ -193,10 +194,13 @@ def type_aliases_index(alias_list: list) -> IndexCategory:
 #     return {}
 
 
-def setup_module_index(base: str,
+def setup_module_index(*,
+                       base: str,
                        module: ModuleEntry,
                        data: dict[str, Any],
-                       path_base: str) -> None:
+                       path_base: str,
+                       doc_files: dict[str, str],
+                       ) -> None:
     """Create the index file for a specific module."""
     template = jinja.get_template('module_index.html')
 
@@ -219,7 +223,16 @@ def setup_module_index(base: str,
     with open(os.path.join(base, 'index.html'), 'w') as f:
         f.write(template.render(module_name=module.name,
                                 content=content,
-                                path_base=path_base))
+                                path_base=path_base,
+                                doc_files=doc_files.items()))
+
+
+GENERATED_MESSAGE = '<!-- DO NOT EDIT: This document was generated by Puppet Strings -->\n'
+"""
+REFERENCE.md files generated by Puppet Strings include this string on
+their third line. We use this to ignore auto-generated files, since we
+replace that output.
+"""
 
 
 def setup_module(base: str, module: ModuleEntry, *, path_base: str) -> None:
@@ -241,8 +254,6 @@ def setup_module(base: str, module: ModuleEntry, *, path_base: str) -> None:
         return
     data = json.loads(module.strings_output)
 
-    setup_module_index(path, module, data, path_base=path_base)
-
     for puppet_class in data['puppet_classes'] + data['defined_types']:
         # localpath = puppet_class['name'].split('::')
         localpath, _ = os.path.splitext(puppet_class['file'])
@@ -289,3 +300,36 @@ def setup_module(base: str, module: ModuleEntry, *, path_base: str) -> None:
     # data['data_type_aliases']
     # data['defined_types']
     # data['resource_types']
+
+    files: dict[str, str] = {}
+    for file in module.doc_files:
+        basename = os.path.basename(file)
+        if basename == 'REFERENCE.md':
+            with open(file) as f:
+                f.readline()
+                f.readline()
+                line3 = f.readline()
+                if line3 == GENERATED_MESSAGE:
+                    continue
+        files[basename] = file
+
+    doc_files: dict[str, str] = {}
+    for filename, filepath in files.items():
+        name, _ = os.path.splitext(filename)
+        with open(filepath) as f:
+            raw_content = f.read()
+        content = commonmark(raw_content)
+
+        out_path = os.path.join(path, f'{name}.html')
+
+        with open(out_path, 'w') as f:
+            f.write(content)
+
+        doc_files[name] = os.path.join(module.name, f'{name}.html')
+
+    setup_module_index(base=path,
+                       module=module,
+                       data=data,
+                       path_base=path_base,
+                       doc_files=doc_files,
+                       )
diff --git a/templates/module_index.html b/templates/module_index.html
index 4176594..3d0f1a8 100644
--- a/templates/module_index.html
+++ b/templates/module_index.html
@@ -2,6 +2,12 @@
 {% block content %}
 <h1>{{ module_name }}</h1>
 
+<ul>
+	{% for name, path in doc_files %}
+		<li><a href="{{ path_base }}/{{ path }}">{{ name }}</a></li>
+	{% endfor %}
+</ul>
+
 {% for entry in content %}
 	<h2>{{ entry['title'] }}</h2>
 	{% for subentry in entry['list'] %}
-- 
GitLab