diff --git a/.forgejo/workflows/aardoc.patch b/.forgejo/workflows/aardoc.patch new file mode 100644 index 0000000..25e5893 --- /dev/null +++ b/.forgejo/workflows/aardoc.patch @@ -0,0 +1,153 @@ +--- aar_doc/defaults.py ++++ aar_doc/defaults.py +@@ -15,7 +15,7 @@ + from ruamel.yaml.scalarstring import LiteralScalarString, SingleQuotedScalarString + + yaml = YAML() +-yaml.indent(mapping=2, sequence=2, offset=2) ++yaml.indent(mapping=2, sequence=4, offset=2) + yaml.encoding = "utf-8" + yaml.allow_unicode = True + +--- aar_doc/defaults.py ++++ aar_doc/defaults.py +@@ -73,18 +73,27 @@ def add_default( + else: + self._defaults.setdefault(name, RoleDefault(name, value, description)) + ++ def safe_quote_recursive(self, value): ++ if isinstance(value, list): ++ return [self.safe_quote_recursive(v) for v in value] ++ elif isinstance(value, dict): ++ return {k: self.safe_quote_recursive(v) for k, v in value.items()} ++ elif isinstance(value, str): ++ if value in ("yes", "no"): ++ return SingleQuotedScalarString(value) ++ elif "\n" in value: ++ return LiteralScalarString(value) ++ elif ":" in value: ++ return SingleQuotedScalarString(value) ++ return value ++ + def to_commented_map(self) -> CommentedMap: + """ + Returns all tracked defaults as a CommentedMap. + """ + commented_defaults = CommentedMap() + for role_default in self.defaults: +- value = role_default.value +- if isinstance(value, str): +- if value in ("yes", "no"): +- value = SingleQuotedScalarString(value) +- if "\n" in value: +- value = LiteralScalarString(value) ++ value = self.safe_quote_recursive(role_default.value) + commented_defaults[role_default.name] = value + description_items = ( + role_default.description +--- aar_doc/core.py ++++ aar_doc/core.py +@@ -7,6 +7,7 @@ and rendering jinja2 templates from processing data. + + import json + import pathlib ++import re + from enum import Enum + + import jinja2 +@@ -21,6 +22,24 @@ yaml.encoding = "utf-8" + yaml.allow_unicode = True + + ++def ansible_doc_markup(text): ++ # Regular expressions copied from ansible-doc: ++ # https://github.com/ansible/ansible/blob/devel/lib/ansible/cli/doc.py#L436 ++ out = re.sub(r'\bI\(([^)]+)\)', r'*\1*', text) # I(text) -> *text* ++ out = re.sub(r'\bB\(([^)]+)\)', r'**\1**', out) # B(text) -> **text** ++ out = re.sub(r'\bC\(([^)]+)\)', r'`\1`', out) # C(text) -> `text` ++ out = re.sub(r'\bM\(([^)]+)\)', r'`\1`', out) # M(module) -> `module` ++ out = re.sub(r'\bO\(((?:[^\\)]+|\\.)+)\)', r'`\1`', out) # O(option) -> `option` ++ out = re.sub(r'\bV\(((?:[^\\)]+|\\.)+)\)', r'`\1`', out) # V(value) -> `value` ++ out = re.sub(r'\bV\(((?:[^\\)]+|\\.)+)\)', r'`\1`', out) # E(env) -> `env` ++ out = re.sub(r'\bV\(((?:[^\\)]+|\\.)+)\)', r'`\1`', out) # RV(retval) -> `retval` ++ out = re.sub(r'\bU\(([^)]+)\)', r'[\1]', out) # U(url) -> [url] ++ out = re.sub(r'\bL\(([^)]+), *([^)]+)\)', r'[\1](\2)', out) # L(text,url) -> [text](url) ++ out = re.sub(r'\bR\(([^)]+), *([^)]+)\)', r'[\1](#\2)', out) # R(text,frag) -> [text](#frag) ++ out = re.sub(r'\bHORIZONTALLINE\b', r'\n\n---\n', out) # HORIZONTALLINE -> --- ++ return out ++ ++ + class OutputMode(Enum): + """ + Defines the options for the output mode. +@@ -240,6 +259,7 @@ def render_content(ctx: typer.Context, content_template: str) -> str: + autoescape=jinja2.select_autoescape(), + undefined=jinja2.StrictUndefined, + ) ++ env.filters['ansible_doc_markup'] = ansible_doc_markup + + role = ctx.obj["config"]["role"] + metadata = ctx.obj["data"]["metadata"] +@@ -270,12 +290,14 @@ def render_content(ctx: typer.Context, content_template: str) -> str: + keep_trailing_newline=True, + loader=jinja2.FileSystemLoader([role_path, output_template_file.parent]), + ) ++ env.filters['ansible_doc_markup'] = ansible_doc_markup + template = env.get_template(output_template_file.name) + except (FileNotFoundError, OSError): + env = jinja2.Environment( + keep_trailing_newline=True, + loader=jinja2.FileSystemLoader(role_path), + ) ++ env.filters['ansible_doc_markup'] = ansible_doc_markup + template = env.from_string(source=output_template) + + return template.render( +--- aar_doc/templates/markdown.j2 ++++ aar_doc/templates/markdown.j2 +@@ -3,7 +3,7 @@ + {%- if "version" in galaxy_collection %} + Version: {{ galaxy_collection.version }} + {% endif %} +-{{ metadata.galaxy_info.description }} ++{{ metadata.galaxy_info.description | ansible_doc_markup }} + {% if ("galaxy_tags" in metadata.galaxy_info) and (metadata.galaxy_info.galaxy_tags | length > 0) %} + Tags: {{ metadata.galaxy_info.galaxy_tags | join(', ') }} + {%- endif %} +@@ -22,14 +22,15 @@ Tags: {{ metadata.galaxy_info.galaxy_tags | join(', ') }} + + ### Entrypoint: {{ entrypoint }} + +-{{ argument_specs[entrypoint].short_description }} ++{{ argument_specs[entrypoint].short_description | ansible_doc_markup }} + + {% if "description" in argument_specs[entrypoint] %} + {%- if argument_specs[entrypoint].description is string -%} +-{{ argument_specs[entrypoint].description }} ++{{ argument_specs[entrypoint].description | ansible_doc_markup }} + {% else %} + {%- for line in argument_specs[entrypoint].description -%} +-{{ line }} ++{{ line | ansible_doc_markup }} ++ + {% endfor -%} + {% endif -%} + {% endif -%} +@@ -39,7 +40,7 @@ Tags: {{ metadata.galaxy_info.galaxy_tags | join(', ') }} + |Option|Description|Type|Required|Default| + |---|---|---|---|---| + {%- for name, details in options.items() %} +-| {{ name }} | {{ details.display_description }} | {{ details.display_type }} | {{ details.display_required }} | {{ details.display_default }} | ++| {{ name }} | {{ details.display_description | ansible_doc_markup }} | {{ details.display_type }} | {{ details.display_required }} | {{ details.display_default }} | + {%- endfor %} + + {% if entrypoint_options[entrypoint] | length > 1 -%} +@@ -49,7 +50,7 @@ Tags: {{ metadata.galaxy_info.galaxy_tags | join(', ') }} + |Option|Description|Type|Required|Default| + |---|---|---|---|---| + {%- for name, details in options.items() %} +-| {{ name }} | {{ details.display_description }} | {{ details.display_type }} | {{ details.display_required }} | {{ details.display_default }} | ++| {{ name }} | {{ details.display_description | ansible_doc_markup }} | {{ details.display_type }} | {{ details.display_required }} | {{ details.display_default }} | + {%- endfor %} + + {% endfor -%} diff --git a/.forgejo/workflows/ansible-galaxy.yml b/.forgejo/workflows/ansible-galaxy.yml index e79b98f..2ee2794 100644 --- a/.forgejo/workflows/ansible-galaxy.yml +++ b/.forgejo/workflows/ansible-galaxy.yml @@ -22,161 +22,7 @@ jobs: - name: Patch aar-doc run: | cd /usr/local/lib/python3.*/dist-packages/ - patch -p1 <<EOF - --- a/aar_doc/defaults.py - +++ b/aar_doc/defaults.py - @@ -15,7 +15,7 @@ - from ruamel.yaml.scalarstring import LiteralScalarString, SingleQuotedScalarString - - yaml = YAML() - -yaml.indent(mapping=2, sequence=2, offset=2) - +yaml.indent(mapping=2, sequence=4, offset=2) - yaml.encoding = "utf-8" - yaml.allow_unicode = True - - --- a/aar_doc/defaults.py - +++ b/aar_doc/defaults.py - @@ -73,18 +73,27 @@ def add_default( - else: - self._defaults.setdefault(name, RoleDefault(name, value, description)) - - + def safe_quote_recursive(self, value): - + if isinstance(value, list): - + return [self.safe_quote_recursive(v) for v in value] - + elif isinstance(value, dict): - + return {k: self.safe_quote_recursive(v) for k, v in value.items()} - + elif isinstance(value, str): - + if value in ("yes", "no"): - + return SingleQuotedScalarString(value) - + elif "\\n" in value: - + return LiteralScalarString(value) - + elif ":" in value: - + return SingleQuotedScalarString(value) - + return value - + - def to_commented_map(self) -> CommentedMap: - """ - Returns all tracked defaults as a CommentedMap. - """ - commented_defaults = CommentedMap() - for role_default in self.defaults: - - value = role_default.value - - if isinstance(value, str): - - if value in ("yes", "no"): - - value = SingleQuotedScalarString(value) - - if "\\n" in value: - - value = LiteralScalarString(value) - + value = self.safe_quote_recursive(role_default.value) - commented_defaults[role_default.name] = value - description_items = ( - role_default.description - --- a/aar_doc/core.py - +++ b/aar_doc/core.py - @@ -7,6 +7,7 @@ and rendering jinja2 templates from processing data. - - import json - import pathlib - +import re - from enum import Enum - - import jinja2 - @@ -21,6 +22,24 @@ yaml.encoding = "utf-8" - yaml.allow_unicode = True - - - +def ansible_doc_markup(text): - + # Regular expressions copied from ansible-doc: - + # https://github.com/ansible/ansible/blob/devel/lib/ansible/cli/doc.py#L436 - + out = re.sub(r'\\bI\\(([^)]+)\\)', r'*\\1*', text) # I(text) -> *text* - + out = re.sub(r'\\bB\\(([^)]+)\\)', r'**\\1**', out) # B(text) -> **text** - + out = re.sub(r'\\bC\\(([^)]+)\\)', r'`\\1`', out) # C(text) -> `text` - + out = re.sub(r'\\bM\\(([^)]+)\\)', r'`\\1`', out) # M(module) -> `module` - + out = re.sub(r'\\bO\\(((?:[^\\\\)]+|\\\\.)+)\\)', r'`\\1`', out) # O(option) -> `option` - + out = re.sub(r'\\bV\\(((?:[^\\\\)]+|\\\\.)+)\\)', r'`\\1`', out) # V(value) -> `value` - + out = re.sub(r'\\bV\\(((?:[^\\\\)]+|\\\\.)+)\\)', r'`\\1`', out) # E(env) -> `env` - + out = re.sub(r'\\bV\\(((?:[^\\\\)]+|\\\\.)+)\\)', r'`\\1`', out) # RV(retval) -> `retval` - + out = re.sub(r'\\bU\\(([^)]+)\\)', r'[\\1]', out) # U(url) -> [url] - + out = re.sub(r'\\bL\\(([^)]+), *([^)]+)\\)', r'[\\1](\\2)', out) # L(text,url) -> [text](url) - + out = re.sub(r'\\bR\\(([^)]+), *([^)]+)\\)', r'[\\1](#\\2)', out) # R(text,frag) -> [text](#frag) - + out = re.sub(r'\\bHORIZONTALLINE\\b', r'\\n\\n---\\n', out) # HORIZONTALLINE -> --- - + return out - + - + - class OutputMode(Enum): - """ - Defines the options for the output mode. - @@ -240,6 +259,7 @@ def render_content(ctx: typer.Context, content_template: str) -> str: - autoescape=jinja2.select_autoescape(), - undefined=jinja2.StrictUndefined, - ) - + env.filters['ansible_doc_markup'] = ansible_doc_markup - - role = ctx.obj["config"]["role"] - metadata = ctx.obj["data"]["metadata"] - @@ -270,12 +290,14 @@ def render_content(ctx: typer.Context, content_template: str) -> str: - keep_trailing_newline=True, - loader=jinja2.FileSystemLoader([role_path, output_template_file.parent]), - ) - + env.filters['ansible_doc_markup'] = ansible_doc_markup - template = env.get_template(output_template_file.name) - except (FileNotFoundError, OSError): - env = jinja2.Environment( - keep_trailing_newline=True, - loader=jinja2.FileSystemLoader(role_path), - ) - + env.filters['ansible_doc_markup'] = ansible_doc_markup - template = env.from_string(source=output_template) - - return template.render( - --- a/aar_doc/templates/markdown.j2 - +++ b/aar_doc/templates/markdown.j2 - @@ -3,7 +3,7 @@ - {%- if "version" in galaxy_collection %} - Version: {{ galaxy_collection.version }} - {% endif %} - -{{ metadata.galaxy_info.description }} - +{{ metadata.galaxy_info.description | ansible_doc_markup }} - {% if ("galaxy_tags" in metadata.galaxy_info) and (metadata.galaxy_info.galaxy_tags | length > 0) %} - Tags: {{ metadata.galaxy_info.galaxy_tags | join(', ') }} - {%- endif %} - @@ -22,14 +22,15 @@ Tags: {{ metadata.galaxy_info.galaxy_tags | join(', ') }} - - ### Entrypoint: {{ entrypoint }} - - -{{ argument_specs[entrypoint].short_description }} - +{{ argument_specs[entrypoint].short_description | ansible_doc_markup }} - - {% if "description" in argument_specs[entrypoint] %} - {%- if argument_specs[entrypoint].description is string -%} - -{{ argument_specs[entrypoint].description }} - +{{ argument_specs[entrypoint].description | ansible_doc_markup }} - {% else %} - {%- for line in argument_specs[entrypoint].description -%} - -{{ line }} - +{{ line | ansible_doc_markup }} - + - {% endfor -%} - {% endif -%} - {% endif -%} - @@ -39,7 +40,7 @@ Tags: {{ metadata.galaxy_info.galaxy_tags | join(', ') }} - |Option|Description|Type|Required|Default| - |---|---|---|---|---| - {%- for name, details in options.items() %} - -| {{ name }} | {{ details.display_description }} | {{ details.display_type }} | {{ details.display_required }} | {{ details.display_default }} | - +| {{ name }} | {{ details.display_description | ansible_doc_markup }} | {{ details.display_type }} | {{ details.display_required }} | {{ details.display_default }} | - {%- endfor %} - - {% if entrypoint_options[entrypoint] | length > 1 -%} - @@ -49,7 +50,7 @@ Tags: {{ metadata.galaxy_info.galaxy_tags | join(', ') }} - |Option|Description|Type|Required|Default| - |---|---|---|---|---| - {%- for name, details in options.items() %} - -| {{ name }} | {{ details.display_description }} | {{ details.display_type }} | {{ details.display_required }} | {{ details.display_default }} | - +| {{ name }} | {{ details.display_description | ansible_doc_markup }} | {{ details.display_type }} | {{ details.display_required }} | {{ details.display_default }} | - {%- endfor %} - - {% endfor -%} - EOF + patch -p1 < $OLDPWD/.forgejo/workflows/aardoc.patch - name: Set version in galaxy.yml run: |