3
0
Fork 0
forked from mirrors/nixpkgs

Merge pull request #242339 from hercules-ci/modules-catch-bare-type

lib/modules: Report a good error when option tree has bare type
This commit is contained in:
Silvan Mosberger 2023-08-14 20:30:41 +02:00 committed by GitHub
commit f10a24eddd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 54 additions and 1 deletions

View file

@ -630,7 +630,13 @@ let
loc = prefix ++ [name]; loc = prefix ++ [name];
defns = pushedDownDefinitionsByName.${name} or []; defns = pushedDownDefinitionsByName.${name} or [];
defns' = rawDefinitionsByName.${name} or []; defns' = rawDefinitionsByName.${name} or [];
optionDecls = filter (m: isOption m.options) decls; optionDecls = filter
(m: m.options?_type
&& (m.options._type == "option"
|| throwDeclarationTypeError loc m.options._type
)
)
decls;
in in
if length optionDecls == length decls then if length optionDecls == length decls then
let opt = fixupOptionType loc (mergeOptionDecls loc decls); let opt = fixupOptionType loc (mergeOptionDecls loc decls);
@ -692,6 +698,32 @@ let
) unmatchedDefnsByName); ) unmatchedDefnsByName);
}; };
throwDeclarationTypeError = loc: actualTag:
let
name = lib.strings.escapeNixIdentifier (lib.lists.last loc);
path = showOption loc;
depth = length loc;
paragraphs = [
"Expected an option declaration at option path `${path}` but got an attribute set with type ${actualTag}"
] ++ optional (actualTag == "option-type") ''
When declaring an option, you must wrap the type in a `mkOption` call. It should look somewhat like:
${comment}
${name} = lib.mkOption {
description = ...;
type = <the type you wrote for ${name}>;
...
};
'';
# Ideally we'd know the exact syntax they used, but short of that,
# we can only reliably repeat the last. However, we repeat the
# full path in a non-misleading way here, in case they overlook
# the start of the message. Examples attract attention.
comment = optionalString (depth > 1) "\n # ${showOption loc}";
in
throw (concatStringsSep "\n\n" paragraphs);
/* Merge multiple option declarations into a single declaration. In /* Merge multiple option declarations into a single declaration. In
general, there should be only one declaration of each option. general, there should be only one declaration of each option.
The exception is the options attribute, which specifies The exception is the options attribute, which specifies

View file

@ -393,6 +393,11 @@ checkConfigError \
config.set \ config.set \
./declare-set.nix ./declare-enable-nested.nix ./declare-set.nix ./declare-enable-nested.nix
# Options: accidental use of an option-type instead of option (or other tagged type; unlikely)
checkConfigError 'Expected an option declaration at option path .result. but got an attribute set with type option-type' config.result ./options-type-error-typical.nix
checkConfigError 'Expected an option declaration at option path .result.here. but got an attribute set with type option-type' config.result.here ./options-type-error-typical-nested.nix
checkConfigError 'Expected an option declaration at option path .result. but got an attribute set with type configuration' config.result ./options-type-error-configuration.nix
# Check that that merging of option collisions doesn't depend on type being set # Check that that merging of option collisions doesn't depend on type being set
checkConfigError 'The option .group..*would be a parent of the following options, but its type .<no description>. does not support nested options.\n\s*- option.s. with prefix .group.enable..*' config.group.enable ./merge-typeless-option.nix checkConfigError 'The option .group..*would be a parent of the following options, but its type .<no description>. does not support nested options.\n\s*- option.s. with prefix .group.enable..*' config.group.enable ./merge-typeless-option.nix

View file

@ -0,0 +1,6 @@
{ lib, ... }: {
options = {
# unlikely mistake, but we can catch any attrset with _type
result = lib.evalModules { modules = []; };
};
}

View file

@ -0,0 +1,5 @@
{ lib, ... }: {
options = {
result.here = lib.types.str;
};
}

View file

@ -0,0 +1,5 @@
{ lib, ... }: {
options = {
result = lib.types.str;
};
}