summary refs log tree commit diff
path: root/lib
diff options
context:
space:
mode:
authorSilvan Mosberger <contact@infinisil.com>2021-12-08 19:13:14 +0100
committerSilvan Mosberger <contact@infinisil.com>2022-03-01 19:31:02 +0100
commit023fa7b9239e645f7dfcbbe3ee82ab0093f9978d (patch)
treef665c6c625a270eba4d5aa7c4e12c1d60b53e29d /lib
parent5cbeddfde486ca5524baeaf3da6e8944075cf463 (diff)
downloadnixpkgs-023fa7b9239e645f7dfcbbe3ee82ab0093f9978d.tar
nixpkgs-023fa7b9239e645f7dfcbbe3ee82ab0093f9978d.tar.gz
nixpkgs-023fa7b9239e645f7dfcbbe3ee82ab0093f9978d.tar.bz2
nixpkgs-023fa7b9239e645f7dfcbbe3ee82ab0093f9978d.tar.lz
nixpkgs-023fa7b9239e645f7dfcbbe3ee82ab0093f9978d.tar.xz
nixpkgs-023fa7b9239e645f7dfcbbe3ee82ab0093f9978d.tar.zst
nixpkgs-023fa7b9239e645f7dfcbbe3ee82ab0093f9978d.zip
lib.modules: Use types.optionType for _module.freeformType
This ensures that the module file locations are propagated to the
freeform type, which makes it so that submodules in freeform types now
have their declaration location shown in the manual, fixing
https://github.com/NixOS/nixpkgs/issues/132085.

In addition, this also newly allows freeformTypes to be declared
multiple times and all declarations being merged together according to
normal option merging.

This also removes some awkwardness regarding the type of `freeformType`
Diffstat (limited to 'lib')
-rw-r--r--lib/modules.nix3
-rwxr-xr-xlib/tests/modules.sh5
-rw-r--r--lib/tests/modules/freeform-submodules.nix22
3 files changed, 28 insertions, 2 deletions
diff --git a/lib/modules.nix b/lib/modules.nix
index e9fc1007fc2..79d54e4a538 100644
--- a/lib/modules.nix
+++ b/lib/modules.nix
@@ -151,8 +151,7 @@ rec {
           };
 
           _module.freeformType = mkOption {
-            # Disallow merging for now, but could be implemented nicely with a `types.optionType`
-            type = types.nullOr (types.uniq types.attrs);
+            type = types.nullOr types.optionType;
             internal = true;
             default = null;
             description = ''
diff --git a/lib/tests/modules.sh b/lib/tests/modules.sh
index d11f32e5996..e4bb7ad2190 100755
--- a/lib/tests/modules.sh
+++ b/lib/tests/modules.sh
@@ -240,6 +240,11 @@ checkConfigOutput '^"24"$' config.foo ./freeform-attrsOf.nix ./freeform-str-dep-
 checkConfigError 'infinite recursion encountered' config.foo ./freeform-attrsOf.nix ./freeform-unstr-dep-str.nix
 checkConfigError 'The option .* is used but not defined' config.foo ./freeform-lazyAttrsOf.nix ./freeform-unstr-dep-str.nix
 checkConfigOutput '^"24"$' config.foo ./freeform-lazyAttrsOf.nix ./freeform-unstr-dep-str.nix ./define-value-string.nix
+# submodules in freeformTypes should have their locations annotated
+checkConfigOutput '/freeform-submodules.nix"$' config.fooDeclarations.0 ./freeform-submodules.nix
+# freeformTypes can get merged using `types.type`, including submodules
+checkConfigOutput '^10$' config.free.xxx.foo ./freeform-submodules.nix
+checkConfigOutput '^10$' config.free.yyy.bar ./freeform-submodules.nix
 
 ## types.anything
 # Check that attribute sets are merged recursively
diff --git a/lib/tests/modules/freeform-submodules.nix b/lib/tests/modules/freeform-submodules.nix
new file mode 100644
index 00000000000..3910435a7b5
--- /dev/null
+++ b/lib/tests/modules/freeform-submodules.nix
@@ -0,0 +1,22 @@
+{ lib, options, ... }: with lib.types; {
+
+  options.fooDeclarations = lib.mkOption {
+    default = (options.free.type.getSubOptions [])._freeformOptions.foo.declarations;
+  };
+
+  options.free = lib.mkOption {
+    type = submodule {
+      config._module.freeformType = lib.mkMerge [
+        (attrsOf (submodule {
+          options.foo = lib.mkOption {};
+        }))
+        (attrsOf (submodule {
+          options.bar = lib.mkOption {};
+        }))
+      ];
+    };
+  };
+
+  config.free.xxx.foo = 10;
+  config.free.yyy.bar = 10;
+}