diff --git a/nixos/lib/make-options-doc/default.nix b/nixos/lib/make-options-doc/default.nix index 14015ab64abb..e058e70f3888 100644 --- a/nixos/lib/make-options-doc/default.nix +++ b/nixos/lib/make-options-doc/default.nix @@ -83,10 +83,13 @@ let 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. - optionsXML = builtins.toFile "options.xml" (builtins.toXML optionsList); + # 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); @@ -185,9 +188,10 @@ in { 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} $optionsXML + -o intermediate.xml ${./options-to-docbook.xsl} sorted.xml ${pkgs.libxslt.bin}/bin/xsltproc \ -o "$out" ${./postprocess-option-descriptions.xsl} intermediate.xml ''; diff --git a/nixos/lib/make-options-doc/sortXML.py b/nixos/lib/make-options-doc/sortXML.py new file mode 100644 index 000000000000..717820788c94 --- /dev/null +++ b/nixos/lib/make-options-doc/sortXML.py @@ -0,0 +1,28 @@ +import xml.etree.ElementTree as ET +import sys + +tree = ET.parse(sys.argv[1]) +# the xml tree is of the form +# {all options, each an attrs} +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')