Files
simple-nixos-mailserver/scripts/generate-options.py
T
Martin Weinelt 0da8e2b197 quota: expose global quota settings
With the options in the upstream dovecot module gone the quota support
and its option now live in our downstream module.

The only behavior change this introduces is not setting a global per
user default instead of the previous 100G per user.

Diabling quota support and setting per user quotas now raises an
assertion:

````
Failed assertions:
- Without quota support enabled, per-user quotas cannot be applied to the following accounts:

  - lowquota@example.com

  Either remove per user quota settings or re-enable `mailserver.quota.enable`.
````
2026-04-13 01:19:14 +02:00

121 lines
2.8 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.storage",
"mailserver.dkim",
"mailserver.srs",
"mailserver.dmarcReporting",
"mailserver.tlsrpt",
"mailserver.fullTextSearch",
"mailserver.quota",
"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)