summary refs log tree commit diff
path: root/nixos/lib/make-options-doc
diff options
context:
space:
mode:
authorsandydoo <hey@sandydoo.me>2022-12-05 16:05:06 +0000
committersandydoo <hey@sandydoo.me>2022-12-07 14:06:56 +0000
commit926afb6f1c9bcca568eaf12fdd9d16c138a26136 (patch)
treeb04377652d7ad2058a1e31f5edc268051a3476fe /nixos/lib/make-options-doc
parent1792d2f5c5e4fc9d656a155f8e1d35fffbd1ecbc (diff)
nixos/make-options-doc: pretty-print literals
Unlike the XML doc renderer, the AsciiDoc and CommonMark renderers don't
pretty-print certain complex types, like literal expressions, DocBook
literals, and derivations. These types are dumped into the documentation
as JSON.

This commit parses and unwraps these types when loading the
JSON-formatted NixOS options. The AsciiDoc and CommonMark renders have
also been combined into a single script to allow code reuse.
Diffstat (limited to 'nixos/lib/make-options-doc')
-rw-r--r--nixos/lib/make-options-doc/default.nix10
-rw-r--r--nixos/lib/make-options-doc/generateAsciiDoc.py37
-rw-r--r--nixos/lib/make-options-doc/generateCommonMark.py27
-rw-r--r--nixos/lib/make-options-doc/generateDoc.py106
4 files changed, 112 insertions, 68 deletions
diff --git a/nixos/lib/make-options-doc/default.nix b/nixos/lib/make-options-doc/default.nix
index e097aa5eebd8e..694512115d40a 100644
--- a/nixos/lib/make-options-doc/default.nix
+++ b/nixos/lib/make-options-doc/default.nix
@@ -111,14 +111,16 @@ in rec {
   inherit optionsNix;
 
   optionsAsciiDoc = pkgs.runCommand "options.adoc" {} ''
-    ${pkgs.python3Minimal}/bin/python ${./generateAsciiDoc.py} \
-      < ${optionsJSON}/share/doc/nixos/options.json \
+    ${pkgs.python3Minimal}/bin/python ${./generateDoc.py} \
+      --format asciidoc \
+      ${optionsJSON}/share/doc/nixos/options.json \
       > $out
   '';
 
   optionsCommonMark = pkgs.runCommand "options.md" {} ''
-    ${pkgs.python3Minimal}/bin/python ${./generateCommonMark.py} \
-      < ${optionsJSON}/share/doc/nixos/options.json \
+    ${pkgs.python3Minimal}/bin/python ${./generateDoc.py} \
+      --format commonmark \
+      ${optionsJSON}/share/doc/nixos/options.json \
       > $out
   '';
 
diff --git a/nixos/lib/make-options-doc/generateAsciiDoc.py b/nixos/lib/make-options-doc/generateAsciiDoc.py
deleted file mode 100644
index 48eadd248c5a0..0000000000000
--- a/nixos/lib/make-options-doc/generateAsciiDoc.py
+++ /dev/null
@@ -1,37 +0,0 @@
-import json
-import sys
-
-options = json.load(sys.stdin)
-# TODO: declarations: link to github
-for (name, value) in options.items():
-    print(f'== {name}')
-    print()
-    print(value['description'])
-    print()
-    print('[discrete]')
-    print('=== details')
-    print()
-    print(f'Type:: {value["type"]}')
-    if 'default' in value:
-        print('Default::')
-        print('+')
-        print('----')
-        print(json.dumps(value['default'], ensure_ascii=False, separators=(',', ':')))
-        print('----')
-        print()
-    else:
-        print('No Default:: {blank}')
-    if value['readOnly']:
-        print('Read Only:: {blank}')
-    else:
-        print()
-    if 'example' in value:
-        print('Example::')
-        print('+')
-        print('----')
-        print(json.dumps(value['example'], ensure_ascii=False, separators=(',', ':')))
-        print('----')
-        print()
-    else:
-        print('No Example:: {blank}')
-    print()
diff --git a/nixos/lib/make-options-doc/generateCommonMark.py b/nixos/lib/make-options-doc/generateCommonMark.py
deleted file mode 100644
index bf487bd89c3f8..0000000000000
--- a/nixos/lib/make-options-doc/generateCommonMark.py
+++ /dev/null
@@ -1,27 +0,0 @@
-import json
-import sys
-
-options = json.load(sys.stdin)
-for (name, value) in options.items():
-    print('##', name.replace('<', '&lt;').replace('>', '&gt;'))
-    print(value['description'])
-    print()
-    if 'type' in value:
-        print('*_Type_*:')
-        print(value['type'])
-        print()
-    print()
-    if 'default' in value:
-        print('*_Default_*')
-        print('```')
-        print(json.dumps(value['default'], ensure_ascii=False, separators=(',', ':')))
-        print('```')
-    print()
-    print()
-    if 'example' in value:
-        print('*_Example_*')
-        print('```')
-        print(json.dumps(value['example'], ensure_ascii=False, separators=(',', ':')))
-        print('```')
-    print()
-    print()
diff --git a/nixos/lib/make-options-doc/generateDoc.py b/nixos/lib/make-options-doc/generateDoc.py
new file mode 100644
index 0000000000000..dffa8cd614012
--- /dev/null
+++ b/nixos/lib/make-options-doc/generateDoc.py
@@ -0,0 +1,106 @@
+import argparse
+import json
+import sys
+
+formats = ['commonmark', 'asciidoc']
+
+parser = argparse.ArgumentParser(
+    description = 'Generate documentation for a set of JSON-formatted NixOS options'
+)
+parser.add_argument(
+    'nix_options_path',
+    help = 'a path to a JSON file containing the NixOS options'
+)
+parser.add_argument(
+    '-f',
+    '--format',
+    choices = formats,
+    required = True,
+    help = f'the documentation format to generate'
+)
+
+args = parser.parse_args()
+
+# Pretty-print certain Nix types, like literal expressions.
+def render_types(obj):
+    if '_type' not in obj: return obj
+
+    _type = obj['_type']
+    if _type == 'literalExpression' or _type == 'literalDocBook':
+        return obj['text']
+
+    if _type == 'derivation':
+        return obj['name']
+
+    raise Exception(f'Unexpected type `{_type}` in {json.dumps(obj)}')
+
+def generate_commonmark(options):
+    for (name, value) in options.items():
+        print('##', name.replace('<', '&lt;').replace('>', '&gt;'))
+        print(value['description'])
+        print()
+        if 'type' in value:
+            print('*_Type_*:')
+            print(value['type'])
+            print()
+        print()
+        if 'default' in value:
+            print('*_Default_*')
+            print('```')
+            print(json.dumps(value['default'], ensure_ascii=False, separators=(',', ':')))
+            print('```')
+        print()
+        print()
+        if 'example' in value:
+            print('*_Example_*')
+            print('```')
+            print(json.dumps(value['example'], ensure_ascii=False, separators=(',', ':')))
+            print('```')
+        print()
+        print()
+
+# TODO: declarations: link to github
+def generate_asciidoc(options):
+    for (name, value) in options.items():
+        print(f'== {name}')
+        print()
+        print(value['description'])
+        print()
+        print('[discrete]')
+        print('=== details')
+        print()
+        print(f'Type:: {value["type"]}')
+        if 'default' in value:
+            print('Default::')
+            print('+')
+            print('----')
+            print(json.dumps(value['default'], ensure_ascii=False, separators=(',', ':')))
+            print('----')
+            print()
+        else:
+            print('No Default:: {blank}')
+        if value['readOnly']:
+            print('Read Only:: {blank}')
+        else:
+            print()
+        if 'example' in value:
+            print('Example::')
+            print('+')
+            print('----')
+            print(json.dumps(value['example'], ensure_ascii=False, separators=(',', ':')))
+            print('----')
+            print()
+        else:
+            print('No Example:: {blank}')
+        print()
+
+with open(args.nix_options_path) as nix_options_json:
+    options = json.load(nix_options_json, object_hook=render_types)
+
+    if args.format == 'commonmark':
+        generate_commonmark(options)
+    elif args.format == 'asciidoc':
+        generate_asciidoc(options)
+    else:
+        raise Exception(f'Unsupported documentation format `--format {args.format}`')
+