e9337b346f
The "login" prefix makes this option more confusing rather than clearer, because what other account types are there? LDAP ones for example, but you can login with those too, so the prefix is pointless.
119 lines
2.7 KiB
Python
119 lines
2.7 KiB
Python
import json
|
|
import sys
|
|
from textwrap import indent
|
|
from typing import Any, Mapping
|
|
|
|
header = """
|
|
# Mailserver options
|
|
|
|
## `mailserver`
|
|
|
|
"""
|
|
|
|
template = """
|
|
({key})=
|
|
`````{{option}} {key}
|
|
{description}
|
|
|
|
{type}
|
|
{default}
|
|
{example}
|
|
`````
|
|
"""
|
|
|
|
f = open(sys.argv[1])
|
|
options = json.load(f)
|
|
|
|
groups = [
|
|
"mailserver.accounts",
|
|
"mailserver.x509",
|
|
"mailserver.dkim",
|
|
"mailserver.srs",
|
|
"mailserver.dmarcReporting",
|
|
"mailserver.tlsrpt",
|
|
"mailserver.fullTextSearch",
|
|
"mailserver.redis",
|
|
"mailserver.ldap",
|
|
"mailserver.monitoring",
|
|
"mailserver.backup",
|
|
"mailserver.borgbackup",
|
|
]
|
|
|
|
|
|
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 ""
|
|
|
|
value = None
|
|
|
|
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)
|
|
|
|
assert value is not None
|
|
|
|
return f"- {key}: {value}"
|
|
|
|
|
|
def print_option(option):
|
|
if (
|
|
isinstance(option["description"], dict) and "_type" in option["description"]
|
|
): # mdDoc
|
|
description = option["description"]["text"]
|
|
else:
|
|
description = option["description"]
|
|
print(
|
|
template.format(
|
|
key=option["name"],
|
|
description=description or "",
|
|
type=f"- type: {md_literal(option['type'])}",
|
|
default=render_option_value(option, "defaultText")
|
|
if "defaultText" in option
|
|
else render_option_value(option, "default"),
|
|
example=render_option_value(option, "example"),
|
|
)
|
|
)
|
|
|
|
|
|
print(header)
|
|
for opt in options:
|
|
if any([opt["name"].startswith(c) for c in groups]):
|
|
continue
|
|
print_option(opt)
|
|
|
|
for c in groups:
|
|
print(f"## `{c}`\n")
|
|
for opt in options:
|
|
if opt["name"].startswith(c):
|
|
print_option(opt)
|