Loading lib/modules.nix +53 −0 Original line number Diff line number Diff line Loading @@ -1366,6 +1366,58 @@ let ]); }; /** `importApply file arg :: Path -> a -> Module`, where `import file :: a -> Module` `importApply` imports a Nix expression file much like the module system would, after passing an extra positional argument to the function in the file. This function should be used when declaring a module in a file that refers to values from a different scope, such as that in a flake. It solves the problems of alternative solutions: - While `importApply file arg` is _mostly_ equivalent to `import file arg`, the latter returns a module without a location, as `import` only returns the contained expression. This leads to worse error messages. - Using `specialArgs` to provide arguments to all modules. This effectively creates an incomplete module, and requires the user of the module to manually pass the `specialArgs` to the configuration, which is error-prone, verbose, and unnecessary. The nix file must contain a function that returns a module. A module may itself be a function, so the file is often a function with two positional arguments instead of one. See the example below. This function does not add support for deduplication and `disabledModules`, although that could be achieved by wrapping the returned module and setting the `_key` module attribute. The reason for this omission is that the file path is not guaranteed to be a unique identifier for the module, as two instances of the module may reference different `arg`s in their closures. Example # lib.nix imports = [ (lib.modules.importApply ./module.nix { bar = bar; }) ]; # module.nix { bar }: { lib, config, ... }: { options = ...; config = ... bar ...; } */ importApply = modulePath: staticArg: lib.setDefaultModuleLocation modulePath (import modulePath staticArg); /* Use this function to import a JSON file as NixOS configuration. modules.importJSON :: path -> attrs Loading Loading @@ -1415,6 +1467,7 @@ private // filterOverrides' fixMergeModules fixupOptionType # should be private? importApply importJSON importTOML mergeDefinitions Loading lib/tests/modules.sh +8 −0 Original line number Diff line number Diff line Loading @@ -247,6 +247,14 @@ checkConfigOutput '^true$' "$@" ./define-enable.nix ./define-attrsOfSub-if-foo-e checkConfigOutput '^true$' "$@" ./define-enable.nix ./define-attrsOfSub-foo-if-enable.nix checkConfigOutput '^true$' "$@" ./define-enable.nix ./define-attrsOfSub-foo-enable-if.nix # Check importApply checkConfigOutput '"abc"' config.value ./importApply.nix # importApply does not set a key. # Disabling the function file is not sufficient, because importApply can't reasonably assume that the key is unique. # e.g. user may call it multiple times with different arguments and expect each of the module to apply. # While this is excusable for the disabledModules aspect, it is not for the deduplication of modules. checkConfigOutput '"abc"' config.value ./importApply-disabling.nix # Check disabledModules with config definitions and option declarations. set -- config.enable ./define-enable.nix ./declare-enable.nix checkConfigOutput '^true$' "$@" Loading lib/tests/modules/importApply-disabling.nix 0 → 100644 +4 −0 Original line number Diff line number Diff line { imports = [ ./importApply.nix ]; disabledModules = [ ./importApply-function.nix ]; } lib/tests/modules/importApply-function.nix 0 → 100644 +5 −0 Original line number Diff line number Diff line { foo }: { lib, config, ... }: { value = foo; } lib/tests/modules/importApply.nix 0 → 100644 +5 −0 Original line number Diff line number Diff line { lib, ... }: { options.value = lib.mkOption { default = 1; }; imports = [ (lib.modules.importApply ./importApply-function.nix { foo = "abc"; }) ]; } Loading
lib/modules.nix +53 −0 Original line number Diff line number Diff line Loading @@ -1366,6 +1366,58 @@ let ]); }; /** `importApply file arg :: Path -> a -> Module`, where `import file :: a -> Module` `importApply` imports a Nix expression file much like the module system would, after passing an extra positional argument to the function in the file. This function should be used when declaring a module in a file that refers to values from a different scope, such as that in a flake. It solves the problems of alternative solutions: - While `importApply file arg` is _mostly_ equivalent to `import file arg`, the latter returns a module without a location, as `import` only returns the contained expression. This leads to worse error messages. - Using `specialArgs` to provide arguments to all modules. This effectively creates an incomplete module, and requires the user of the module to manually pass the `specialArgs` to the configuration, which is error-prone, verbose, and unnecessary. The nix file must contain a function that returns a module. A module may itself be a function, so the file is often a function with two positional arguments instead of one. See the example below. This function does not add support for deduplication and `disabledModules`, although that could be achieved by wrapping the returned module and setting the `_key` module attribute. The reason for this omission is that the file path is not guaranteed to be a unique identifier for the module, as two instances of the module may reference different `arg`s in their closures. Example # lib.nix imports = [ (lib.modules.importApply ./module.nix { bar = bar; }) ]; # module.nix { bar }: { lib, config, ... }: { options = ...; config = ... bar ...; } */ importApply = modulePath: staticArg: lib.setDefaultModuleLocation modulePath (import modulePath staticArg); /* Use this function to import a JSON file as NixOS configuration. modules.importJSON :: path -> attrs Loading Loading @@ -1415,6 +1467,7 @@ private // filterOverrides' fixMergeModules fixupOptionType # should be private? importApply importJSON importTOML mergeDefinitions Loading
lib/tests/modules.sh +8 −0 Original line number Diff line number Diff line Loading @@ -247,6 +247,14 @@ checkConfigOutput '^true$' "$@" ./define-enable.nix ./define-attrsOfSub-if-foo-e checkConfigOutput '^true$' "$@" ./define-enable.nix ./define-attrsOfSub-foo-if-enable.nix checkConfigOutput '^true$' "$@" ./define-enable.nix ./define-attrsOfSub-foo-enable-if.nix # Check importApply checkConfigOutput '"abc"' config.value ./importApply.nix # importApply does not set a key. # Disabling the function file is not sufficient, because importApply can't reasonably assume that the key is unique. # e.g. user may call it multiple times with different arguments and expect each of the module to apply. # While this is excusable for the disabledModules aspect, it is not for the deduplication of modules. checkConfigOutput '"abc"' config.value ./importApply-disabling.nix # Check disabledModules with config definitions and option declarations. set -- config.enable ./define-enable.nix ./declare-enable.nix checkConfigOutput '^true$' "$@" Loading
lib/tests/modules/importApply-disabling.nix 0 → 100644 +4 −0 Original line number Diff line number Diff line { imports = [ ./importApply.nix ]; disabledModules = [ ./importApply-function.nix ]; }
lib/tests/modules/importApply-function.nix 0 → 100644 +5 −0 Original line number Diff line number Diff line { foo }: { lib, config, ... }: { value = foo; }
lib/tests/modules/importApply.nix 0 → 100644 +5 −0 Original line number Diff line number Diff line { lib, ... }: { options.value = lib.mkOption { default = 1; }; imports = [ (lib.modules.importApply ./importApply-function.nix { foo = "abc"; }) ]; }