summaryrefslogtreecommitdiffstats
path: root/nixos
diff options
context:
space:
mode:
authorSilvan Mosberger <contact@infinisil.com>2021-12-08 21:27:02 +0100
committerGitHub <noreply@github.com>2021-12-08 21:27:02 +0100
commit15c41e1d54fca9ba6f3c7fbaf294b8af139fbca2 (patch)
tree21a29d4eb2ee33c357a04a939ef68f861cea0b31 /nixos
parent0d85aadbf639e143421ed461ab0a9c42f5f99781 (diff)
parent027f7e1b7f4552c9c9f0ff909a6863d5bf347a72 (diff)
Merge pull request #147265 from pennae/option-docs-build
put all option docs build flavors on equal footing
Diffstat (limited to 'nixos')
-rw-r--r--nixos/doc/manual/default.nix2
-rw-r--r--nixos/lib/make-options-doc/default.nix129
-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/options-to-docbook.xsl2
-rw-r--r--nixos/lib/make-options-doc/optionsJSONtoXML.nix6
-rw-r--r--nixos/lib/make-options-doc/sortXML.py1
7 files changed, 110 insertions, 94 deletions
diff --git a/nixos/doc/manual/default.nix b/nixos/doc/manual/default.nix
index 151743d9fb58..31b6da01c6bd 100644
--- a/nixos/doc/manual/default.nix
+++ b/nixos/doc/manual/default.nix
@@ -161,7 +161,7 @@ let
in rec {
inherit generatedSources;
- inherit (optionsDoc) optionsJSON optionsXML optionsDocBook;
+ inherit (optionsDoc) optionsJSON optionsDocBook;
# Generate the NixOS manual.
manualHTML = runCommand "nixos-manual-html"
diff --git a/nixos/lib/make-options-doc/default.nix b/nixos/lib/make-options-doc/default.nix
index e058e70f3888..493006c92e7f 100644
--- a/nixos/lib/make-options-doc/default.nix
+++ b/nixos/lib/make-options-doc/default.nix
@@ -24,18 +24,25 @@
}:
let
- # Replace functions by the string <function>
- substFunction = x:
- if builtins.isAttrs x then lib.mapAttrs (name: substFunction) x
- else if builtins.isList x then map substFunction x
+ # Make a value safe for JSON. Functions are replaced by the string "<function>",
+ # derivations are replaced with an attrset
+ # { _type = "derivation"; name = <name of that derivation>; }.
+ # We need to handle derivations specially because consumers want to know about them,
+ # but we can't easily use the type,name subset of keys (since type is often used as
+ # a module option and might cause confusion). Use _type,name instead to the same
+ # effect, since _type is already used by the module system.
+ substSpecial = x:
+ if lib.isDerivation x then { _type = "derivation"; name = x.name; }
+ else if builtins.isAttrs x then lib.mapAttrs (name: substSpecial) x
+ else if builtins.isList x then map substSpecial x
else if lib.isFunction x then "<function>"
else x;
- optionsListDesc = lib.flip map optionsListVisible
+ optionsList = lib.flip map optionsListVisible
(opt: transformOptions opt
- // lib.optionalAttrs (opt ? example) { example = substFunction opt.example; }
- // lib.optionalAttrs (opt ? default) { default = substFunction opt.default; }
- // lib.optionalAttrs (opt ? type) { type = substFunction opt.type; }
+ // lib.optionalAttrs (opt ? example) { example = substSpecial opt.example; }
+ // lib.optionalAttrs (opt ? default) { default = substSpecial opt.default; }
+ // lib.optionalAttrs (opt ? type) { type = substSpecial opt.type; }
// lib.optionalAttrs (opt ? relatedPackages && opt.relatedPackages != []) { relatedPackages = genRelatedPackages opt.relatedPackages opt.name; }
);
@@ -69,96 +76,25 @@ let
+ "</listitem>";
in "<itemizedlist>${lib.concatStringsSep "\n" (map (p: describe (unpack p)) packages)}</itemizedlist>";
- # Custom "less" that pushes up all the things ending in ".enable*"
- # and ".package*"
- optionLess = a: b:
- let
- ise = lib.hasPrefix "enable";
- isp = lib.hasPrefix "package";
- cmp = lib.splitByAndCompare ise lib.compare
- (lib.splitByAndCompare isp lib.compare lib.compare);
- in lib.compareLists cmp a.loc b.loc < 0;
-
# Remove invisible and internal options.
optionsListVisible = lib.filter (opt: opt.visible && !opt.internal) (lib.optionAttrSetToDocList options);
- # Customly sort option list for the man page.
- # Always ensure that the sort order matches sortXML.py!
- optionsList = lib.sort optionLess optionsListDesc;
-
- # Convert the list of options into an XML file.
- # This file is *not* sorted sorted to save on eval time, since the docbook XML
- # and the manpage depend on it and thus we evaluate this on every system rebuild.
- optionsXML = builtins.toFile "options.xml" (builtins.toXML optionsListDesc);
-
optionsNix = builtins.listToAttrs (map (o: { name = o.name; value = removeAttrs o ["name" "visible" "internal"]; }) optionsList);
- # TODO: declarations: link to github
- singleAsciiDoc = name: value: ''
- == ${name}
-
- ${value.description}
-
- [discrete]
- === details
-
- Type:: ${value.type}
- ${ if lib.hasAttr "default" value
- then ''
- Default::
- +
- ----
- ${builtins.toJSON value.default}
- ----
- ''
- else "No Default:: {blank}"
- }
- ${ if value.readOnly
- then "Read Only:: {blank}"
- else ""
- }
- ${ if lib.hasAttr "example" value
- then ''
- Example::
- +
- ----
- ${builtins.toJSON value.example}
- ----
- ''
- else "No Example:: {blank}"
- }
- '';
-
- singleMDDoc = name: value: ''
- ## ${lib.escape [ "<" ">" ] name}
- ${value.description}
-
- ${lib.optionalString (value ? type) ''
- *_Type_*:
- ${value.type}
- ''}
-
- ${lib.optionalString (value ? default) ''
- *_Default_*
- ```
- ${builtins.toJSON value.default}
- ```
- ''}
-
- ${lib.optionalString (value ? example) ''
- *_Example_*
- ```
- ${builtins.toJSON value.example}
- ```
- ''}
- '';
-
-in {
+in rec {
inherit optionsNix;
- optionsAsciiDoc = lib.concatStringsSep "\n" (lib.mapAttrsToList singleAsciiDoc optionsNix);
+ optionsAsciiDoc = pkgs.runCommand "options.adoc" {} ''
+ ${pkgs.python3Minimal}/bin/python ${./generateAsciiDoc.py} \
+ < ${optionsJSON}/share/doc/nixos/options.json \
+ > $out
+ '';
- optionsMDDoc = lib.concatStringsSep "\n" (lib.mapAttrsToList singleMDDoc optionsNix);
+ optionsCommonMark = pkgs.runCommand "options.md" {} ''
+ ${pkgs.python3Minimal}/bin/python ${./generateCommonMark.py} \
+ < ${optionsJSON}/share/doc/nixos/options.json \
+ > $out
+ '';
optionsJSON = pkgs.runCommand "options.json"
{ meta.description = "List of NixOS options in JSON format";
@@ -176,7 +112,18 @@ in {
mkdir -p $out/nix-support
echo "file json $dst/options.json" >> $out/nix-support/hydra-build-products
echo "file json-br $dst/options.json.br" >> $out/nix-support/hydra-build-products
- ''; # */
+ '';
+
+ # Convert options.json into an XML file.
+ # The actual generation of the xml file is done in nix purely for the convenience
+ # of not having to generate the xml some other way
+ optionsXML = pkgs.runCommand "options.xml" {} ''
+ ${pkgs.nix}/bin/nix-instantiate \
+ --store dummy:// \
+ --eval --xml --strict ${./optionsJSONtoXML.nix} \
+ --argstr file ${optionsJSON}/share/doc/nixos/options.json \
+ > "$out"
+ '';
optionsDocBook = pkgs.runCommand "options-docbook.xml" {} ''
optionsXML=${optionsXML}
diff --git a/nixos/lib/make-options-doc/generateAsciiDoc.py b/nixos/lib/make-options-doc/generateAsciiDoc.py
new file mode 100644
index 000000000000..48eadd248c5a
--- /dev/null
+++ b/nixos/lib/make-options-doc/generateAsciiDoc.py
@@ -0,0 +1,37 @@
+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
new file mode 100644
index 000000000000..404e53b0df9c
--- /dev/null
+++ b/nixos/lib/make-options-doc/generateCommonMark.py
@@ -0,0 +1,27 @@
+import json
+import sys
+
+options = json.load(sys.stdin)
+for (name, value) in options.items():
+ print('##', name.replace('<', '\\<').replace('>', '\\>'))
+ 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/options-to-docbook.xsl b/nixos/lib/make-options-doc/options-to-docbook.xsl
index da4cd164bf20..b9ac26450514 100644
--- a/nixos/lib/make-options-doc/options-to-docbook.xsl
+++ b/nixos/lib/make-options-doc/options-to-docbook.xsl
@@ -189,7 +189,7 @@
</xsl:template>
- <xsl:template match="derivation">
+ <xsl:template match="attrs[attr[@name = '_type' and string[@value = 'derivation']]]">
<replaceable>(build of <xsl:value-of select="attr[@name = 'name']/string/@value" />)</replaceable>
</xsl:template>
diff --git a/nixos/lib/make-options-doc/optionsJSONtoXML.nix b/nixos/lib/make-options-doc/optionsJSONtoXML.nix
new file mode 100644
index 000000000000..ba50c5f898b5
--- /dev/null
+++ b/nixos/lib/make-options-doc/optionsJSONtoXML.nix
@@ -0,0 +1,6 @@
+{ file }:
+
+builtins.attrValues
+ (builtins.mapAttrs
+ (name: def: def // { inherit name; })
+ (builtins.fromJSON (builtins.readFile file)))
diff --git a/nixos/lib/make-options-doc/sortXML.py b/nixos/lib/make-options-doc/sortXML.py
index 717820788c94..e63ff3538b3f 100644
--- a/nixos/lib/make-options-doc/sortXML.py
+++ b/nixos/lib/make-options-doc/sortXML.py
@@ -19,7 +19,6 @@ def sortKey(opt):
for p in opt.findall('attr[@name="loc"]/list/string')
]
-# always ensure that the sort order matches the order used in the nix expression!
options.sort(key=sortKey)
doc = ET.Element("expr")