nixos docs: allow displaying package references

This is an improved version of original #12357.
For the purpose of generating docs, evaluate options with each derivation
in `pkgs` (recursively) replaced by a fake with path "\${pkgs.attribute.path}".
It isn't perfect, but it seems to cover a vast majority of use cases.
Caveat: even if the package is reached by a different means,
the path above will be shown and not e.g. `${config.services.foo.package}`.

As before, defaults created by `mkDefault` aren't displayed,
but documentation shouldn't (mostly) be a reason to use that anymore.

Note: t wouldn't be enough to just use `lib.mapAttrsRecursive`,
because derivations are also (special) attribute sets.

Changed files
+22 -6
nixos
modules
services
+22 -6
nixos/modules/services/misc/nixos-manual.nix
···
nixpkgs.system = config.nixpkgs.system;
};
-
eval = evalModules {
-
modules = [ versionModule ] ++ baseModules;
-
args = (config._module.args) // { modules = [ ]; };
-
};
-
manual = import ../../../doc/manual {
inherit pkgs;
version = config.system.nixosVersion;
revision = config.system.nixosRevision;
-
options = eval.options;
};
entry = "${manual.manual}/share/doc/nixos/index.html";
···
nixpkgs.system = config.nixpkgs.system;
};
+
/* For the purpose of generating docs, evaluate options with each derivation
+
in `pkgs` (recursively) replaced by a fake with path "\${pkgs.attribute.path}".
+
It isn't perfect, but it seems to cover a vast majority of use cases.
+
Caveat: even if the package is reached by a different means,
+
the path above will be shown and not e.g. `${config.services.foo.package}`. */
manual = import ../../../doc/manual {
inherit pkgs;
version = config.system.nixosVersion;
revision = config.system.nixosRevision;
+
options =
+
let
+
scrubbedEval = evalModules {
+
modules = [ versionModule ] ++ baseModules;
+
args = (config._module.args) // { modules = [ ]; };
+
specialArgs = { pkgs = scrubDerivations "pkgs" pkgs; };
+
};
+
scrubDerivations = namePrefix: pkgSet: mapAttrs
+
(name: value:
+
let wholeName = "${namePrefix}.${name}"; in
+
if isAttrs value then
+
scrubDerivations wholeName value
+
// (optionalAttrs (isDerivation value) { outPath = "\${${wholeName}}"; })
+
else value
+
)
+
pkgSet;
+
in scrubbedEval.options;
};
entry = "${manual.manual}/share/doc/nixos/index.html";