Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion lib/generators.nix
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,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.
Expand All @@ -206,7 +230,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 " ";
Expand Down
25 changes: 18 additions & 7 deletions lib/modules.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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}

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'.
''
then
let
optionName = showOption prefix;
in
if optionName == ""
then throw ''
${baseMsg}

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;

Expand Down
4 changes: 3 additions & 1 deletion lib/options.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
19 changes: 19 additions & 0 deletions lib/tests/misc.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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 ] ];
Expand Down