lib.types: Make functor.wrapped deprecation work in unprocessed types (#382848)

This commit is contained in:
Johannes Kirschbauer
2025-02-21 15:57:20 +07:00
committed by GitHub
3 changed files with 72 additions and 5 deletions

View File

@@ -398,9 +398,23 @@ checkConfigError 'infinite recursion encountered' config.nonLazyResult ./lazy-at
checkConfigOutput '^"mergedName.<id>.nested"$' config.result ./name-merge-attrsWith-1.nix
checkConfigError 'The option .mergedName. in .*\.nix. is already declared in .*\.nix' config.mergedName ./name-merge-attrsWith-2.nix
# Test the attrsOf functor.wrapped warning
# shellcheck disable=2016
NIX_ABORT_ON_WARN=1 checkConfigError 'The deprecated `type.functor.wrapped` attribute of the option `mergedLazyLazy` is accessed, use `type.nestedTypes.elemType` instead.' options.mergedLazyLazy.type.functor.wrapped ./lazy-attrsWith.nix
# Test type.functor.wrapped deprecation warning
# should emit the warning on:
# - merged types
# - non-merged types
# - nestedTypes elemType
# attrsWith
NIX_ABORT_ON_WARN=1 checkConfigError 'The deprecated `.*functor.wrapped` attribute .*is accessed, use `.*nestedTypes.elemType` instead.' options.attrsWith.type.functor.wrapped ./deprecated-wrapped.nix
NIX_ABORT_ON_WARN=1 checkConfigError 'The deprecated `.*functor.wrapped` attribute .*is accessed, use `.*nestedTypes.elemType` instead.' options.mergedAttrsWith.type.functor.wrapped ./deprecated-wrapped.nix
NIX_ABORT_ON_WARN=1 checkConfigError 'The deprecated `.*functor.wrapped` attribute .*is accessed, use `.*nestedTypes.elemType` instead.' options.attrsWith.type.nestedTypes.elemType.functor.wrapped ./deprecated-wrapped.nix
NIX_ABORT_ON_WARN=1 checkConfigError 'The deprecated `.*functor.wrapped` attribute .*is accessed, use `.*nestedTypes.elemType` instead.' options.mergedAttrsWith.type.nestedTypes.elemType.functor.wrapped ./deprecated-wrapped.nix
# listOf
NIX_ABORT_ON_WARN=1 checkConfigError 'The deprecated `.*functor.wrapped` attribute .*is accessed, use `.*nestedTypes.elemType` instead.' options.listOf.type.functor.wrapped ./deprecated-wrapped.nix
NIX_ABORT_ON_WARN=1 checkConfigError 'The deprecated `.*functor.wrapped` attribute .*is accessed, use `.*nestedTypes.elemType` instead.' options.mergedListOf.type.functor.wrapped ./deprecated-wrapped.nix
NIX_ABORT_ON_WARN=1 checkConfigError 'The deprecated `.*functor.wrapped` attribute .*is accessed, use `.*nestedTypes.elemType` instead.' options.listOf.type.nestedTypes.elemType.functor.wrapped ./deprecated-wrapped.nix
NIX_ABORT_ON_WARN=1 checkConfigError 'The deprecated `.*functor.wrapped` attribute .*is accessed, use `.*nestedTypes.elemType` instead.' options.mergedListOf.type.nestedTypes.elemType.functor.wrapped ./deprecated-wrapped.nix
# Even with multiple assignments, a type error should be thrown if any of them aren't valid
checkConfigError 'A definition for option .* is not of type .*' \

View File

@@ -0,0 +1,44 @@
{ lib, ... }:
let
inherit (lib) types mkOption;
inherit (types)
# attrsOf uses attrsWith internally
attrsOf
listOf
;
in
{
imports = [
# Module A
(
{ ... }:
{
options.attrsWith = mkOption {
type = attrsOf (listOf types.str);
};
options.mergedAttrsWith = mkOption {
type = attrsOf (listOf types.str);
};
options.listOf = mkOption {
type = listOf (listOf types.str);
};
options.mergedListOf = mkOption {
type = listOf (listOf types.str);
};
}
)
# Module B
(
{ ... }:
{
options.mergedAttrsWith = mkOption {
type = attrsOf (listOf types.str);
};
options.mergedListOf = mkOption {
type = listOf (listOf types.str);
};
}
)
];
}

View File

@@ -86,7 +86,7 @@ let
else
{ elemType = merged; };
wrappedDeprecationMessage = { loc }: lib.warn ''
The deprecated `type.functor.wrapped` attribute of the option `${showOption loc}` is accessed, use `type.nestedTypes.elemType` instead.
The deprecated `${lib.optionalString (loc != null) "type."}functor.wrapped` attribute ${lib.optionalString (loc != null) "of the option `${showOption loc}` "}is accessed, use `${lib.optionalString (loc != null) "type."}nestedTypes.elemType` instead.
'' payload.elemType;
};
@@ -227,7 +227,16 @@ rec {
{ _type = "option-type";
inherit
name check merge emptyValue getSubOptions getSubModules substSubModules
typeMerge functor deprecationMessage nestedTypes descriptionClass;
typeMerge deprecationMessage nestedTypes descriptionClass;
functor =
if functor ? wrappedDeprecationMessage then
functor // {
wrapped = functor.wrappedDeprecationMessage {
loc = null;
};
}
else
functor;
description = if description == null then name else description;
};