From c18a9715b83ef94a56c064edee511162998001cc Mon Sep 17 00:00:00 2001
From: Eli Schwartz <eschwartz@archlinux.org>
Date: Sun, 10 Jan 2021 07:48:34 -0500
Subject: [PATCH] Hotdoc: use template for Commands.md instead of generating
 the entire file (#8154)

* doc: fix hotdoc misuse for dynamically generated content

hotdoc has a native include feature for including files inline. Use this
to generate one file for each dynamically generated code block, and
include that file in Commands.md; see:
https://hotdoc.github.io/syntax-extensions.html#smart-file-inclusion-syntax

This permits us to move back to using the in-tree version of the hotdoc
*.md sources, thus fixing the incorrect inclusion of "builddir/" in the
"Edit on github" links which resulted from using copies as the source.

Fixes #8061

* doc: call the dummy file a "stamp" as it is a better known term
---
 .../Commands.md                               | 88 +++++--------------
 docs/meson.build                              | 20 ++---
 run_unittests.py                              | 12 +--
 tools/regenerate_docs.py                      | 20 ++---
 4 files changed, 38 insertions(+), 102 deletions(-)
 rename docs/{markdown_dynamic => markdown}/Commands.md (82%)

diff --git a/docs/markdown_dynamic/Commands.md b/docs/markdown/Commands.md
similarity index 82%
rename from docs/markdown_dynamic/Commands.md
rename to docs/markdown/Commands.md
index a35b4da96..46bd21b87 100644
--- a/docs/markdown_dynamic/Commands.md
+++ b/docs/markdown/Commands.md
@@ -16,15 +16,11 @@ For the full list of all available options for a specific command use the follow
 
 ### configure
 
-```
-{{ cmd_help['configure']['usage'] }}
-```
+{{ configure_usage.inc }}
 
 Changes options of a configured meson project.
 
-```
-{{ cmd_help['configure']['arguments'] }}
-```
+{{ configure_arguments.inc }}
 
 Most arguments are the same as in [`setup`](#setup).
 
@@ -46,15 +42,11 @@ meson configure builddir -Doption=new_value
 
 *(since 0.54.0)*
 
-```
-{{ cmd_help['compile']['usage'] }}
-```
+{{ compile_usage.inc }}
 
 Builds a default or a specified target of a configured meson project.
 
-```
-{{ cmd_help['compile']['arguments'] }}
-```
+{{ compile_arguments.inc }}
 
 `--verbose` argument is available since 0.55.0.
 
@@ -115,15 +107,11 @@ meson compile coverage-html
 
 *(since 0.52.0)*
 
-```
-{{ cmd_help['dist']['usage'] }}
-```
+{{ dist_usage.inc }}
 
 Generates a release archive from the current source tree.
 
-```
-{{ cmd_help['dist']['arguments'] }}
-```
+{{ dist_arguments.inc }}
 
 See [notes about creating releases](Creating-releases.md) for more info.
 
@@ -138,15 +126,11 @@ meson dist -C builddir
 
 *(since 0.45.0)*
 
-```
-{{ cmd_help['init']['usage'] }}
-```
+{{ init_usage.inc }}
 
 Creates a basic set of build files based on a template.
 
-```
-{{ cmd_help['init']['arguments'] }}
-```
+{{ init_arguments.inc }}
 
 #### Examples:
 
@@ -157,15 +141,11 @@ meson init -C sourcedir
 
 ### introspect
 
-```
-{{ cmd_help['introspect']['usage'] }}
-```
+{{ introspect_usage.inc }}
 
 Displays information about a configured meson project.
 
-```
-{{ cmd_help['introspect']['arguments'] }}
-```
+{{ introspect_arguments.inc }}
 
 #### Examples:
 
@@ -178,15 +158,11 @@ meson introspect builddir
 
 *(since 0.47.0)*
 
-```
-{{ cmd_help['install']['usage'] }}
-```
+{{ install_usage.inc }}
 
 Installs the project to the prefix specified in [`setup`](#setup).
 
-```
-{{ cmd_help['install']['arguments'] }}
-```
+{{ install_arguments.inc }}
 
 See [the installation documentation](Installing.md) for more info.
 
@@ -206,31 +182,23 @@ DESTDIR=/path/to/staging/area meson install -C builddir
 
 *(since 0.50.0)*
 
-```
-{{ cmd_help['rewrite']['usage'] }}
-```
+{{ rewrite_usage.inc }}
 
 Modifies the meson project.
 
-```
-{{ cmd_help['rewrite']['arguments'] }}
-```
+{{ rewrite_arguments.inc }}
 
 See [the meson file rewriter documentation](Rewriter.md) for more info.
 
 ### setup
 
-```
-{{ cmd_help['setup']['usage'] }}
-```
+{{ setup_usage.inc }}
 
 Configures a build directory for the meson project.
 
 This is the default meson command (invoked if there was no COMMAND supplied).
 
-```
-{{ cmd_help['setup']['arguments'] }}
-```
+{{ setup_arguments.inc }}
 
 See [meson introduction page](Running-Meson.md#configuring-the-build-directory) for more info.
 
@@ -245,27 +213,19 @@ meson setup builddir
 
 *(since 0.49.0)*
 
-```
-{{ cmd_help['subprojects']['usage'] }}
-```
+{{ subprojects_usage.inc }}
 
 Manages subprojects of the meson project.
 
-```
-{{ cmd_help['subprojects']['arguments'] }}
-```
+{{ subprojects_arguments.inc }}
 
 ### test
 
-```
-{{ cmd_help['test']['usage'] }}
-```
+{{ test_usage.inc }}
 
 Run tests for the configure meson project.
 
-```
-{{ cmd_help['test']['arguments'] }}
-```
+{{ test_arguments.inc }}
 
 See [the unit test documentation](Unit-tests.md) for more info.
 
@@ -283,14 +243,10 @@ meson test -C builddir specific_test_1 specific_test_2
 
 ### wrap
 
-```
-{{ cmd_help['wrap']['usage'] }}
-```
+{{ wrap_usage.inc }}
 
 An utility to manage WrapDB dependencies.
 
-```
-{{ cmd_help['wrap']['arguments'] }}
-```
+{{ wrap_arguments.inc }}
 
 See [the WrapDB tool documentation](Using-wraptool.md) for more info.
diff --git a/docs/meson.build b/docs/meson.build
index 496588d40..fa80512e7 100644
--- a/docs/meson.build
+++ b/docs/meson.build
@@ -2,22 +2,14 @@ project('Meson documentation', version: '1.0')
 
 cur_bdir = meson.current_build_dir()
 
-# Copy all files to build dir, since HotDoc uses relative paths
-run_command(
-    files('../tools/copy_files.py'),
-    '-C', meson.current_source_dir(),
-    '--output-dir', cur_bdir,
-    'markdown', 'theme', 'sitemap.txt', 
-    check: true)
-
 # Only the script knows which files are being generated
 docs_gen = custom_target(
     'gen_docs',
     input: files('markdown/index.md'),
-    output: 'gen_docs.dummy',
+    output: 'gen_docs.stamp',
     command: [
         files('../tools/regenerate_docs.py'),
-        '--output-dir', join_paths(cur_bdir, 'markdown'),
+        '--output-dir', cur_bdir,
         '--dummy-output-file', '@OUTPUT@',
     ],
     build_by_default: true,
@@ -26,15 +18,15 @@ docs_gen = custom_target(
 hotdoc = import('hotdoc')
 documentation = hotdoc.generate_doc(meson.project_name(),
     project_version: meson.project_version(),
-    sitemap: join_paths(cur_bdir, 'sitemap.txt'),
+    sitemap: 'sitemap.txt',
     build_by_default: true,
     depends: docs_gen,
-    index: join_paths(cur_bdir, 'markdown/index.md'),
+    index: 'markdown/index.md',
     install: false,
     extra_assets: ['images/'],
-    include_paths: [join_paths(cur_bdir, 'markdown')],
+    include_paths: ['markdown', cur_bdir],
     default_license: 'CC-BY-SAv4.0',
-    html_extra_theme: join_paths(cur_bdir, 'theme', 'extra'),
+    html_extra_theme: join_paths('theme', 'extra'),
     git_upload_repository: 'git@github.com:jpakkane/jpakkane.github.io.git',
     edit_on_github_repository: 'https://github.com/mesonbuild/meson',
     syntax_highlighting_activate: true,
diff --git a/run_unittests.py b/run_unittests.py
index 1ff54eb37..d6afaff2e 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -4915,7 +4915,7 @@ class AllPlatformTests(BasePlatformTests):
         # The docs directory is not in release tarballs.
         if not os.path.isdir('docs'):
             raise unittest.SkipTest('Doc directory does not exist.')
-        doc_path = 'docs/markdown_dynamic/Commands.md'
+        doc_path = 'docs/markdown/Commands.md'
 
         md = None
         with open(doc_path, encoding='utf-8') as f:
@@ -4944,13 +4944,9 @@ class AllPlatformTests(BasePlatformTests):
 
         def get_data_pattern(command):
             return re.compile(
-                r'^```[\r\n]'
-                r'{{ cmd_help\[\'' + command + r'\'\]\[\'usage\'\] }}[\r\n]'
-                r'^```[\r\n]'
+                r'{{ ' + command + r'_usage.inc }}[\r\n]'
                 r'.*?'
-                r'^```[\r\n]'
-                r'{{ cmd_help\[\'' + command + r'\'\]\[\'arguments\'\] }}[\r\n]'
-                r'^```',
+                r'{{ ' + command + r'_arguments.inc }}[\r\n]',
                 flags = re.MULTILINE|re.DOTALL)
 
         for command in md_commands:
@@ -7533,7 +7529,7 @@ class LinuxCrossArmTests(BaseLinuxCrossTests):
             '-Dbuild.pkg_config_path=' + os.path.join(testdir, 'build_extra_path'),
             '-Dpkg_config_path=' + os.path.join(testdir, 'host_extra_path'),
         ])
-    
+
     def test_run_native_test(self):
         '''
         https://github.com/mesonbuild/meson/issues/7997
diff --git a/tools/regenerate_docs.py b/tools/regenerate_docs.py
index 74a8b0c0c..b9b994a1a 100755
--- a/tools/regenerate_docs.py
+++ b/tools/regenerate_docs.py
@@ -20,7 +20,6 @@ Regenerate markdown docs by using `meson.py` from the root dir
 '''
 
 import argparse
-import jinja2
 import os
 import re
 import subprocess
@@ -108,20 +107,13 @@ def get_commands_data(root_dir: Path) -> T.Dict[str, T.Any]:
 
     return cmd_data
 
-def regenerate_commands(root_dir: Path, output_dir: Path) -> None:
-    with open(root_dir/'docs'/'markdown_dynamic'/'Commands.md') as f:
-        template = f.read()
-
+def generate_hotdoc_includes(root_dir: Path, output_dir: Path) -> None:
     cmd_data = get_commands_data(root_dir)
 
-    t = jinja2.Template(template, undefined=jinja2.StrictUndefined, keep_trailing_newline=True)
-    content = t.render(cmd_help=cmd_data)
-
-    output_file = output_dir/'Commands.md'
-    with open(output_file, 'w') as f:
-        f.write(content)
-
-    print(f'`{output_file}` was regenerated')
+    for cmd, parsed in cmd_data.items():
+        for typ in parsed.keys():
+            with open(output_dir / (cmd+'_'+typ+'.inc'), 'w') as f:
+                f.write(parsed[typ])
 
 def regenerate_docs(output_dir: PathLike,
                     dummy_output_file: T.Optional[PathLike]) -> None:
@@ -133,7 +125,7 @@ def regenerate_docs(output_dir: PathLike,
 
     root_dir = Path(__file__).resolve().parent.parent
 
-    regenerate_commands(root_dir, output_dir)
+    generate_hotdoc_includes(root_dir, output_dir)
 
     if dummy_output_file:
         with open(output_dir/dummy_output_file, 'w') as f: