lib.importApply: init (#230588)
* lib.modules.importApply: init Brings variables from rich scopes to modules defined in separate files. A helper for functions in files that return a module. * lib.modules.importApply: Edit doc Generally improve the quality. Notes: - Not rendered to the manual yet, so probably the syntax could be improved, but I have no way to test this now. - The docs use `arg` vs `staticArg` in the code. This is intentional, because the doc is pretty clear about the role of `arg` whereas the code exists in a context where ambiguities are more harmful. * Format
This commit is contained in:
parent
ef0bb1fc69
commit
0abfc619bc
@ -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.
|
/* Use this function to import a JSON file as NixOS configuration.
|
||||||
|
|
||||||
modules.importJSON :: path -> attrs
|
modules.importJSON :: path -> attrs
|
||||||
@ -1415,6 +1467,7 @@ private //
|
|||||||
filterOverrides'
|
filterOverrides'
|
||||||
fixMergeModules
|
fixMergeModules
|
||||||
fixupOptionType # should be private?
|
fixupOptionType # should be private?
|
||||||
|
importApply
|
||||||
importJSON
|
importJSON
|
||||||
importTOML
|
importTOML
|
||||||
mergeDefinitions
|
mergeDefinitions
|
||||||
|
@ -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-if-enable.nix
|
||||||
checkConfigOutput '^true$' "$@" ./define-enable.nix ./define-attrsOfSub-foo-enable-if.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.
|
# Check disabledModules with config definitions and option declarations.
|
||||||
set -- config.enable ./define-enable.nix ./declare-enable.nix
|
set -- config.enable ./define-enable.nix ./declare-enable.nix
|
||||||
checkConfigOutput '^true$' "$@"
|
checkConfigOutput '^true$' "$@"
|
||||||
|
4
lib/tests/modules/importApply-disabling.nix
Normal file
4
lib/tests/modules/importApply-disabling.nix
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
imports = [ ./importApply.nix ];
|
||||||
|
disabledModules = [ ./importApply-function.nix ];
|
||||||
|
}
|
5
lib/tests/modules/importApply-function.nix
Normal file
5
lib/tests/modules/importApply-function.nix
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{ foo }:
|
||||||
|
{ lib, config, ... }:
|
||||||
|
{
|
||||||
|
value = foo;
|
||||||
|
}
|
5
lib/tests/modules/importApply.nix
Normal file
5
lib/tests/modules/importApply.nix
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{ lib, ... }:
|
||||||
|
{
|
||||||
|
options.value = lib.mkOption { default = 1; };
|
||||||
|
imports = [ (lib.modules.importApply ./importApply-function.nix { foo = "abc"; }) ];
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user