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():