mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-11-17 19:21:04 +00:00
Merge pull request #131205 from Ma27/showdefs-overflow
lib/modules: improve errors for `options`/`config`-mixups
This commit is contained in:
commit
a3df3d05e5
|
@ -197,6 +197,30 @@ rec {
|
|||
*/
|
||||
toYAML = {}@args: toJSON args;
|
||||
|
||||
withRecursion =
|
||||
args@{
|
||||
/* If this option is not null, the given value will stop evaluating at a certain depth */
|
||||
depthLimit
|
||||
/* If this option is true, an error will be thrown, if a certain given depth is exceeded */
|
||||
, throwOnDepthLimit ? true
|
||||
}:
|
||||
assert builtins.isInt depthLimit;
|
||||
let
|
||||
transform = depth:
|
||||
if depthLimit != null && depth > depthLimit then
|
||||
if throwOnDepthLimit
|
||||
then throw "Exceeded maximum eval-depth limit of ${toString depthLimit} while trying to evaluate with `generators.withRecursion'!"
|
||||
else const "<unevaluated>"
|
||||
else id;
|
||||
mapAny = with builtins; depth: v:
|
||||
let
|
||||
evalNext = x: mapAny (depth + 1) (transform (depth + 1) x);
|
||||
in
|
||||
if isAttrs v then mapAttrs (const evalNext) v
|
||||
else if isList v then map evalNext v
|
||||
else transform (depth + 1) v;
|
||||
in
|
||||
mapAny 0;
|
||||
|
||||
/* Pretty print a value, akin to `builtins.trace`.
|
||||
* Should probably be a builtin as well.
|
||||
|
@ -208,7 +232,8 @@ rec {
|
|||
allowPrettyValues ? false,
|
||||
/* If this option is true, the output is indented with newlines for attribute sets and lists */
|
||||
multiline ? true
|
||||
}@args: let
|
||||
}@args:
|
||||
let
|
||||
go = indent: v: with builtins;
|
||||
let isPath = v: typeOf v == "path";
|
||||
introSpace = if multiline then "\n${indent} " else " ";
|
||||
|
|
|
@ -162,13 +162,24 @@ rec {
|
|||
baseMsg = "The option `${showOption (prefix ++ firstDef.prefix)}' does not exist. Definition values:${showDefs [ firstDef ]}";
|
||||
in
|
||||
if attrNames options == [ "_module" ]
|
||||
then throw ''
|
||||
${baseMsg}
|
||||
then
|
||||
let
|
||||
optionName = showOption prefix;
|
||||
in
|
||||
if optionName == ""
|
||||
then throw ''
|
||||
${baseMsg}
|
||||
|
||||
However there are no options defined in `${showOption prefix}'. Are you sure you've
|
||||
declared your options properly? This can happen if you e.g. declared your options in `types.submodule'
|
||||
under `config' rather than `options'.
|
||||
''
|
||||
It seems as if you're trying to declare an option by placing it into `config' rather than `options'!
|
||||
''
|
||||
else
|
||||
throw ''
|
||||
${baseMsg}
|
||||
|
||||
However there are no options defined in `${showOption prefix}'. Are you sure you've
|
||||
declared your options properly? This can happen if you e.g. declared your options in `types.submodule'
|
||||
under `config' rather than `options'.
|
||||
''
|
||||
else throw baseMsg
|
||||
else null;
|
||||
|
||||
|
|
|
@ -247,7 +247,9 @@ rec {
|
|||
showDefs = defs: concatMapStrings (def:
|
||||
let
|
||||
# Pretty print the value for display, if successful
|
||||
prettyEval = builtins.tryEval (lib.generators.toPretty {} def.value);
|
||||
prettyEval = builtins.tryEval
|
||||
(lib.generators.toPretty { }
|
||||
(lib.generators.withRecursion { depthLimit = 10; throwOnDepthLimit = false; } def.value));
|
||||
# Split it into its lines
|
||||
lines = filter (v: ! isList v) (builtins.split "\n" prettyEval.value);
|
||||
# Only display the first 5 lines, and indent them for better visibility
|
||||
|
|
|
@ -529,6 +529,25 @@ runTests {
|
|||
};
|
||||
};
|
||||
|
||||
testToPrettyLimit =
|
||||
let
|
||||
a.b = 1;
|
||||
a.c = a;
|
||||
in {
|
||||
expr = generators.toPretty { } (generators.withRecursion { throwOnDepthLimit = false; depthLimit = 2; } a);
|
||||
expected = "{\n b = 1;\n c = {\n b = \"<unevaluated>\";\n c = {\n b = \"<unevaluated>\";\n c = \"<unevaluated>\";\n };\n };\n}";
|
||||
};
|
||||
|
||||
testToPrettyLimitThrow =
|
||||
let
|
||||
a.b = 1;
|
||||
a.c = a;
|
||||
in {
|
||||
expr = (builtins.tryEval
|
||||
(generators.toPretty { } (generators.withRecursion { depthLimit = 2; } a))).success;
|
||||
expected = false;
|
||||
};
|
||||
|
||||
testToPrettyMultiline = {
|
||||
expr = mapAttrs (const (generators.toPretty { })) rec {
|
||||
list = [ 3 4 [ false ] ];
|
||||
|
|
Loading…
Reference in a new issue