nixos-mailserver/scripts/generate-options.py

110 lines
2.6 KiB
Python
Raw Normal View History

2022-11-30 22:30:45 +01:00
import json
import sys
from textwrap import indent
from typing import Any, Mapping
2022-11-30 22:30:45 +01:00
header = """
# Mailserver options
## `mailserver`
"""
template = """
`````{{option}} {key}
{description}
{type}
{default}
{example}
`````
"""
f = open(sys.argv[1])
options = json.load(f)
2025-05-08 01:40:37 +02:00
groups = [
"mailserver.loginAccounts",
"mailserver.certificate",
"mailserver.dkim",
"mailserver.dmarcReporting",
"mailserver.fullTextSearch",
"mailserver.redis",
"mailserver.ldap",
"mailserver.monitoring",
"mailserver.backup",
"mailserver.borgbackup",
]
2022-11-30 22:30:45 +01:00
def md_literal(value: str) -> str:
return f"`{value}`"
def md_codefence(value: str, language: str = "nix") -> str:
return indent(
f"\n```{language}\n{value}\n```",
prefix=2 * " ",
)
def render_option_value(option: Mapping[str, Any], key: str) -> str:
if key not in option:
return ""
if isinstance(option[key], dict) and "_type" in option[key]:
if option[key]["_type"] == "literalExpression":
# multi-line codeblock
if "\n" in option[key]["text"]:
text = option[key]["text"].rstrip("\n")
value = md_codefence(text)
# inline codeblock
else:
value = md_literal(option[key]["text"])
# literal markdown
elif option[key]["_type"] == "literalMD":
value = option[key]["text"]
else:
assert RuntimeError(f"Unhandled option type {option[key]['_type']}")
else:
text = str(option[key])
if text == "":
value = md_literal('""')
elif "\n" in text:
value = md_codefence(text.rstrip("\n"))
else:
value = md_literal(text)
2025-05-08 01:40:37 +02:00
return f"- {key}: {value}" # type: ignore
2022-11-30 22:30:45 +01:00
def print_option(option):
if (
isinstance(option["description"], dict) and "_type" in option["description"]
): # mdDoc
description = option["description"]["text"]
2022-11-30 22:30:45 +01:00
else:
description = option["description"]
2025-05-08 01:40:37 +02:00
print(
template.format(
key=option["name"],
2025-05-08 01:40:37 +02:00
description=description or "",
type=f"- type: {md_literal(option['type'])}",
default=render_option_value(option, "default"),
example=render_option_value(option, "example"),
2025-05-08 01:40:37 +02:00
)
)
2022-11-30 22:30:45 +01:00
print(header)
for opt in options:
2025-05-08 01:40:37 +02:00
if any([opt["name"].startswith(c) for c in groups]):
2022-11-30 22:30:45 +01:00
continue
print_option(opt)
for c in groups:
print(f"## `{c}`\n")
2022-11-30 22:30:45 +01:00
for opt in options:
2025-05-08 01:40:37 +02:00
if opt["name"].startswith(c):
2022-11-30 22:30:45 +01:00
print_option(opt)