python3Packages.orjson: Disable failing tests on 32 bit
[NixPkgs.git] / nixos / modules / misc / documentation.nix
blobaa6e40f43705e06694ad6cc0ca9ba3884fb20b7e
1 { config, options, lib, pkgs, utils, modules, baseModules, extraModules, modulesPath, specialArgs, ... }:
3 with lib;
5 let
7   cfg = config.documentation;
8   allOpts = options;
10   canCacheDocs = m:
11     let
12       f = import m;
13       instance = f (mapAttrs (n: _: abort "evaluating ${n} for `meta` failed") (functionArgs f));
14     in
15       cfg.nixos.options.splitBuild
16         && builtins.isPath m
17         && isFunction f
18         && instance ? options
19         && instance.meta.buildDocsInSandbox or true;
21   docModules =
22     let
23       p = partition canCacheDocs (baseModules ++ cfg.nixos.extraModules);
24     in
25       {
26         lazy = p.right;
27         eager = p.wrong ++ optionals cfg.nixos.includeAllModules (extraModules ++ modules);
28       };
30   manual = import ../../doc/manual rec {
31     inherit pkgs config;
32     version = config.system.nixos.release;
33     revision = "release-${version}";
34     extraSources = cfg.nixos.extraModuleSources;
35     options =
36       let
37         scrubbedEval = evalModules {
38           modules = [ {
39             _module.check = false;
40           } ] ++ docModules.eager;
41           specialArgs = specialArgs // {
42             pkgs = scrubDerivations "pkgs" pkgs;
43             # allow access to arbitrary options for eager modules, eg for getting
44             # option types from lazy modules
45             options = allOpts;
46             inherit modulesPath utils;
47           };
48         };
49         scrubDerivations = namePrefix: pkgSet: mapAttrs
50           (name: value:
51             let wholeName = "${namePrefix}.${name}"; in
52             if isAttrs value then
53               scrubDerivations wholeName value
54               // (optionalAttrs (isDerivation value) { outPath = "\${${wholeName}}"; })
55             else value
56           )
57           pkgSet;
58       in scrubbedEval.options;
60     baseOptionsJSON =
61       let
62         filter =
63           builtins.filterSource
64             (n: t:
65               cleanSourceFilter n t
66               && (t == "directory" -> baseNameOf n != "tests")
67               && (t == "file" -> hasSuffix ".nix" n)
68             );
69       in
70         pkgs.runCommand "lazy-options.json" {
71           libPath = filter (pkgs.path + "/lib");
72           pkgsLibPath = filter (pkgs.path + "/pkgs/pkgs-lib");
73           nixosPath = filter (pkgs.path + "/nixos");
74           modules = map (p: ''"${removePrefix "${modulesPath}/" (toString p)}"'') docModules.lazy;
75         } ''
76           export NIX_STORE_DIR=$TMPDIR/store
77           export NIX_STATE_DIR=$TMPDIR/state
78           ${pkgs.buildPackages.nix}/bin/nix-instantiate \
79             --show-trace \
80             --eval --json --strict \
81             --argstr libPath "$libPath" \
82             --argstr pkgsLibPath "$pkgsLibPath" \
83             --argstr nixosPath "$nixosPath" \
84             --arg modules "[ $modules ]" \
85             --argstr stateVersion "${options.system.stateVersion.default}" \
86             --argstr release "${config.system.nixos.release}" \
87             $nixosPath/lib/eval-cacheable-options.nix > $out \
88             || {
89               echo -en "\e[1;31m"
90               echo 'Cacheable portion of option doc build failed.'
91               echo 'Usually this means that an option attribute that ends up in documentation (eg' \
92                 '`default` or `description`) depends on the restricted module arguments' \
93                 '`config` or `pkgs`.'
94               echo
95               echo 'Rebuild your configuration with `--show-trace` to find the offending' \
96                 'location. Remove the references to restricted arguments (eg by escaping' \
97                 'their antiquotations or adding a `defaultText`) or disable the sandboxed' \
98                 'build for the failing module by setting `meta.buildDocsInSandbox = false`.'
99               echo -en "\e[0m"
100               exit 1
101             } >&2
102         '';
104     inherit (cfg.nixos.options) warningsAreErrors allowDocBook;
105   };
108   nixos-help = let
109     helpScript = pkgs.writeShellScriptBin "nixos-help" ''
110       # Finds first executable browser in a colon-separated list.
111       # (see how xdg-open defines BROWSER)
112       browser="$(
113         IFS=: ; for b in $BROWSER; do
114           [ -n "$(type -P "$b" || true)" ] && echo "$b" && break
115         done
116       )"
117       if [ -z "$browser" ]; then
118         browser="$(type -P xdg-open || true)"
119         if [ -z "$browser" ]; then
120           browser="${pkgs.w3m-nographics}/bin/w3m"
121         fi
122       fi
123       exec "$browser" ${manual.manualHTMLIndex}
124     '';
126     desktopItem = pkgs.makeDesktopItem {
127       name = "nixos-manual";
128       desktopName = "NixOS Manual";
129       genericName = "View NixOS documentation in a web browser";
130       icon = "nix-snowflake";
131       exec = "nixos-help";
132       categories = ["System"];
133     };
135     in pkgs.symlinkJoin {
136       name = "nixos-help";
137       paths = [
138         helpScript
139         desktopItem
140       ];
141     };
146   imports = [
147     ./man-db.nix
148     ./mandoc.nix
149     ./assertions.nix
150     ./meta.nix
151     ../config/system-path.nix
152     ../system/etc/etc.nix
153     (mkRenamedOptionModule [ "programs" "info" "enable" ] [ "documentation" "info" "enable" ])
154     (mkRenamedOptionModule [ "programs" "man"  "enable" ] [ "documentation" "man"  "enable" ])
155     (mkRenamedOptionModule [ "services" "nixosManual" "enable" ] [ "documentation" "nixos" "enable" ])
156   ];
158   options = {
160     documentation = {
162       enable = mkOption {
163         type = types.bool;
164         default = true;
165         description = lib.mdDoc ''
166           Whether to install documentation of packages from
167           {option}`environment.systemPackages` into the generated system path.
169           See "Multiple-output packages" chapter in the nixpkgs manual for more info.
170         '';
171         # which is at ../../../doc/multiple-output.chapter.md
172       };
174       man.enable = mkOption {
175         type = types.bool;
176         default = true;
177         description = lib.mdDoc ''
178           Whether to install manual pages.
179           This also includes `man` outputs.
180         '';
181       };
183       man.generateCaches = mkOption {
184         type = types.bool;
185         default = false;
186         description = mdDoc ''
187           Whether to generate the manual page index caches.
188           This allows searching for a page or
189           keyword using utilities like {manpage}`apropos(1)`
190           and the `-k` option of
191           {manpage}`man(1)`.
192         '';
193       };
195       info.enable = mkOption {
196         type = types.bool;
197         default = true;
198         description = lib.mdDoc ''
199           Whether to install info pages and the {command}`info` command.
200           This also includes "info" outputs.
201         '';
202       };
204       doc.enable = mkOption {
205         type = types.bool;
206         default = true;
207         description = lib.mdDoc ''
208           Whether to install documentation distributed in packages' `/share/doc`.
209           Usually plain text and/or HTML.
210           This also includes "doc" outputs.
211         '';
212       };
214       dev.enable = mkOption {
215         type = types.bool;
216         default = false;
217         description = mdDoc ''
218           Whether to install documentation targeted at developers.
219           * This includes man pages targeted at developers if {option}`documentation.man.enable` is
220             set (this also includes "devman" outputs).
221           * This includes info pages targeted at developers if {option}`documentation.info.enable`
222             is set (this also includes "devinfo" outputs).
223           * This includes other pages targeted at developers if {option}`documentation.doc.enable`
224             is set (this also includes "devdoc" outputs).
225         '';
226       };
228       nixos.enable = mkOption {
229         type = types.bool;
230         default = true;
231         description = lib.mdDoc ''
232           Whether to install NixOS's own documentation.
234           - This includes man pages like
235             {manpage}`configuration.nix(5)` if {option}`documentation.man.enable` is
236             set.
237           - This includes the HTML manual and the {command}`nixos-help` command if
238             {option}`documentation.doc.enable` is set.
239         '';
240       };
242       nixos.extraModules = mkOption {
243         type = types.listOf types.raw;
244         default = [];
245         description = lib.mdDoc ''
246           Modules for which to show options even when not imported.
247         '';
248       };
250       nixos.options.splitBuild = mkOption {
251         type = types.bool;
252         default = true;
253         description = lib.mdDoc ''
254           Whether to split the option docs build into a cacheable and an uncacheable part.
255           Splitting the build can substantially decrease the amount of time needed to build
256           the manual, but some user modules may be incompatible with this splitting.
257         '';
258       };
260       nixos.options.allowDocBook = mkOption {
261         type = types.bool;
262         default = true;
263         description = lib.mdDoc ''
264           Whether to allow DocBook option docs. When set to `false` all option using
265           DocBook documentation will cause a manual build error; additionally a new
266           renderer may be used.
268           ::: {.note}
269           The `false` setting for this option is not yet fully supported. While it
270           should work fine and produce the same output as the previous toolchain
271           using DocBook it may not work in all circumstances. Whether markdown option
272           documentation is allowed is independent of this option.
273           :::
274         '';
275       };
277       nixos.options.warningsAreErrors = mkOption {
278         type = types.bool;
279         default = true;
280         description = lib.mdDoc ''
281           Treat warning emitted during the option documentation build (eg for missing option
282           descriptions) as errors.
283         '';
284       };
286       nixos.includeAllModules = mkOption {
287         type = types.bool;
288         default = false;
289         description = lib.mdDoc ''
290           Whether the generated NixOS's documentation should include documentation for all
291           the options from all the NixOS modules included in the current
292           `configuration.nix`. Disabling this will make the manual
293           generator to ignore options defined outside of `baseModules`.
294         '';
295       };
297       nixos.extraModuleSources = mkOption {
298         type = types.listOf (types.either types.path types.str);
299         default = [ ];
300         description = lib.mdDoc ''
301           Which extra NixOS module paths the generated NixOS's documentation should strip
302           from options.
303         '';
304         example = literalExpression ''
305           # e.g. with options from modules in ''${pkgs.customModules}/nix:
306           [ pkgs.customModules ]
307         '';
308       };
310     };
312   };
314   config = mkIf cfg.enable (mkMerge [
315     {
316       assertions = [
317         {
318           assertion = !(cfg.man.man-db.enable && cfg.man.mandoc.enable);
319           message = ''
320             man-db and mandoc can't be used as the default man page viewer at the same time!
321           '';
322         }
323       ];
324     }
326     # The actual implementation for this lives in man-db.nix or mandoc.nix,
327     # depending on which backend is active.
328     (mkIf cfg.man.enable {
329       environment.pathsToLink = [ "/share/man" ];
330       environment.extraOutputsToInstall = [ "man" ] ++ optional cfg.dev.enable "devman";
331     })
333     (mkIf cfg.info.enable {
334       environment.systemPackages = [ pkgs.texinfoInteractive ];
335       environment.pathsToLink = [ "/share/info" ];
336       environment.extraOutputsToInstall = [ "info" ] ++ optional cfg.dev.enable "devinfo";
337       environment.extraSetup = ''
338         if [ -w $out/share/info ]; then
339           shopt -s nullglob
340           for i in $out/share/info/*.info $out/share/info/*.info.gz; do
341               ${pkgs.buildPackages.texinfo}/bin/install-info $i $out/share/info/dir
342           done
343         fi
344       '';
345     })
347     (mkIf cfg.doc.enable {
348       environment.pathsToLink = [ "/share/doc" ];
349       environment.extraOutputsToInstall = [ "doc" ] ++ optional cfg.dev.enable "devdoc";
350     })
352     (mkIf cfg.nixos.enable {
353       system.build.manual = manual;
355       environment.systemPackages = []
356         ++ optional cfg.man.enable manual.manpages
357         ++ optionals cfg.doc.enable [ manual.manualHTML nixos-help ];
358     })
360   ]);