lib/modules: add suggestions to invalid option name errors

This change introduces the suggesting of possible valid option names for
a given invalid option, based on the keys of said invalid option's
parent attrset. That is, `foo.bar.baz` will only be suggested keys from
`foo.bar`, while `(config).baz` will only be suggested keys from the
toplevel.
This commit is contained in:
Winter
2025-09-11 22:48:47 -04:00
parent 9403601d25
commit 0f54833b4a
4 changed files with 54 additions and 1 deletions

View File

@@ -20,12 +20,14 @@ let
head
id
imap1
init
isAttrs
isBool
isFunction
oldestSupportedReleaseIsAtLeast
isList
isString
last
length
mapAttrs
mapAttrsToList
@@ -35,6 +37,7 @@ let
optionalAttrs
optionalString
recursiveUpdate
remove
reverseList
sort
seq
@@ -60,6 +63,7 @@ let
;
inherit (lib.strings)
isConvertibleWithToString
levenshtein
;
showDeclPrefix =
@@ -303,8 +307,17 @@ let
addErrorContext
"while evaluating the error message for definitions for `${optText}', which is an option that does not exist"
(addErrorContext "while evaluating a definition from `${firstDef.file}'" (showDefs [ firstDef ]));
prefix' = init (prefix ++ firstDef.prefix);
adj = attrNames (attrByPath prefix' { } options);
adj' = if prefix' == [ ] then remove "_module" adj else adj;
lev = levenshtein (last firstDef.prefix);
closest = if adj' == [ ] then null else head (sort (p: q: lev p < lev q) adj');
suggestion =
optionalString (closest != null)
"\n\nDid you mean `${showOption (prefix' ++ [ closest ])}'?";
in
"The option `${optText}' does not exist. Definition values:${defText}";
"The option `${optText}' does not exist. Definition values:${defText}${suggestion}";
in
if
attrNames options == [ "_module" ]

View File

@@ -741,6 +741,10 @@ checkConfigError 'attribute .*bar.* not found' config.sub.conditionalImportAsNix
checkConfigError 'attribute .*foo.* not found' config.sub.conditionalImportAsDarwin.foo ./specialArgs-class.nix
checkConfigOutput '"foo"' config.sub.conditionalImportAsDarwin.bar ./specialArgs-class.nix
# Option name suggestions
checkConfigError 'Did you mean .set\.enable.\?' config.set ./error-typo-nested.nix
checkConfigError 'Did you mean .set.\?' config ./error-typo-outside-with-nested.nix
cat <<EOF
====== module tests ======
$pass Pass

View File

@@ -0,0 +1,18 @@
{ lib, ... }:
{
options.set = {
enable = lib.mkOption {
default = false;
example = true;
type = lib.types.bool;
description = ''
Some descriptive text
'';
};
};
config = {
set.ena = true;
};
}

View File

@@ -0,0 +1,18 @@
{ lib, ... }:
{
options.set = {
enable = lib.mkOption {
default = false;
example = true;
type = lib.types.bool;
description = ''
Some descriptive text
'';
};
};
config = {
sea.enable = true;
};
}