NixOS modules: Add error context on module arguments evaluation.
This commit is contained in:
parent
2fa88f65ea
commit
a6b455bbae
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
{ lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
config = {
|
||||||
|
_module.args.custom = true;
|
||||||
|
};
|
||||||
|
}
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
{
|
{
|
||||||
config = {
|
config = {
|
||||||
_module.args.custom = true;
|
|
||||||
enable = custom;
|
enable = custom;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{ lib, custom, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = []
|
||||||
|
++ lib.optional custom ./define-enable-force.nix;
|
||||||
|
}
|
Loading…
Reference in New Issue