at 23.11-pre 7.1 kB view raw
1/* Generate JSON, XML and DocBook documentation for given NixOS options. 2 3 Minimal example: 4 5 { pkgs, }: 6 7 let 8 eval = import (pkgs.path + "/nixos/lib/eval-config.nix") { 9 baseModules = [ 10 ../module.nix 11 ]; 12 modules = []; 13 }; 14 in pkgs.nixosOptionsDoc { 15 options = eval.options; 16 } 17 18*/ 19{ pkgs 20, lib 21, options 22, transformOptions ? lib.id # function for additional transformations of the options 23, documentType ? "appendix" # TODO deprecate "appendix" in favor of "none" 24 # and/or rename function to moduleOptionDoc for clean slate 25 26 # If you include more than one option list into a document, you need to 27 # provide different ids. 28, variablelistId ? "configuration-variable-list" 29 # String to prefix to the option XML/HTML id attributes. 30, optionIdPrefix ? "opt-" 31, revision ? "" # Specify revision for the options 32# a set of options the docs we are generating will be merged into, as if by recursiveUpdate. 33# used to split the options doc build into a static part (nixos/modules) and a dynamic part 34# (non-nixos modules imported via configuration.nix, other module sources). 35, baseOptionsJSON ? null 36# instead of printing warnings for eg options with missing descriptions (which may be lost 37# by nix build unless -L is given), emit errors instead and fail the build 38, warningsAreErrors ? true 39# allow docbook option docs if `true`. only markdown documentation is allowed when set to 40# `false`, and a different renderer may be used with different bugs and performance 41# characteristics but (hopefully) indistinguishable output. 42, allowDocBook ? true 43# whether lib.mdDoc is required for descriptions to be read as markdown. 44# !!! when this is eventually flipped to true, `lib.doRename` should also default to emitting Markdown 45, markdownByDefault ? false 46}: 47 48let 49 rawOpts = lib.optionAttrSetToDocList options; 50 transformedOpts = map transformOptions rawOpts; 51 filteredOpts = lib.filter (opt: opt.visible && !opt.internal) transformedOpts; 52 optionsList = lib.flip map filteredOpts 53 (opt: opt 54 // lib.optionalAttrs (opt ? relatedPackages && opt.relatedPackages != []) { relatedPackages = genRelatedPackages opt.relatedPackages opt.name; } 55 ); 56 57 # Generate DocBook documentation for a list of packages. This is 58 # what `relatedPackages` option of `mkOption` from 59 # ../../../lib/options.nix influences. 60 # 61 # Each element of `relatedPackages` can be either 62 # - a string: that will be interpreted as an attribute name from `pkgs` and turned into a link 63 # to search.nixos.org, 64 # - a list: that will be interpreted as an attribute path from `pkgs` and turned into a link 65 # to search.nixos.org, 66 # - an attrset: that can specify `name`, `path`, `comment` 67 # (either of `name`, `path` is required, the rest are optional). 68 # 69 # NOTE: No checks against `pkgs` are made to ensure that the referenced package actually exists. 70 # Such checks are not compatible with option docs caching. 71 genRelatedPackages = packages: optName: 72 let 73 unpack = p: if lib.isString p then { name = p; } 74 else if lib.isList p then { path = p; } 75 else p; 76 describe = args: 77 let 78 title = args.title or null; 79 name = args.name or (lib.concatStringsSep "." args.path); 80 in '' 81 - [${lib.optionalString (title != null) "${title} aka "}`pkgs.${name}`]( 82 https://search.nixos.org/packages?show=${name}&sort=relevance&query=${name} 83 )${ 84 lib.optionalString (args ? comment) "\n\n ${args.comment}" 85 } 86 ''; 87 in lib.concatMapStrings (p: describe (unpack p)) packages; 88 89 optionsNix = builtins.listToAttrs (map (o: { name = o.name; value = removeAttrs o ["name" "visible" "internal"]; }) optionsList); 90 91in rec { 92 inherit optionsNix; 93 94 optionsAsciiDoc = pkgs.runCommand "options.adoc" { 95 nativeBuildInputs = [ pkgs.nixos-render-docs ]; 96 } '' 97 nixos-render-docs -j $NIX_BUILD_CORES options asciidoc \ 98 --manpage-urls ${pkgs.path + "/doc/manpage-urls.json"} \ 99 --revision ${lib.escapeShellArg revision} \ 100 ${optionsJSON}/share/doc/nixos/options.json \ 101 $out 102 ''; 103 104 optionsCommonMark = pkgs.runCommand "options.md" { 105 nativeBuildInputs = [ pkgs.nixos-render-docs ]; 106 } '' 107 nixos-render-docs -j $NIX_BUILD_CORES options commonmark \ 108 --manpage-urls ${pkgs.path + "/doc/manpage-urls.json"} \ 109 --revision ${lib.escapeShellArg revision} \ 110 ${optionsJSON}/share/doc/nixos/options.json \ 111 $out 112 ''; 113 114 optionsJSON = pkgs.runCommand "options.json" 115 { meta.description = "List of NixOS options in JSON format"; 116 nativeBuildInputs = [ 117 pkgs.brotli 118 pkgs.python3Minimal 119 ]; 120 options = builtins.toFile "options.json" 121 (builtins.unsafeDiscardStringContext (builtins.toJSON optionsNix)); 122 # merge with an empty set if baseOptionsJSON is null to run markdown 123 # processing on the input options 124 baseJSON = 125 if baseOptionsJSON == null 126 then builtins.toFile "base.json" "{}" 127 else baseOptionsJSON; 128 } 129 '' 130 # Export list of options in different format. 131 dst=$out/share/doc/nixos 132 mkdir -p $dst 133 134 TOUCH_IF_DB=$dst/.used-docbook \ 135 python ${./mergeJSON.py} \ 136 ${lib.optionalString warningsAreErrors "--warnings-are-errors"} \ 137 ${if allowDocBook then "--warn-on-docbook" else "--error-on-docbook"} \ 138 $baseJSON $options \ 139 > $dst/options.json 140 141 brotli -9 < $dst/options.json > $dst/options.json.br 142 143 mkdir -p $out/nix-support 144 echo "file json $dst/options.json" >> $out/nix-support/hydra-build-products 145 echo "file json-br $dst/options.json.br" >> $out/nix-support/hydra-build-products 146 ''; 147 148 optionsUsedDocbook = pkgs.runCommand "options-used-docbook" {} '' 149 if [ -e ${optionsJSON}/share/doc/nixos/.used-docbook ]; then 150 echo 1 151 else 152 echo 0 153 fi >"$out" 154 ''; 155 156 optionsDocBook = pkgs.runCommand "options-docbook.xml" { 157 nativeBuildInputs = [ 158 pkgs.nixos-render-docs 159 ]; 160 } '' 161 nixos-render-docs -j $NIX_BUILD_CORES options docbook \ 162 --manpage-urls ${pkgs.path + "/doc/manpage-urls.json"} \ 163 --revision ${lib.escapeShellArg revision} \ 164 --document-type ${lib.escapeShellArg documentType} \ 165 --varlist-id ${lib.escapeShellArg variablelistId} \ 166 --id-prefix ${lib.escapeShellArg optionIdPrefix} \ 167 ${lib.optionalString markdownByDefault "--markdown-by-default"} \ 168 ${optionsJSON}/share/doc/nixos/options.json \ 169 options.xml 170 171 if grep /nixpkgs/nixos/modules options.xml; then 172 echo "The manual appears to depend on the location of Nixpkgs, which is bad" 173 echo "since this prevents sharing via the NixOS channel. This is typically" 174 echo "caused by an option default that refers to a relative path (see above" 175 echo "for hints about the offending path)." 176 exit 1 177 fi 178 179 ${pkgs.libxslt.bin}/bin/xsltproc \ 180 -o "$out" ${./postprocess-option-descriptions.xsl} options.xml 181 ''; 182}