summaryrefslogtreecommitdiffstats
path: root/lib/modules.nix
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2013-10-28 15:48:20 +0100
committerEelco Dolstra <eelco.dolstra@logicblox.com>2013-10-28 22:45:56 +0100
commitf4a418761b481b15900c78b8086e7be58b0afe4e (patch)
treed162399d2c02754bd2c7697b140a0794ccba8254 /lib/modules.nix
parentc263b5b284cee4d2b658c6acd2942e367ac3f985 (diff)
Check for undeclared options
Diffstat (limited to 'lib/modules.nix')
-rw-r--r--lib/modules.nix28
1 files changed, 16 insertions, 12 deletions
diff --git a/lib/modules.nix b/lib/modules.nix
index 7ad722359945..076ffdde2463 100644
--- a/lib/modules.nix
+++ b/lib/modules.nix
@@ -6,16 +6,14 @@ rec {
/* Evaluate a set of modules. The result is a set of two
attributes: ‘options’: the nested set of all option declarations,
and ‘config’: the nested set of all option values. */
- evalModules = evalModules' [];
-
- evalModules' = prefix: modules: args:
+ evalModules = { modules, prefix ? [], args ? {}, check ? true }:
let
args' = args // result;
closed = closeModules modules args';
# Note: the list of modules is reversed to maintain backward
# compatibility with the old module system. Not sure if this is
# the most sensible policy.
- options = mergeModules prefix (reverseList closed);
+ options = mergeModules check prefix (reverseList closed);
config = yieldConfig options;
yieldConfig = mapAttrs (n: v: if isOption v then v.value else yieldConfig v);
result = { inherit options config; };
@@ -52,7 +50,7 @@ rec {
{ inherit file key;
imports = m.require or [];
options = {};
- config = m;
+ config = removeAttrs m ["require"];
};
applyIfFunction = f: arg: if builtins.isFunction f then f arg else f;
@@ -62,13 +60,19 @@ rec {
At the same time, for each option declaration, it will merge the
corresponding option definitions in all machines, returning them
in the ‘value’ attribute of each option. */
- mergeModules = prefix: modules:
- mergeModules' prefix modules
+ mergeModules = check: prefix: modules:
+ mergeModules' check prefix modules
(concatMap (m: map (config: { inherit (m) file; inherit config; }) (pushDownProperties m.config)) modules);
- mergeModules' = prefix: options: configs:
- let names = concatMap (m: attrNames m.options) options;
- in listToAttrs (map (name: {
+ mergeModules' = check: prefix: options: configs:
+ let
+ declaredNames = concatMap (m: attrNames m.options) options;
+ declaredNames' = listToAttrs (map (n: { name = n; value = 1; }) declaredNames);
+ checkDefinedNames = res: fold (m: res: fold (n: res:
+ if hasAttr n declaredNames' then res else
+ throw "The option `${showOption (prefix ++ [n])}' defined in `${m.file}' does not exist."
+ ) res (attrNames m.config)) res configs;
+ in (if check then checkDefinedNames else id) (listToAttrs (map (name: {
# We're descending into attribute ‘name’.
inherit name;
value =
@@ -105,8 +109,8 @@ rec {
in
throw "The option `${showOption loc}' in `${firstOption.file}' is a prefix of options in `${firstNonOption.file}'."
else
- mergeModules' loc decls defns;
- }) names);
+ mergeModules' check loc decls defns;
+ }) declaredNames));
/* Merge multiple option declarations into a single declaration. In
general, there should be only one declaration of each option.