at 25.11-pre 7.9 kB view raw
1# Tests: ./tests.nix 2 3/** 4 Generates documentation for [nix modules](https://nix.dev/tutorials/module-system/index.html). 5 6 It uses the declared `options` to generate documentation in various formats. 7 8 # Outputs 9 10 This function returns an attribute set with the following entries. 11 12 ## optionsCommonMark 13 14 Documentation in CommonMark text format. 15 16 ## optionsJSON 17 18 All options in a JSON format suitable for further automated processing. 19 20 `example.json` 21 ```json 22 { 23 ... 24 "fileSystems.<name>.options": { 25 "declarations": ["nixos/modules/tasks/filesystems.nix"], 26 "default": { 27 "_type": "literalExpression", 28 "text": "[\n \"defaults\"\n]" 29 }, 30 "description": "Options used to mount the file system.", 31 "example": { 32 "_type": "literalExpression", 33 "text": "[\n \"data=journal\"\n]" 34 }, 35 "loc": ["fileSystems", "<name>", "options"], 36 "readOnly": false, 37 "type": "non-empty (list of string (with check: non-empty))" 38 "relatedPackages": "- [`pkgs.tmux`](\n https://search.nixos.org/packages?show=tmux&sort=relevance&query=tmux\n )\n", 39 }, 40 ... 41 } 42 ``` 43 44 ## optionsAsciiDoc 45 46 Documentation rendered as AsciiDoc. This is useful for e.g. man pages. 47 48 > Note: NixOS itself uses this ouput to to build the configuration.nix man page" 49 50 ## optionsNix 51 52 All options as a Nix attribute set value, with the same schema as `optionsJSON`. 53 54 # Example 55 56 ## Example: NixOS configuration 57 58 ```nix 59 let 60 # Evaluate a NixOS configuration 61 eval = import (pkgs.path + "/nixos/lib/eval-config.nix") { 62 # Overriden explicitly here, this would include all modules from NixOS otherwise. 63 # See: docs of eval-config.nix for more details 64 baseModules = []; 65 modules = [ 66 ./module.nix 67 ]; 68 }; 69 in 70 pkgs.nixosOptionsDoc { 71 inherit (eval) options; 72 } 73 ``` 74 75 ## Example: non-NixOS modules 76 77 `nixosOptionsDoc` can also be used to build documentation for non-NixOS modules. 78 79 ```nix 80 let 81 eval = lib.evalModules { 82 modules = [ 83 ./module.nix 84 ]; 85 }; 86 in 87 pkgs.nixosOptionsDoc { 88 inherit (eval) options; 89 } 90 ``` 91*/ 92{ 93 pkgs, 94 lib, 95 options, 96 transformOptions ? lib.id, # function for additional transformations of the options 97 documentType ? "appendix", 98 # TODO deprecate "appendix" in favor of "none" 99 # and/or rename function to moduleOptionDoc for clean slate 100 101 # If you include more than one option list into a document, you need to 102 # provide different ids. 103 variablelistId ? "configuration-variable-list", 104 # String to prefix to the option XML/HTML id attributes. 105 optionIdPrefix ? "opt-", 106 revision ? "", # Specify revision for the options 107 # a set of options the docs we are generating will be merged into, as if by recursiveUpdate. 108 # used to split the options doc build into a static part (nixos/modules) and a dynamic part 109 # (non-nixos modules imported via configuration.nix, other module sources). 110 baseOptionsJSON ? null, 111 # instead of printing warnings for eg options with missing descriptions (which may be lost 112 # by nix build unless -L is given), emit errors instead and fail the build 113 warningsAreErrors ? true, 114}: 115 116let 117 rawOpts = lib.optionAttrSetToDocList options; 118 transformedOpts = map transformOptions rawOpts; 119 filteredOpts = lib.filter (opt: opt.visible && !opt.internal) transformedOpts; 120 optionsList = lib.flip map filteredOpts ( 121 opt: 122 opt 123 // lib.optionalAttrs (opt ? relatedPackages && opt.relatedPackages != [ ]) { 124 relatedPackages = genRelatedPackages opt.relatedPackages opt.name; 125 } 126 ); 127 128 # Generate DocBook documentation for a list of packages. This is 129 # what `relatedPackages` option of `mkOption` from 130 # ../../../lib/options.nix influences. 131 # 132 # Each element of `relatedPackages` can be either 133 # - a string: that will be interpreted as an attribute name from `pkgs` and turned into a link 134 # to search.nixos.org, 135 # - a list: that will be interpreted as an attribute path from `pkgs` and turned into a link 136 # to search.nixos.org, 137 # - an attrset: that can specify `name`, `path`, `comment` 138 # (either of `name`, `path` is required, the rest are optional). 139 # 140 # NOTE: No checks against `pkgs` are made to ensure that the referenced package actually exists. 141 # Such checks are not compatible with option docs caching. 142 genRelatedPackages = 143 packages: optName: 144 let 145 unpack = 146 p: 147 if lib.isString p then 148 { name = p; } 149 else if lib.isList p then 150 { path = p; } 151 else 152 p; 153 describe = 154 args: 155 let 156 title = args.title or null; 157 name = args.name or (lib.concatStringsSep "." args.path); 158 in 159 '' 160 - [${lib.optionalString (title != null) "${title} aka "}`pkgs.${name}`]( 161 https://search.nixos.org/packages?show=${name}&sort=relevance&query=${name} 162 )${lib.optionalString (args ? comment) "\n\n ${args.comment}"} 163 ''; 164 in 165 lib.concatMapStrings (p: describe (unpack p)) packages; 166 167 optionsNix = builtins.listToAttrs ( 168 map (o: { 169 name = o.name; 170 value = removeAttrs o [ 171 "name" 172 "visible" 173 "internal" 174 ]; 175 }) optionsList 176 ); 177 178in 179rec { 180 inherit optionsNix; 181 182 optionsAsciiDoc = 183 pkgs.runCommand "options.adoc" 184 { 185 nativeBuildInputs = [ pkgs.nixos-render-docs ]; 186 } 187 '' 188 nixos-render-docs -j $NIX_BUILD_CORES options asciidoc \ 189 --manpage-urls ${pkgs.path + "/doc/manpage-urls.json"} \ 190 --revision ${lib.escapeShellArg revision} \ 191 ${optionsJSON}/share/doc/nixos/options.json \ 192 $out 193 ''; 194 195 optionsCommonMark = 196 pkgs.runCommand "options.md" 197 { 198 __structuredAttrs = true; 199 nativeBuildInputs = [ pkgs.nixos-render-docs ]; 200 # For overriding 201 extraArgs = [ ]; 202 } 203 '' 204 nixos-render-docs -j $NIX_BUILD_CORES options commonmark \ 205 --manpage-urls ${pkgs.path + "/doc/manpage-urls.json"} \ 206 --revision ${lib.escapeShellArg revision} \ 207 ''${extraArgs[@]} \ 208 ${optionsJSON}/share/doc/nixos/options.json \ 209 $out 210 ''; 211 212 optionsJSON = 213 pkgs.runCommand "options.json" 214 { 215 meta.description = "List of NixOS options in JSON format"; 216 nativeBuildInputs = [ 217 pkgs.brotli 218 pkgs.python3 219 ]; 220 options = builtins.toFile "options.json" ( 221 builtins.unsafeDiscardStringContext (builtins.toJSON optionsNix) 222 ); 223 # merge with an empty set if baseOptionsJSON is null to run markdown 224 # processing on the input options 225 baseJSON = if baseOptionsJSON == null then builtins.toFile "base.json" "{}" else baseOptionsJSON; 226 } 227 '' 228 # Export list of options in different format. 229 dst=$out/share/doc/nixos 230 mkdir -p $dst 231 232 TOUCH_IF_DB=$dst/.used-docbook \ 233 python ${./mergeJSON.py} \ 234 ${lib.optionalString warningsAreErrors "--warnings-are-errors"} \ 235 $baseJSON $options \ 236 > $dst/options.json 237 238 if grep /nixpkgs/nixos/modules $dst/options.json; then 239 echo "The manual appears to depend on the location of Nixpkgs, which is bad" 240 echo "since this prevents sharing via the NixOS channel. This is typically" 241 echo "caused by an option default that refers to a relative path (see above" 242 echo "for hints about the offending path)." 243 exit 1 244 fi 245 246 brotli -9 < $dst/options.json > $dst/options.json.br 247 248 mkdir -p $out/nix-support 249 echo "file json $dst/options.json" >> $out/nix-support/hydra-build-products 250 echo "file json-br $dst/options.json.br" >> $out/nix-support/hydra-build-products 251 ''; 252}