at master 7.8 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 output 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 modules = [ 63 ./module.nix 64 ]; 65 }; 66 in 67 pkgs.nixosOptionsDoc { 68 inherit (eval) options; 69 } 70 ``` 71 72 ## Example: non-NixOS modules 73 74 `nixosOptionsDoc` can also be used to build documentation for non-NixOS modules. 75 76 ```nix 77 let 78 eval = lib.evalModules { 79 modules = [ 80 ./module.nix 81 ]; 82 }; 83 in 84 pkgs.nixosOptionsDoc { 85 inherit (eval) options; 86 } 87 ``` 88*/ 89{ 90 pkgs, 91 lib, 92 options, 93 transformOptions ? lib.id, # function for additional transformations of the options 94 documentType ? "appendix", 95 # TODO deprecate "appendix" in favor of "none" 96 # and/or rename function to moduleOptionDoc for clean slate 97 98 # If you include more than one option list into a document, you need to 99 # provide different ids. 100 variablelistId ? "configuration-variable-list", 101 # String to prefix to the option XML/HTML id attributes. 102 optionIdPrefix ? "opt-", 103 revision ? "", # Specify revision for the options 104 # a set of options the docs we are generating will be merged into, as if by recursiveUpdate. 105 # used to split the options doc build into a static part (nixos/modules) and a dynamic part 106 # (non-nixos modules imported via configuration.nix, other module sources). 107 baseOptionsJSON ? null, 108 # instead of printing warnings for eg options with missing descriptions (which may be lost 109 # by nix build unless -L is given), emit errors instead and fail the build 110 warningsAreErrors ? true, 111}: 112 113let 114 rawOpts = lib.optionAttrSetToDocList options; 115 transformedOpts = map transformOptions rawOpts; 116 filteredOpts = lib.filter (opt: opt.visible && !opt.internal) transformedOpts; 117 optionsList = lib.flip map filteredOpts ( 118 opt: 119 opt 120 // lib.optionalAttrs (opt ? relatedPackages && opt.relatedPackages != [ ]) { 121 relatedPackages = genRelatedPackages opt.relatedPackages opt.name; 122 } 123 ); 124 125 # Generate DocBook documentation for a list of packages. This is 126 # what `relatedPackages` option of `mkOption` from 127 # ../../../lib/options.nix influences. 128 # 129 # Each element of `relatedPackages` can be either 130 # - a string: that will be interpreted as an attribute name from `pkgs` and turned into a link 131 # to search.nixos.org, 132 # - a list: that will be interpreted as an attribute path from `pkgs` and turned into a link 133 # to search.nixos.org, 134 # - an attrset: that can specify `name`, `path`, `comment` 135 # (either of `name`, `path` is required, the rest are optional). 136 # 137 # NOTE: No checks against `pkgs` are made to ensure that the referenced package actually exists. 138 # Such checks are not compatible with option docs caching. 139 genRelatedPackages = 140 packages: optName: 141 let 142 unpack = 143 p: 144 if lib.isString p then 145 { name = p; } 146 else if lib.isList p then 147 { path = p; } 148 else 149 p; 150 describe = 151 args: 152 let 153 title = args.title or null; 154 name = args.name or (lib.concatStringsSep "." args.path); 155 in 156 '' 157 - [${lib.optionalString (title != null) "${title} aka "}`pkgs.${name}`]( 158 https://search.nixos.org/packages?show=${name}&sort=relevance&query=${name} 159 )${lib.optionalString (args ? comment) "\n\n ${args.comment}"} 160 ''; 161 in 162 lib.concatMapStrings (p: describe (unpack p)) packages; 163 164 optionsNix = builtins.listToAttrs ( 165 map (o: { 166 name = o.name; 167 value = removeAttrs o [ 168 "name" 169 "visible" 170 "internal" 171 ]; 172 }) optionsList 173 ); 174 175in 176rec { 177 inherit optionsNix; 178 179 optionsAsciiDoc = 180 pkgs.runCommand "options.adoc" 181 { 182 nativeBuildInputs = [ pkgs.nixos-render-docs ]; 183 } 184 '' 185 nixos-render-docs -j $NIX_BUILD_CORES options asciidoc \ 186 --manpage-urls ${pkgs.path + "/doc/manpage-urls.json"} \ 187 --revision ${lib.escapeShellArg revision} \ 188 ${optionsJSON}/share/doc/nixos/options.json \ 189 $out 190 ''; 191 192 optionsCommonMark = 193 pkgs.runCommand "options.md" 194 { 195 __structuredAttrs = true; 196 nativeBuildInputs = [ pkgs.nixos-render-docs ]; 197 # For overriding 198 extraArgs = [ ]; 199 } 200 '' 201 nixos-render-docs -j $NIX_BUILD_CORES options commonmark \ 202 --manpage-urls ${pkgs.path + "/doc/manpage-urls.json"} \ 203 --revision ${lib.escapeShellArg revision} \ 204 ''${extraArgs[@]} \ 205 ${optionsJSON}/share/doc/nixos/options.json \ 206 $out 207 ''; 208 209 optionsJSON = 210 pkgs.runCommand "options.json" 211 { 212 meta.description = "List of NixOS options in JSON format"; 213 nativeBuildInputs = [ 214 pkgs.brotli 215 pkgs.python3 216 ]; 217 options = builtins.toFile "options.json" ( 218 builtins.unsafeDiscardStringContext (builtins.toJSON optionsNix) 219 ); 220 # merge with an empty set if baseOptionsJSON is null to run markdown 221 # processing on the input options 222 baseJSON = if baseOptionsJSON == null then builtins.toFile "base.json" "{}" else baseOptionsJSON; 223 } 224 '' 225 # Export list of options in different format. 226 dst=$out/share/doc/nixos 227 mkdir -p $dst 228 229 TOUCH_IF_DB=$dst/.used-docbook \ 230 python ${./mergeJSON.py} \ 231 ${lib.optionalString warningsAreErrors "--warnings-are-errors"} \ 232 $baseJSON $options \ 233 > $dst/options.json 234 235 if grep /nixpkgs/nixos/modules $dst/options.json; then 236 echo "The manual appears to depend on the location of Nixpkgs, which is bad" 237 echo "since this prevents sharing via the NixOS channel. This is typically" 238 echo "caused by an option default that refers to a relative path (see above" 239 echo "for hints about the offending path)." 240 exit 1 241 fi 242 243 brotli -9 < $dst/options.json > $dst/options.json.br 244 245 mkdir -p $out/nix-support 246 echo "file json $dst/options.json" >> $out/nix-support/hydra-build-products 247 echo "file json-br $dst/options.json.br" >> $out/nix-support/hydra-build-products 248 ''; 249}