lib/types: minimal fix for the regression of either when used in freeformType (#440459)
This commit is contained in:
@@ -244,8 +244,13 @@
|
||||
|
||||
### Deprecations {#sec-nixpkgs-release-25.11-lib-deprecations}
|
||||
|
||||
- Create the first release note entry in this section!
|
||||
- `types.either` silently accepted mismatching types when used in `freeformType`. Module maintainers should fix the used type
|
||||
In most cases wrapping `either` with `attrsOf` should be sufficient.
|
||||
|
||||
Since types.either was used to bootstrap other types. This also affects the following types:
|
||||
- `oneOf`
|
||||
- `number`
|
||||
- `numbers.*`
|
||||
|
||||
### Additions and Improvements {#sec-nixpkgs-release-25.11-lib-additions-improvements}
|
||||
|
||||
|
||||
@@ -550,6 +550,28 @@ checkConfigOutput '/freeform-submodules.nix"$' config.fooDeclarations.0 ./freefo
|
||||
checkConfigOutput '^10$' config.free.xxx.foo ./freeform-submodules.nix
|
||||
checkConfigOutput '^10$' config.free.yyy.bar ./freeform-submodules.nix
|
||||
|
||||
# Regression of either, due to freeform not beeing checked previously
|
||||
checkConfigOutput '^"foo"$' config.either.int ./freeform-deprecated-malicous.nix ./freeform-deprecated-malicous-wrong.nix
|
||||
NIX_ABORT_ON_WARN=1 checkConfigError "One or more definitions did not pass the type-check of the \'either\' type" config.either.int ./freeform-deprecated-malicous.nix ./freeform-deprecated-malicous-wrong.nix
|
||||
checkConfigOutput '^"foo"$' config.eitherBehindNullor.int ./freeform-deprecated-malicous.nix ./freeform-deprecated-malicous-wrong.nix
|
||||
NIX_ABORT_ON_WARN=1 checkConfigError "One or more definitions did not pass the type-check of the \'either\' type" config.eitherBehindNullor.int ./freeform-deprecated-malicous.nix ./freeform-deprecated-malicous-wrong.nix
|
||||
checkConfigOutput '^"foo"$' config.oneOf.int ./freeform-deprecated-malicous.nix ./freeform-deprecated-malicous-wrong.nix
|
||||
NIX_ABORT_ON_WARN=1 checkConfigError "One or more definitions did not pass the type-check of the \'either\' type" config.oneOf.int ./freeform-deprecated-malicous.nix ./freeform-deprecated-malicous-wrong.nix
|
||||
checkConfigOutput '^"foo"$' config.number.str ./freeform-deprecated-malicous.nix ./freeform-deprecated-malicous-wrong.nix
|
||||
NIX_ABORT_ON_WARN=1 checkConfigError "One or more definitions did not pass the type-check of the \'either\' type" config.number.str ./freeform-deprecated-malicous.nix ./freeform-deprecated-malicous-wrong.nix
|
||||
|
||||
checkConfigOutput '^42$' config.either.int ./freeform-deprecated-malicous.nix ./freeform-deprecated-malicous-wrong2.nix
|
||||
NIX_ABORT_ON_WARN=1 checkConfigError "One or more definitions did not pass the type-check of the \'either\' type" config.either.int ./freeform-deprecated-malicous.nix ./freeform-deprecated-malicous-wrong2.nix
|
||||
checkConfigOutput '^42$' config.eitherBehindNullor.int ./freeform-deprecated-malicous.nix ./freeform-deprecated-malicous-wrong2.nix
|
||||
NIX_ABORT_ON_WARN=1 checkConfigError "One or more definitions did not pass the type-check of the \'either\' type" config.eitherBehindNullor.int ./freeform-deprecated-malicous.nix ./freeform-deprecated-malicous-wrong2.nix
|
||||
checkConfigOutput '^42$' config.oneOf.int ./freeform-deprecated-malicous.nix ./freeform-deprecated-malicous-wrong2.nix
|
||||
NIX_ABORT_ON_WARN=1 checkConfigError "One or more definitions did not pass the type-check of the \'either\' type" config.oneOf.int ./freeform-deprecated-malicous.nix ./freeform-deprecated-malicous-wrong2.nix
|
||||
checkConfigOutput '^42$' config.number.str ./freeform-deprecated-malicous.nix ./freeform-deprecated-malicous-wrong2.nix
|
||||
NIX_ABORT_ON_WARN=1 checkConfigError "One or more definitions did not pass the type-check of the \'either\' type" config.number.str ./freeform-deprecated-malicous.nix ./freeform-deprecated-malicous-wrong2.nix
|
||||
# Value OK: Fail if a warning is emitted
|
||||
NIX_ABORT_ON_WARN=1 checkConfigOutput "^42$" config.number.int ./freeform-attrsof-either.nix
|
||||
|
||||
|
||||
## types.anything
|
||||
# Check that attribute sets are merged recursively
|
||||
checkConfigOutput '^null$' config.value.foo ./types-anything/nested-attrs.nix
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
{ lib, ... }:
|
||||
let
|
||||
inherit (lib) types mkOption;
|
||||
in
|
||||
{
|
||||
options.number = mkOption {
|
||||
type = types.submodule ({
|
||||
freeformType = types.attrsOf (types.either types.int types.int);
|
||||
});
|
||||
default = {
|
||||
int = 42;
|
||||
}; # should not emit a warning
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
# Obviously wrong typed
|
||||
{
|
||||
config.either = {
|
||||
int = "foo";
|
||||
};
|
||||
|
||||
config.eitherBehindNullor = {
|
||||
int = "foo";
|
||||
};
|
||||
|
||||
config.oneOf = {
|
||||
int = "foo";
|
||||
};
|
||||
|
||||
config.number = {
|
||||
str = "foo";
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
# freeeformType should have been (attrsOf either)
|
||||
# This should also print the warning
|
||||
{
|
||||
config.either = {
|
||||
int = 42;
|
||||
};
|
||||
|
||||
config.eitherBehindNullor = {
|
||||
int = 42;
|
||||
};
|
||||
|
||||
config.oneOf = {
|
||||
int = 42;
|
||||
};
|
||||
|
||||
config.number = {
|
||||
str = 42;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
{ lib, ... }:
|
||||
let
|
||||
inherit (lib) types mkOption;
|
||||
in
|
||||
{
|
||||
options.either = mkOption {
|
||||
type = types.submodule ({
|
||||
freeformType = (types.either types.int types.int);
|
||||
});
|
||||
};
|
||||
|
||||
options.eitherBehindNullor = mkOption {
|
||||
type = types.submodule ({
|
||||
freeformType = types.nullOr (types.either types.int types.int);
|
||||
});
|
||||
};
|
||||
|
||||
options.oneOf = mkOption {
|
||||
type = types.submodule ({
|
||||
freeformType = (
|
||||
types.oneOf [
|
||||
types.int
|
||||
types.int
|
||||
]
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
options.number = mkOption {
|
||||
type = types.submodule ({
|
||||
freeformType = (types.number); # either int float
|
||||
});
|
||||
};
|
||||
}
|
||||
+6
-1
@@ -1453,7 +1453,12 @@ let
|
||||
headError = {
|
||||
message = "The option `${showOption loc}` is neither a value of type `${t1.description}` nor `${t2.description}`, Definition values: ${showDefs defs}";
|
||||
};
|
||||
value = abort "(t.merge.v2 defs).value must only be accessed when `.headError == null`. This is a bug in code that consumes a module system type.";
|
||||
value = lib.warn ''
|
||||
One or more definitions did not pass the type-check of the 'either' type.
|
||||
${headError.message}
|
||||
If `either`, `oneOf` or similar is used in freeformType, ensure that it is preceded by an 'attrsOf' such as: `freeformType = types.attrsOf (types.either t1 t2)`.
|
||||
Otherwise consider using the correct type for the option `${showOption loc}`. This will be an error in Nixpkgs 26.06.
|
||||
'' (mergeOneOption loc defs);
|
||||
};
|
||||
in
|
||||
checkedAndMerged;
|
||||
|
||||
Reference in New Issue
Block a user