summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authornixpkgs-ci[bot] <190413589+nixpkgs-ci[bot]@users.noreply.github.com>2026-01-21 00:19:20 +0000
committerGitHub <noreply@github.com>2026-01-21 00:19:20 +0000
commitbf69762f2aecc73eb156d7a201b8cea74bc9c2bd (patch)
tree7395e47805b9f76d7f10a113d99bb89c4aa8e15d /lib
parentpkgsMusl.onnxruntime: fix build (#480773) (diff)
parentgoogle-chrome: 144.0.7559.59 -> 144.0.7559.96 (#482113) (diff)
downloadnixpkgs-bf69762f2aecc73eb156d7a201b8cea74bc9c2bd.tar.gz
Merge master into staging-next
Diffstat (limited to 'lib')
-rwxr-xr-xlib/tests/modules.sh28
-rw-r--r--lib/tests/modules/types.nix32
-rw-r--r--lib/types.nix39
3 files changed, 95 insertions, 4 deletions
diff --git a/lib/tests/modules.sh b/lib/tests/modules.sh
index 8ea8adab72c9..d148cd1839da 100755
--- a/lib/tests/modules.sh
+++ b/lib/tests/modules.sh
@@ -58,12 +58,19 @@ logFailure() {
evalConfig() {
local attr=$1
shift
- local script="import ./default.nix { modules = [ $* ];}"
+
+ local nix_args=()
+
if [ "${ABORT_ON_WARN-0}" = "1" ]; then
- local-nix-instantiate --option abort-on-warn true -E "$script" -A "$attr"
- else
- local-nix-instantiate -E "$script" -A "$attr"
+ nix_args+=(--option abort-on-warn true)
+ fi
+
+ if [ "${STRICT_EVAL-0}" = "1" ]; then
+ nix_args+=(--strict)
fi
+
+ local script="import ./default.nix { modules = [ $* ];}"
+ local-nix-instantiate "${nix_args[@]}" -E "$script" -A "$attr"
}
reportFailure() {
@@ -247,6 +254,19 @@ checkConfigError 'A definition for option .* is not of type .fileset.. Definitio
checkConfigError 'A definition for option .* is not of type .fileset.. Definition values:\n.*' config.filesetCardinal.err3 ./fileset.nix
checkConfigError 'A definition for option .* is not of type .fileset.. Definition values:\n.*' config.filesetCardinal.err4 ./fileset.nix
+# types.serializableValueWith
+checkConfigOutput '^null$' config.nullableValue.null ./types.nix
+checkConfigOutput '^true$' config.nullableValue.bool ./types.nix
+checkConfigOutput '^1$' config.nullableValue.int ./types.nix
+checkConfigOutput '^1.1$' config.nullableValue.float ./types.nix
+checkConfigOutput '^"foo"$' config.nullableValue.str ./types.nix
+checkConfigOutput '^".*/store.*"$' config.nullableValue.path ./types.nix
+STRICT_EVAL=1 checkConfigOutput '^\{"foo":1\}$' config.nullableValue.attrs ./types.nix
+STRICT_EVAL=1 checkConfigOutput '^\[\{"bar":\[1\]\}\]$' config.nullableValue.list ./types.nix
+
+checkConfigError 'A definition for option .* is not of type .VAL value.. .*' config.nullableValue.lambda ./types.nix
+checkConfigError 'A definition for option .* is not of type .VAL value.. .*' config.structuredValue.null ./types.nix
+
# Check boolean option.
checkConfigOutput '^false$' config.enable ./declare-enable.nix
checkConfigError 'The option .* does not exist. Definition values:\n\s*- In .*: true' config.enable ./define-enable.nix
diff --git a/lib/tests/modules/types.nix b/lib/tests/modules/types.nix
index 0a566ea960c4..e12591d27e1f 100644
--- a/lib/tests/modules/types.nix
+++ b/lib/tests/modules/types.nix
@@ -16,6 +16,19 @@ in
options = {
pathInStore = mkOption { type = types.lazyAttrsOf types.pathInStore; };
externalPath = mkOption { type = types.lazyAttrsOf types.externalPath; };
+ # serializableValueWith
+ nullableValue = mkOption {
+ type = types.attrsOf (types.serializableValueWith { typeName = "VAL"; });
+ };
+ structuredValue = mkOption {
+ type = types.attrsOf (
+ types.serializableValueWith {
+ typeName = "VAL";
+ nullable = false;
+ }
+ );
+ };
+
assertions = mkOption { };
};
config = {
@@ -35,6 +48,22 @@ in
externalPath.ok1 = "/foo/bar";
externalPath.ok2 = "/";
+ # serializableValueWith { nullable = true; }
+ nullableValue.null = null; # null
+ nullableValue.bool = true; # bool
+ nullableValue.int = 1; # int
+ nullableValue.float = 1.1; # float
+ nullableValue.str = "foo"; # str
+ nullableValue.path = ./.; # path
+ nullableValue.attrs = {
+ foo = 1;
+ };
+ nullableValue.list = [ { bar = [ 1 ]; } ]; # list
+ nullableValue.lambda = x: x; # Error
+
+ # serializableValueWith { nullable = false; }
+ structuredValue.null = null; # Error
+
assertions =
with lib.types;
@@ -486,6 +515,9 @@ in
assert (unique { message = "custom"; } (listOf str)).description == "list of string";
assert (unique { message = "test"; } (either int str)).description == "signed integer or string";
assert (unique { message = "test"; } (listOf str)).description == "list of string";
+ # json & toml
+ assert json.description == "JSON value";
+ assert toml.description == "TOML value";
# done
"ok";
};
diff --git a/lib/types.nix b/lib/types.nix
index bd9ac93df472..1a98b12bd5ca 100644
--- a/lib/types.nix
+++ b/lib/types.nix
@@ -1437,6 +1437,45 @@ rec {
};
};
+ /**
+ Creates a value type suitable for serialization formats.
+
+ Parameters:
+ - typeName: String describing the format (e.g. "JSON", "YAML", "XML")
+ - nullable: Whether the structured value type allows `null` values.
+
+ Returns a type suitable for structured data formats that supports:
+ - Basic types: boolean, integer, float, string, path
+ - Complex types: attribute sets and lists
+ */
+ serializableValueWith =
+ {
+ typeName,
+ nullable ? true,
+ }:
+ let
+ baseType = oneOf [
+ bool
+ int
+ float
+ str
+ path
+ (attrsOf valueType)
+ (listOf valueType)
+ ];
+ valueType = (if nullable then nullOr baseType else baseType) // {
+ description = "${typeName} value";
+ };
+ in
+ valueType;
+
+ json = serializableValueWith { typeName = "JSON"; };
+
+ toml = serializableValueWith {
+ typeName = "TOML";
+ nullable = false;
+ };
+
# Either value of type `t1` or `t2`.
either =
t1: t2: