Compare commits

...

4 Commits

Author SHA1 Message Date
Robert Hensing
2513e2f1f0 lib.types.attrNamesTo{Set,Submodule}: add 2025-05-16 15:09:31 +02:00
Robert Hensing
e938d5b77a lib/types.nix: Remove duplicate user documentation 2025-05-16 15:09:25 +02:00
Robert Hensing
1980e9a444 lib/tests/modules: Test attrNamesToTrue 2025-05-16 15:09:24 +02:00
Will Fancher
851d4f4f2b lib.types.attrNamesToTrue: add
(cherry picked from commit 98652f9a90)
2025-05-16 12:35:16 +02:00
4 changed files with 215 additions and 1 deletions

View File

@@ -160,6 +160,9 @@ checkConfigError 'A definition for option .intStrings\.badTagTypeError\.left. is
checkConfigError 'A definition for option .nested\.right\.left. is not of type .signed integer.' config.nested.right.left ./types-attrTag.nix
checkConfigError 'In attrTag, each tag value must be an option, but tag int was a bare type, not wrapped in mkOption.' config.opt.int ./types-attrTag-wrong-decl.nix
# types.nix assertions
checkConfigOutput '"ok"' config.check ./types.nix
# types.pathInStore
checkConfigOutput '".*/store/0lz9p8xhf89kb1c1kk6jxrzskaiygnlh-bash-5.2-p15.drv"' config.pathInStore.ok1 ./types.nix
checkConfigOutput '".*/store/0fb3ykw9r5hpayd05sr0cizwadzq1d8q-bash-5.2-p15"' config.pathInStore.ok2 ./types.nix

View File

@@ -1,4 +1,4 @@
{ lib, ... }:
{ config, lib, ... }:
let
inherit (builtins)
storeDir
@@ -7,10 +7,24 @@ let
types
mkOption
;
m = {
options = {
enableQux = mkOption {
type = types.bool;
default = false;
};
};
};
in
{
options = {
check = mkOption { };
# 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";
@@ -21,5 +35,112 @@ in
pathInStore.bad3 = "${storeDir}/";
pathInStore.bad4 = "${storeDir}/.links"; # technically true, but not reasonable
pathInStore.bad5 = "/foo/bar";
attrNamesToTrue.justNames = [
"a"
"b"
"c"
];
attrNamesToTrue.mixed = lib.mkMerge [
{
a = true;
b = false;
}
[ "c" ]
];
attrNamesToTrue.trivial = {
a = true;
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 == {
a = true;
b = true;
c = true;
};
assert
config.attrNamesToTrue.mixed == {
a = true;
b = false;
c = true;
};
assert
config.attrNamesToTrue.trivial == {
a = true;
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";
};
}

View File

@@ -1456,6 +1456,23 @@ let
nestedTypes.finalType = finalType;
};
# Tests: 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
attrNamesToTrue = coercedTo (types.listOf types.str) (
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; };

View File

@@ -135,6 +135,79 @@ merging is handled.
problems.
:::
`types.attrNamesToTrue`
: Either a list of attribute names, or an attribute set of
booleans. A list will be coerced into an attribute set with those
names, whose values are set to `true`. This is useful when it is
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`
```
{
foo = [ "bar" ];
}
```
```
{
foo.bar = true;
}
```
:::
`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.