diff options
author | Robert Hensing <robert@roberthensing.nl> | 2022-02-28 22:39:56 +0100 |
---|---|---|
committer | Robert Hensing <robert@roberthensing.nl> | 2022-03-03 00:29:11 +0100 |
commit | 11537c9c0239dc4ae52477faa78a4a0a7bdf206c (patch) | |
tree | 4c7d2b9f657108be2a4ddb0641643417df53952c /lib | |
parent | 81f342d1f3a6bab4a57e195ce99a153b82b1ef86 (diff) | |
download | nixlib-11537c9c0239dc4ae52477faa78a4a0a7bdf206c.tar nixlib-11537c9c0239dc4ae52477faa78a4a0a7bdf206c.tar.gz nixlib-11537c9c0239dc4ae52477faa78a4a0a7bdf206c.tar.bz2 nixlib-11537c9c0239dc4ae52477faa78a4a0a7bdf206c.tar.lz nixlib-11537c9c0239dc4ae52477faa78a4a0a7bdf206c.tar.xz nixlib-11537c9c0239dc4ae52477faa78a4a0a7bdf206c.tar.zst nixlib-11537c9c0239dc4ae52477faa78a4a0a7bdf206c.zip |
lib.modules: Improve option-is-prefix error message
Diffstat (limited to 'lib')
-rw-r--r-- | lib/modules.nix | 24 | ||||
-rwxr-xr-x | lib/tests/modules.sh | 6 | ||||
-rw-r--r-- | lib/tests/modules/declare-set.nix | 12 |
3 files changed, 39 insertions, 3 deletions
diff --git a/lib/modules.nix b/lib/modules.nix index 62e9615d25b3..7d9c55f9a158 100644 --- a/lib/modules.nix +++ b/lib/modules.nix @@ -9,6 +9,7 @@ let catAttrs concatLists concatMap + concatStringsSep elem filter findFirst @@ -46,6 +47,20 @@ let showOption unknownModule ; + + showDeclPrefix = loc: decl: prefix: + " - option(s) with prefix `${showOption (loc ++ [prefix])}' in module `${decl._file}'"; + showRawDecls = loc: decls: + concatStringsSep "\n" + (sort (a: b: a < b) + (concatMap + (decl: map + (showDeclPrefix loc decl) + (attrNames decl.options) + ) + decls + )); + in rec { @@ -500,7 +515,7 @@ rec { unmatchedDefns = []; } else if optionDecls != [] then - if (lib.head optionDecls).options.type.name == "submodule" + if all (x: x.options.type.name == "submodule") optionDecls # Raw options can only be merged into submodules. Merging into # attrsets might be nice, but ambiguous. Suppose we have # attrset as a `attrsOf submodule`. User declares option @@ -509,7 +524,7 @@ rec { # b. option `foo.bar` is available in all `attrset.*` # c. reject and require "<name>" as a reminder that it behaves like (b). # d. magically combine (a) and (c). - # All options are merely syntax sugar though. + # All of the above are merely syntax sugar though. then let opt = fixupOptionType loc (mergeOptionDecls loc (map optionTreeToOption decls)); in { @@ -519,8 +534,11 @@ rec { else let firstNonOption = findFirst (m: !isOption m.options) "" decls; + nonOptions = filter (m: !isOption m.options) decls; in - throw "The option `${showOption loc}' in `${(lib.head optionDecls)._file}' is a prefix of options in `${firstNonOption._file}'." + throw "The option `${showOption loc}' in module `${(lib.head optionDecls)._file}' would be a parent of the following options, but its type `${(lib.head optionDecls).options.type.description or "<no description>"}' does not support nested options.\n${ + showRawDecls loc nonOptions + }" else mergeModules' loc decls defns) declsByName; diff --git a/lib/tests/modules.sh b/lib/tests/modules.sh index 3591b8f1e6fc..e903714a7209 100755 --- a/lib/tests/modules.sh +++ b/lib/tests/modules.sh @@ -309,6 +309,12 @@ checkConfigOutput "10" config.processedToplevel ./raw.nix checkConfigError "The option .multiple. is defined multiple times" config.multiple ./raw.nix checkConfigOutput "bar" config.priorities ./raw.nix +## Option collision +checkConfigError \ + 'The option .set. in module .*/declare-set.nix. would be a parent of the following options, but its type .attribute set of signed integers. does not support nested options.\n\s*- option[(]s[)] with prefix .set.enable. in module .*/declare-enable-nested.nix.' \ + config.set \ + ./declare-set.nix ./declare-enable-nested.nix + # Test that types.optionType merges types correctly checkConfigOutput '^10$' config.theOption.int ./optionTypeMerging.nix checkConfigOutput '^"hello"$' config.theOption.str ./optionTypeMerging.nix diff --git a/lib/tests/modules/declare-set.nix b/lib/tests/modules/declare-set.nix new file mode 100644 index 000000000000..853418531a81 --- /dev/null +++ b/lib/tests/modules/declare-set.nix @@ -0,0 +1,12 @@ +{ lib, ... }: + +{ + options.set = lib.mkOption { + default = { }; + example = { a = 1; }; + type = lib.types.attrsOf lib.types.int; + description = '' + Some descriptive text + ''; + }; +} |