summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Hensing <robert@roberthensing.nl>2025-05-16 15:07:58 +0200
committerRobert Hensing <robert@roberthensing.nl>2025-05-16 15:09:31 +0200
commit2513e2f1f0835a0748b90f51620c548bfdd7d70f (patch)
tree0a08a848a115242b021f2ec983b5e22aaf0ec8ae
parentlib/types.nix: Remove duplicate user documentation (diff)
downloadnixpkgs-origin/lib-types-attrNamesToTrue.tar.gz
lib.types.attrNamesTo{Set,Submodule}: addorigin/lib-types-attrNamesToTrue
-rw-r--r--lib/tests/modules/types.nix81
-rw-r--r--lib/types.nix10
-rw-r--r--nixos/doc/manual/development/option-types.section.md50
3 files changed, 141 insertions, 0 deletions
diff --git a/lib/tests/modules/types.nix b/lib/tests/modules/types.nix
index 13c925853b98..8fa15ff8f5b9 100644
--- a/lib/tests/modules/types.nix
+++ b/lib/tests/modules/types.nix
@@ -7,6 +7,15 @@ let
types
mkOption
;
+
+ m = {
+ options = {
+ enableQux = mkOption {
+ type = types.bool;
+ default = false;
+ };
+ };
+ };
in
{
options = {
@@ -14,6 +23,8 @@ in
# NB: types are tested in multiple places, so this list is far from exhaustive
pathInStore = mkOption { type = types.lazyAttrsOf types.pathInStore; };
attrNamesToTrue = mkOption { type = types.lazyAttrsOf types.attrNamesToTrue; };
+ attrNamesToSet = mkOption { type = types.lazyAttrsOf types.attrNamesToSet; };
+ attrNamesToSubmodules = mkOption { type = types.lazyAttrsOf (types.attrNamesToSubmodules m); };
};
config = {
pathInStore.ok1 = "${storeDir}/0lz9p8xhf89kb1c1kk6jxrzskaiygnlh-bash-5.2-p15.drv";
@@ -41,6 +52,40 @@ in
b = false;
c = true;
};
+ attrNamesToSet.justNames = [
+ "a"
+ "b"
+ "c"
+ ];
+ attrNamesToSet.mixed = lib.mkMerge [
+ {
+ a = { };
+ b = { };
+ }
+ [ "c" ]
+ ];
+ attrNamesToSet.trivial = {
+ a = { };
+ b = { };
+ c = { };
+ };
+ attrNamesToSubmodules.justNames = [
+ "a"
+ "b"
+ "c"
+ ];
+ attrNamesToSubmodules.mixed = lib.mkMerge [
+ {
+ a = { };
+ b.enableQux = true;
+ }
+ [ "c" ]
+ ];
+ attrNamesToSubmodules.trivial = {
+ a = { };
+ b.enableQux = true;
+ c = { };
+ };
check =
assert
config.attrNamesToTrue.justNames == {
@@ -60,6 +105,42 @@ in
b = false;
c = true;
};
+ assert
+ config.attrNamesToSet.justNames == {
+ a = { };
+ b = { };
+ c = { };
+ };
+ assert
+ config.attrNamesToSet.mixed == {
+ a = { };
+ b = { };
+ c = { };
+ };
+ assert
+ config.attrNamesToSet.trivial == {
+ a = { };
+ b = { };
+ c = { };
+ };
+ assert
+ config.attrNamesToSubmodules.justNames == {
+ a.enableQux = false;
+ b.enableQux = false;
+ c.enableQux = false;
+ };
+ assert
+ config.attrNamesToSubmodules.mixed == {
+ a.enableQux = false;
+ b.enableQux = true;
+ c.enableQux = false;
+ };
+ assert
+ config.attrNamesToSubmodules.trivial == {
+ a.enableQux = false;
+ b.enableQux = true;
+ c.enableQux = false;
+ };
"ok";
};
}
diff --git a/lib/types.nix b/lib/types.nix
index c0fcf5dae0c7..7b977f439afe 100644
--- a/lib/types.nix
+++ b/lib/types.nix
@@ -1463,6 +1463,16 @@ let
enabledList: lib.genAttrs enabledList (_attrName: true)
) (types.attrsOf types.bool);
+ # Tests: lib/tests/modules.sh, lib/tests/modules/types.nix
+ # Docs: nixos/doc/manual/development/option-types.section.md
+ # Docs: https://nixos.org/manual/nixos/unstable/#sec-option-types-basic
+ attrNamesToSet = attrNamesToSubmodules { };
+ attrNamesToSubmodules =
+ m:
+ coercedTo (types.listOf types.str) (enabledList: lib.genAttrs enabledList (_attrName: { })) (
+ types.attrsOf (types.submodule m)
+ );
+
# Augment the given type with an additional type check function.
addCheck = elemType: check: elemType // { check = x: elemType.check x && check x; };
diff --git a/nixos/doc/manual/development/option-types.section.md b/nixos/doc/manual/development/option-types.section.md
index 8539da71a214..b144095c7153 100644
--- a/nixos/doc/manual/development/option-types.section.md
+++ b/nixos/doc/manual/development/option-types.section.md
@@ -143,6 +143,9 @@ merging is handled.
convenient to be able to write definitions as a simple list, but
still need to be able to override and disable individual values.
+ If configurability of the items is needed or `false` is not a
+ desirable value, prefer `types.attrNamesToSubmodule` or `types.attrNamesToSet`.
+
::: {#ex-types-attrNamesToTrue .example}
### `types.attrNamesToTrue`
```
@@ -158,6 +161,53 @@ merging is handled.
```
:::
+`types.attrNamesToSet`
+
+: Either a list of attribute names, or an attribute set of `{ }`.
+ This is similar to `types.attrNamesToTrue`, but `false` is not a permitted
+ value. This is useful when that's not an expected value, and by using this
+ type, you have the option to upgrade the type to `types.attrNamesToSubmodule`
+ without breaking anything.
+
+ ::: {#ex-types-attrNamesToSet .example}
+ ### `types.attrNamesToSet`
+ ```
+ {
+ foo = [ "bar" ];
+ }
+ ```
+
+ ```
+ {
+ foo.bar = { };
+ }
+ ```
+ :::
+
+`types.attrNamesToSubmodule` *`submodule`*
+
+: Either a list of attribute names, or an attribute set of submodules.
+ This is similar to `types.attrNamesToSet`, but the values are submodules
+ instead of empty sets. This is useful when the values of this type are
+ optionally configurable.
+
+ ::: {#ex-types-attrNamesToSubmodule .example}
+ ### `types.attrNamesToSubmodule`
+ ```
+ {
+ foo = [ "bar" ];
+ }
+ ```
+
+ ```
+ {
+ foo.bar = { };
+ foo.baz.enableQux = true;
+ }
+ ```
+ :::
+
+
`types.pkgs`
: A type for the top level Nixpkgs package set.