about summary refs log tree commit diff
path: root/lib
diff options
context:
space:
mode:
authorgithub-actions[bot]2024-08-31 00:13:46 +0000
committerGitHub2024-08-31 00:13:46 +0000
commitfab50d5f8d5d8fee0dd1229b82241f68cc3cd3f8 (patch)
tree707507c77ca6825a6bd4d3cadc8e7a201ea2c83c /lib
parentd8c78f272ca287089e989dbb3c43594b0929d73d (diff)
parentdcad9b571a0324dbc4e9c3b75ff54a58dce09879 (diff)
Merge staging-next into staging
Diffstat (limited to 'lib')
-rw-r--r--lib/modules.nix53
-rwxr-xr-xlib/tests/modules.sh8
-rw-r--r--lib/tests/modules/importApply-disabling.nix4
-rw-r--r--lib/tests/modules/importApply-function.nix5
-rw-r--r--lib/tests/modules/importApply.nix5
5 files changed, 75 insertions, 0 deletions
diff --git a/lib/modules.nix b/lib/modules.nix
index b9e9ca1e5d78..ef0be5b27aaf 100644
--- a/lib/modules.nix
+++ b/lib/modules.nix
@@ -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
@@ -1415,6 +1467,7 @@ private //
     filterOverrides'
     fixMergeModules
     fixupOptionType  # should be private?
+    importApply
     importJSON
     importTOML
     mergeDefinitions
diff --git a/lib/tests/modules.sh b/lib/tests/modules.sh
index 3301a3d987ee..09547b2e0e6c 100755
--- a/lib/tests/modules.sh
+++ b/lib/tests/modules.sh
@@ -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$' "$@"
diff --git a/lib/tests/modules/importApply-disabling.nix b/lib/tests/modules/importApply-disabling.nix
new file mode 100644
index 000000000000..016036dd8af5
--- /dev/null
+++ b/lib/tests/modules/importApply-disabling.nix
@@ -0,0 +1,4 @@
+{
+  imports = [ ./importApply.nix ];
+  disabledModules = [ ./importApply-function.nix ];
+}
diff --git a/lib/tests/modules/importApply-function.nix b/lib/tests/modules/importApply-function.nix
new file mode 100644
index 000000000000..7c193a912d49
--- /dev/null
+++ b/lib/tests/modules/importApply-function.nix
@@ -0,0 +1,5 @@
+{ foo }:
+{ lib, config, ... }:
+{
+  value = foo;
+}
diff --git a/lib/tests/modules/importApply.nix b/lib/tests/modules/importApply.nix
new file mode 100644
index 000000000000..d3b893cb34e2
--- /dev/null
+++ b/lib/tests/modules/importApply.nix
@@ -0,0 +1,5 @@
+{ lib, ... }:
+{
+  options.value = lib.mkOption { default = 1; };
+  imports = [ (lib.modules.importApply ./importApply-function.nix { foo = "abc"; }) ];
+}