Skip to content

Commit

Permalink
✨[#64] add setup config rst templates
Browse files Browse the repository at this point in the history
  • Loading branch information
Coperh committed Oct 2, 2024
1 parent 3a07693 commit a91a8ae
Show file tree
Hide file tree
Showing 6 changed files with 198 additions and 22 deletions.
156 changes: 141 additions & 15 deletions open_api_framework/management/commands/generate_envvar_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from django.template import loader
from django.utils.module_loading import import_string

from django_setup_configuration.config_settings import ConfigSettings
from django_setup_configuration.management.commands.generate_config_docs import (
ConfigDocBase,
)
Expand All @@ -27,7 +28,140 @@ def convert_variables_to_rst(variables: list[EnvironmentVariable]) -> str:
return template.render({"vars": vars})


class Command(ConfigDocBase, BaseCommand):
class SetupConfigDocs(ConfigDocBase):

def generate_config_file(self) -> str:

full_rendered_content = ""

if not hasattr(settings, "SETUP_CONFIGURATION_STEPS"):
return full_rendered_content

for config_string in settings.SETUP_CONFIGURATION_STEPS:
config_step = import_string(config_string)

config_settings = getattr(config_step, "config_settings", None)
if not config_settings or not config_settings.independent:
continue

rendered_content = self.render_doc(config_settings, config_step)
full_rendered_content += rendered_content

template = loader.get_template("open_api_framework/setup_config.rst")
rendered = template.render(
{"rendered_configuration_steps": full_rendered_content}
)

return rendered

def render_doc(self, config_settings, config_step) -> str:
"""
Render a `ConfigSettings` documentation template with the following variables:
1. enable_setting
2. required_settings
3. optional_settings
4. detailed_info
5. title
"""
# 1.
enable_setting = getattr(config_settings, "enable_setting", None)

# 2.
required_settings = [
name for name in getattr(config_settings, "required_settings", [])
]

# additional settings from related configuration steps to embed
# the documentation of several steps into one
related_config_settings = [
config for config in getattr(config_settings, "related_config_settings", [])
]
required_settings_related = self.extract_unique_settings(
[config.required_settings for config in related_config_settings]
)
# optional_settings_related = self.extract_unique_settings(
# [config.optional_settings for config in related_config_settings]
# )

required_settings.extend(required_settings_related)
required_settings.sort()

optional_settings = config_settings.optional_settings
optional_settings.sort()

# 4.
detailed_info = self.get_detailed_info(
config_settings,
related_config_settings,
)

# 5.
title = self.format_display_name(config_step.verbose_name)

template_variables = {
"enable_setting": enable_setting,
"required_settings": required_settings,
"optional_settings": optional_settings,
"detailed_info": detailed_info,
"title": title,
}

template = loader.get_template(
"open_api_framework/components/setup_config_step.rst"
)
rendered = template.render(template_variables)

return rendered

def format_display_name(self, display_name: str) -> str:
"""Underlines title with '=' to display as heading in rst file"""

heading_bar = "-" * len(display_name)
display_name_formatted = f"{display_name}\n{heading_bar}"
return display_name_formatted

def get_detailed_info(
self,
config_settings: ConfigSettings,
related_config_settings: list[ConfigSettings],
) -> dict[dict[str]]:
"""
Get information about the configuration settings:
1. from model fields associated with the `ConfigSettings`
2. from information provided manually in the `ConfigSettings`
3. from information provided manually in the `ConfigSettings` of related
configuration steps
"""
result = dict()
for field in config_settings.config_fields:
part = dict()
variable = config_settings.get_config_variable(field.name)
part["setting"] = field.verbose_name
part["description"] = field.description or 'No description'
part["possible_values"] = field.field_description
part["default_value"] = field.default_value

result[variable] = part

self.add_additional_info(config_settings, result)
for config_settings in related_config_settings:
self.add_additional_info(config_settings, result)

return result

@staticmethod
def add_additional_info(
config_settings: ConfigSettings, result: dict[dict[str]]
) -> None:
"""Convenience/helper function to retrieve additional documentation info"""

additional_info = config_settings.additional_info

for key, value in additional_info.items():
result[key] = value


class Command(BaseCommand):
help = "Generate documentation for all used envvars"

def add_arguments(self, parser):
Expand Down Expand Up @@ -55,7 +189,8 @@ def handle(self, *args, **options):
self.generate_regular_config_docs(*args, **options)
self.generate_setup_config_docs(*args, **options)

def generate_regular_config_docs(self, *args, **options):
@staticmethod
def generate_regular_config_docs(*args, **options):
from open_api_framework.conf.utils import ENVVAR_REGISTRY

file_path = options["envvar_file"]
Expand All @@ -77,22 +212,13 @@ def _sort(envvar):
with open(file_path, "w") as f:
f.write(convert_variables_to_rst(sorted_registry))

def generate_setup_config_docs(self, *args, **options) -> None:
full_rendered_content = ""
@staticmethod
def generate_setup_config_docs(*args, **options) -> None:

file_path = options["config_file"]
if not hasattr(settings, "SETUP_CONFIGURATION_STEPS"):
return
doc_generator = SetupConfigDocs()

for config_string in settings.SETUP_CONFIGURATION_STEPS:
config_step = import_string(config_string)

config_settings = getattr(config_step, "config_settings", None)
if not config_settings or not config_settings.independent:
continue

rendered_content = self.render_doc(config_settings, config_step)
full_rendered_content += rendered_content
full_rendered_content = doc_generator.generate_config_file()

if len(full_rendered_content) > 0:
with open(file_path, "w") as f:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{% load doc_tags %}
{% spaceless %}
{{ title }}

Enable/Disable configuration:
"""""""""""""""""""""""""""""

::

{{ enable_setting }}

{% if required_settings %}
Required settings
"""""""""""""""""
{% for setting in required_settings %}
* ``{{ setting }}``: {% config_var_description setting detailed_info %}
{% endfor %}{% endif %}

{% if optional_settings %}
Optional Settings
"""""""""""""""""
{% for setting in optional_settings %}
* ``{{ setting }}``: {% config_var_description setting detailed_info %}
{% endfor %}{% endif %}

{% endspaceless %}
15 changes: 9 additions & 6 deletions open_api_framework/templates/open_api_framework/env_config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@ Available environment variables

{% for group_name, group_vars in vars %}
{{group_name}}
{{group_name|repeat_char:"-"}}{% for subgroup_name, subgroup_vars in group_vars %}
{% if subgroup_name is not null %}
{{group_name|repeat_char:"-"}}

{% spaceless %}{% for subgroup_name, subgroup_vars in group_vars %}{% if subgroup_name is not null %}
{{subgroup_name}}
{{subgroup_name|repeat_char:"^"}}
{% endif %}
{% for var in subgroup_vars %}* ``{{var.name}}``: {% if var.help_text %}{{var.help_text|safe|ensure_endswith:"."}}{% endif %}{% if var.auto_display_default and not var.default|is_undefined %} Defaults to: ``{{var.default|to_str|safe}}``.{% endif %}
{% endfor %}{% endfor %}
{{subgroup_name|repeat_char:"^"}}{% endif %}

{% spaceless %}
{% for var in subgroup_vars %}
* ``{{var.name}}``: {% if var.help_text %}{{var.help_text|safe|ensure_endswith:"."}}{% endif %}{% if var.auto_display_default and not var.default|is_undefined %} Defaults to: ``{{var.default|to_str|safe}}``.{% endif %}{% endfor %}{% endspaceless %}{% endfor %}{% endspaceless %}

{% endfor %}

{% block extra %}{% endblock %}
Expand Down
16 changes: 16 additions & 0 deletions open_api_framework/templates/open_api_framework/setup_config.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{% load doc_tags %}.. _installation_setup_config:

=============================
Setup configuration reference
=============================

{% block intro %}
Setup configuration description
{% endblock %}

Configuration Environment Variables
===================================

All configuration steps currently available:

{{ rendered_configuration_steps | safe }}
5 changes: 5 additions & 0 deletions open_api_framework/templatetags/doc_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,8 @@ def ensure_endswith(value, char):
if not value.endswith(char):
value += char
return value

@register.filter()
def config_var_description(variable, details):

return details[variable].get("description")
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ extras =
deps =
django42: Django~=4.2.0
commands =
py.test tests \
py.test tests -vv \
--cov --cov-report xml:reports/coverage-{envname}.xml \
{posargs}

Expand Down

0 comments on commit a91a8ae

Please sign in to comment.