diff --git a/lib/modules.nix b/lib/modules.nix
index 9bb8bfbbdf14..011ebb7111f8 100644
--- a/lib/modules.nix
+++ b/lib/modules.nix
@@ -46,6 +46,7 @@ let
showFiles
showOption
unknownModule
+ literalExpression
;
showDeclPrefix = loc: decl: prefix:
@@ -140,7 +141,7 @@ rec {
# this module is used, to avoid conflicts and allow chaining of
# extendModules.
internalModule = rec {
- _file = ./modules.nix;
+ _file = "lib/modules.nix";
key = _file;
@@ -153,8 +154,91 @@ rec {
# a `_module.args.pkgs = import (fetchTarball { ... }) {}` won't
# start a download when `pkgs` wasn't evaluated.
type = types.lazyAttrsOf types.raw;
- internal = true;
- description = "Arguments passed to each module.";
+ # Only render documentation once at the root of the option tree,
+ # not for all individual submodules.
+ internal = prefix != [];
+ # TODO: Change the type of this option to a submodule with a
+ # freeformType, so that individual arguments can be documented
+ # separately
+ description = ''
+ Additional arguments passed to each module in addition to ones
+ like lib, config,
+ and pkgs, modulesPath.
+
+
+ This option is also available to all submodules. Submodules do not
+ inherit args from their parent module, nor do they provide args to
+ their parent module or sibling submodules. The sole exception to
+ this is the argument name which is provided by
+ parent modules to a submodule and contains the attribute name
+ the submodule is bound to, or a unique generated name if it is
+ not bound to an attribute.
+
+
+ Some arguments are already passed by default, of which the
+ following cannot be changed with this option:
+
+
+
+ lib: The nixpkgs library.
+
+
+
+
+ config: The results of all options after merging the values from all modules together.
+
+
+
+
+ options: The options declared in all modules.
+
+
+
+
+ specialArgs: The specialArgs argument passed to evalModules.
+
+
+
+
+ All attributes of specialArgs
+
+
+ Whereas option values can generally depend on other option values
+ thanks to laziness, this does not apply to imports, which
+ must be computed statically before anything else.
+
+
+ For this reason, callers of the module system can provide specialArgs
+ which are available during import resolution.
+
+
+ For NixOS, specialArgs includes
+ modulesPath, which allows you to import
+ extra modules from the nixpkgs package tree without having to
+ somehow make the module aware of the location of the
+ nixpkgs or NixOS directories.
+
+ { modulesPath, ... }: {
+ imports = [
+ (modulesPath + "/profiles/minimal.nix")
+ ];
+ }
+
+
+
+
+
+
+ For NixOS, the default value for this option includes at least this argument:
+
+
+
+ pkgs: The nixpkgs package set according to
+ the option.
+
+
+
+ '';
};
_module.check = mkOption {
diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix
index 271119031395..d283c253f45f 100644
--- a/lib/tests/misc.nix
+++ b/lib/tests/misc.nix
@@ -691,7 +691,7 @@ runTests {
locs = filter (o: ! o.internal) (optionAttrSetToDocList options);
in map (o: o.loc) locs;
- expected = [ [ "foo" ] [ "foo" "" "bar" ] [ "foo" "bar" ] ];
+ expected = [ [ "_module" "args" ] [ "foo" ] [ "foo" "" "bar" ] [ "foo" "bar" ] ];
};
testCartesianProductOfEmptySet = {
diff --git a/nixos/lib/make-options-doc/mergeJSON.py b/nixos/lib/make-options-doc/mergeJSON.py
index 8e2ea322dc89..44a188a08c99 100644
--- a/nixos/lib/make-options-doc/mergeJSON.py
+++ b/nixos/lib/make-options-doc/mergeJSON.py
@@ -48,7 +48,9 @@ overrides = pivot(json.load(open(sys.argv[2 + optOffset], 'r')))
# fix up declaration paths in lazy options, since we don't eval them from a full nixpkgs dir
for (k, v) in options.items():
- v.value['declarations'] = list(map(lambda s: f'nixos/modules/{s}', v.value['declarations']))
+ # The _module options are not declared in nixos/modules
+ if v.value['loc'][0] != "_module":
+ v.value['declarations'] = list(map(lambda s: f'nixos/modules/{s}', v.value['declarations']))
# merge both descriptions
for (k, v) in overrides.items():