NixOS modules: Add error context on module arguments evaluation.

This commit is contained in:
Nicolas B. Pierron 2015-05-13 22:44:04 +02:00
parent 2fa88f65ea
commit a6b455bbae
5 changed files with 37 additions and 8 deletions

View File

@ -91,9 +91,11 @@ rec {
let let
toClosureList = file: parentKey: imap (n: x: toClosureList = file: parentKey: imap (n: x:
if isAttrs x || isFunction x then if isAttrs x || isFunction x then
unifyModuleSyntax file "${parentKey}:anon-${toString n}" (unpackSubmodule applyIfFunction x args) let key = "${parentKey}:anon-${toString n}"; in
unifyModuleSyntax file key (unpackSubmodule (applyIfFunction key) x args)
else else
unifyModuleSyntax (toString x) (toString x) (applyIfFunction (import x) args)); let file = toString x; key = toString x; in
unifyModuleSyntax file key (applyIfFunction key (import x) args));
in in
builtins.genericClosure { builtins.genericClosure {
startSet = toClosureList unknownModule "" modules; startSet = toClosureList unknownModule "" modules;
@ -122,7 +124,7 @@ rec {
config = removeAttrs m ["key" "_file" "require" "imports"]; config = removeAttrs m ["key" "_file" "require" "imports"];
}; };
applyIfFunction = f: arg@{ config, options, lib, ... }: if isFunction f then applyIfFunction = key: f: args@{ config, options, lib, ... }: if isFunction f then
let let
# Module arguments are resolved in a strict manner when attribute set # Module arguments are resolved in a strict manner when attribute set
# deconstruction is used. As the arguments are now defined with the # deconstruction is used. As the arguments are now defined with the
@ -137,11 +139,18 @@ rec {
# not their values. The values are forwarding the result of the # not their values. The values are forwarding the result of the
# evaluation of the option. # evaluation of the option.
requiredArgs = builtins.attrNames (builtins.functionArgs f); requiredArgs = builtins.attrNames (builtins.functionArgs f);
context = name: ''while evaluating the module argument `${name}' in "${key}":'';
extraArgs = builtins.listToAttrs (map (name: { extraArgs = builtins.listToAttrs (map (name: {
inherit name; inherit name;
value = config._module.args.${name}; value = addErrorContext (context name)
(args.${name} or config._module.args.${name});
}) requiredArgs); }) requiredArgs);
in f (extraArgs // arg)
# Note: we append in the opposite order such that we can add an error
# context on the explicited arguments of "args" too. This update
# operator is used to make the "args@{ ... }: with args.lib;" notation
# works.
in f (args // extraArgs)
else else
f; f;

View File

@ -12,7 +12,7 @@ evalConfig() {
local attr=$1 local attr=$1
shift; shift;
local script="import ./default.nix { modules = [ $@ ];}" local script="import ./default.nix { modules = [ $@ ];}"
nix-instantiate --timeout 1 -E "$script" -A "$attr" --eval-only nix-instantiate --timeout 1 -E "$script" -A "$attr" --eval-only --show-trace
} }
reportFailure() { reportFailure() {
@ -100,7 +100,15 @@ checkConfigOutput 'true' "$@" ./define-enable.nix ./define-loaOfSub-foo-if-enabl
checkConfigOutput 'true' "$@" ./define-enable.nix ./define-loaOfSub-foo-enable-if.nix checkConfigOutput 'true' "$@" ./define-enable.nix ./define-loaOfSub-foo-enable-if.nix
# Check _module.args. # Check _module.args.
checkConfigOutput "true" config.enable ./declare-enable.nix ./custom-arg-define-enable.nix set -- config.enable ./declare-enable.nix ./define-enable-with-custom-arg.nix
checkConfigError 'while evaluating the module argument .*custom.* in .*define-enable-with-custom-arg.nix.*:' "$@"
checkConfigOutput "true" "$@" ./define-_module-args-custom.nix
# Check that using _module.args on imports cause infinite recursions, with
# the proper error context.
set -- "$@" ./define-_module-args-custom.nix ./import-custom-arg.nix
checkConfigError 'while evaluating the module argument .*custom.* in .*import-custom-arg.nix.*:' "$@"
checkConfigError 'infinite recursion encountered' "$@"
# Check _module.check. # Check _module.check.
set -- config.enable ./declare-enable.nix ./define-enable.nix ./define-loaOfSub-foo.nix set -- config.enable ./declare-enable.nix ./define-enable.nix ./define-loaOfSub-foo.nix

View File

@ -0,0 +1,7 @@
{ lib, ... }:
{
config = {
_module.args.custom = true;
};
}

View File

@ -2,7 +2,6 @@
{ {
config = { config = {
_module.args.custom = true;
enable = custom; enable = custom;
}; };
} }

View File

@ -0,0 +1,6 @@
{ lib, custom, ... }:
{
imports = []
++ lib.optional custom ./define-enable-force.nix;
}