make-options-docs: don't sort the options XML file

we need the file itself as a dependency for the docbook build, but we don't need
it to be properly sorted at the nix level. push the sort out to a python script
instead to save eval time. on the machine used to write this `nix-instantiate
<nixos/nixos> -A system` went down from 7.1s to 5.4s and GC heap size decreased
by 50MB (or 70MB max RSS).

pennae 24eb3539 97774c04

Changed files
+34 -2
nixos
lib
make-options-doc
+6 -2
nixos/lib/make-options-doc/default.nix
···
optionsListVisible = lib.filter (opt: opt.visible && !opt.internal) (lib.optionAttrSetToDocList options);
# Customly sort option list for the man page.
optionsList = lib.sort optionLess optionsListDesc;
# Convert the list of options into an XML file.
-
optionsXML = builtins.toFile "options.xml" (builtins.toXML optionsList);
optionsNix = builtins.listToAttrs (map (o: { name = o.name; value = removeAttrs o ["name" "visible" "internal"]; }) optionsList);
···
exit 1
fi
${pkgs.libxslt.bin}/bin/xsltproc \
--stringparam revision '${revision}' \
-
-o intermediate.xml ${./options-to-docbook.xsl} $optionsXML
${pkgs.libxslt.bin}/bin/xsltproc \
-o "$out" ${./postprocess-option-descriptions.xsl} intermediate.xml
'';
···
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);
···
exit 1
fi
+
${pkgs.python3Minimal}/bin/python ${./sortXML.py} $optionsXML sorted.xml
${pkgs.libxslt.bin}/bin/xsltproc \
--stringparam revision '${revision}' \
+
-o intermediate.xml ${./options-to-docbook.xsl} sorted.xml
${pkgs.libxslt.bin}/bin/xsltproc \
-o "$out" ${./postprocess-option-descriptions.xsl} intermediate.xml
'';
+28
nixos/lib/make-options-doc/sortXML.py
···
···
+
import xml.etree.ElementTree as ET
+
import sys
+
+
tree = ET.parse(sys.argv[1])
+
# the xml tree is of the form
+
# <expr><list> {all options, each an attrs} </list></expr>
+
options = list(tree.getroot().find('list'))
+
+
def sortKey(opt):
+
def order(s):
+
if s.startswith("enable"):
+
return 0
+
if s.startswith("package"):
+
return 1
+
return 2
+
+
return [
+
(order(p.attrib['value']), p.attrib['value'])
+
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")
+
newOptions = ET.SubElement(doc, "list")
+
newOptions.extend(options)
+
ET.ElementTree(doc).write(sys.argv[2], encoding='utf-8')