nixos-render-docs: add some better CLI infrastructure

using environment variables isn't great once multiple input or output
formats get involved (which will happen soon). now is a good time to set
a pattern for future converters.
This commit is contained in:
pennae
2023-01-27 20:07:34 +01:00
parent e0596e0940
commit e8c5618b67
3 changed files with 58 additions and 46 deletions
+7 -8
View File
@@ -148,20 +148,19 @@ in rec {
'';
optionsDocBook = pkgs.runCommand "options-docbook.xml" {
MANPAGE_URLS = pkgs.path + "/doc/manpage-urls.json";
OTD_DOCUMENT_TYPE = documentType;
OTD_VARIABLE_LIST_ID = variablelistId;
OTD_OPTION_ID_PREFIX = optionIdPrefix;
OTD_REVISION = revision;
nativeBuildInputs = [
pkgs.nixos-render-docs
];
} ''
nixos-render-docs \
nixos-render-docs options docbook \
--manpage-urls ${pkgs.path + "/doc/manpage-urls.json"} \
--revision ${lib.escapeShellArg revision} \
--document-type ${lib.escapeShellArg documentType} \
--varlist-id ${lib.escapeShellArg variablelistId} \
--id-prefix ${lib.escapeShellArg optionIdPrefix} \
${lib.optionalString markdownByDefault "--markdown-by-default"} \
${optionsJSON}/share/doc/nixos/options.json \
> options.xml
options.xml
if grep /nixpkgs/nixos/modules options.xml; then
echo "The manual appears to depend on the location of Nixpkgs, which is bad"
@@ -1,45 +1,20 @@
import collections
import json
import argparse
import os
import sys
from collections.abc import MutableMapping, Sequence
from typing import Any, Dict, List
from frozendict import frozendict
from typing import Any, Dict
# for MD conversion
import markdown_it
import markdown_it.renderer
from markdown_it.token import Token
from markdown_it.utils import OptionsDict
from mdit_py_plugins.container import container_plugin
from mdit_py_plugins.deflist import deflist_plugin
from mdit_py_plugins.myst_role import myst_role_plugin
from xml.sax.saxutils import escape, quoteattr
from .md import Converter
from . import options
from .options import DocBookConverter
def main() -> None:
parser = argparse.ArgumentParser(description='render nixos manual bits')
def need_env(n):
if n not in os.environ:
raise RuntimeError("required environment variable not set", n)
return os.environ[n]
commands = parser.add_subparsers(dest='command', required=True)
def main():
markdownByDefault = False
optOffset = 0
for arg in sys.argv[1:]:
if arg == "--markdown-by-default":
optOffset += 1
markdownByDefault = True
options.build_cli(commands.add_parser('options'))
md = DocBookConverter(
json.load(open(os.getenv('MANPAGE_URLS'))),
revision = need_env('OTD_REVISION'),
document_type = need_env('OTD_DOCUMENT_TYPE'),
varlist_id = need_env('OTD_VARIABLE_LIST_ID'),
id_prefix = need_env('OTD_OPTION_ID_PREFIX'),
markdown_by_default = markdownByDefault
)
options = json.load(open(sys.argv[1 + optOffset], 'r'))
md.add_options(options)
print(md.finalize())
args = parser.parse_args()
if args.command == 'options':
options.run_cli(args)
else:
raise RuntimeError('command not hooked up', args)
@@ -1,3 +1,6 @@
import argparse
import json
from abc import abstractmethod
from typing import Any, Optional
from xml.sax.saxutils import escape, quoteattr
@@ -223,3 +226,38 @@ class DocBookConverter(BaseConverter):
result.append("</appendix>")
return "\n".join(result)
def _build_cli_db(p: argparse.ArgumentParser) -> None:
p.add_argument('--manpage-urls', required=True)
p.add_argument('--revision', required=True)
p.add_argument('--document-type', required=True)
p.add_argument('--varlist-id', required=True)
p.add_argument('--id-prefix', required=True)
p.add_argument('--markdown-by-default', default=False, action='store_true')
p.add_argument("infile")
p.add_argument("outfile")
def _run_cli_db(args: argparse.Namespace) -> None:
with open(args.manpage_urls, 'r') as manpage_urls:
md = DocBookConverter(
json.load(manpage_urls),
revision = args.revision,
document_type = args.document_type,
varlist_id = args.varlist_id,
id_prefix = args.id_prefix,
markdown_by_default = args.markdown_by_default)
with open(args.infile, 'r') as f:
md.add_options(json.load(f))
with open(args.outfile, 'w') as f:
f.write(md.finalize())
def build_cli(p: argparse.ArgumentParser) -> None:
formats = p.add_subparsers(dest='format', required=True)
_build_cli_db(formats.add_parser('docbook'))
def run_cli(args: argparse.Namespace) -> None:
if args.format == 'docbook':
_run_cli_db(args)
else:
raise RuntimeError('format not hooked up', args)