Check for undeclared options
This commit is contained in:
parent
c263b5b284
commit
f4a418761b
|
@ -6,16 +6,14 @@ rec {
|
||||||
/* Evaluate a set of modules. The result is a set of two
|
/* Evaluate a set of modules. The result is a set of two
|
||||||
attributes: ‘options’: the nested set of all option declarations,
|
attributes: ‘options’: the nested set of all option declarations,
|
||||||
and ‘config’: the nested set of all option values. */
|
and ‘config’: the nested set of all option values. */
|
||||||
evalModules = evalModules' [];
|
evalModules = { modules, prefix ? [], args ? {}, check ? true }:
|
||||||
|
|
||||||
evalModules' = prefix: modules: args:
|
|
||||||
let
|
let
|
||||||
args' = args // result;
|
args' = args // result;
|
||||||
closed = closeModules modules args';
|
closed = closeModules modules args';
|
||||||
# Note: the list of modules is reversed to maintain backward
|
# Note: the list of modules is reversed to maintain backward
|
||||||
# compatibility with the old module system. Not sure if this is
|
# compatibility with the old module system. Not sure if this is
|
||||||
# the most sensible policy.
|
# the most sensible policy.
|
||||||
options = mergeModules prefix (reverseList closed);
|
options = mergeModules check prefix (reverseList closed);
|
||||||
config = yieldConfig options;
|
config = yieldConfig options;
|
||||||
yieldConfig = mapAttrs (n: v: if isOption v then v.value else yieldConfig v);
|
yieldConfig = mapAttrs (n: v: if isOption v then v.value else yieldConfig v);
|
||||||
result = { inherit options config; };
|
result = { inherit options config; };
|
||||||
|
@ -52,7 +50,7 @@ rec {
|
||||||
{ inherit file key;
|
{ inherit file key;
|
||||||
imports = m.require or [];
|
imports = m.require or [];
|
||||||
options = {};
|
options = {};
|
||||||
config = m;
|
config = removeAttrs m ["require"];
|
||||||
};
|
};
|
||||||
|
|
||||||
applyIfFunction = f: arg: if builtins.isFunction f then f arg else f;
|
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
|
At the same time, for each option declaration, it will merge the
|
||||||
corresponding option definitions in all machines, returning them
|
corresponding option definitions in all machines, returning them
|
||||||
in the ‘value’ attribute of each option. */
|
in the ‘value’ attribute of each option. */
|
||||||
mergeModules = prefix: modules:
|
mergeModules = check: prefix: modules:
|
||||||
mergeModules' prefix modules
|
mergeModules' check prefix modules
|
||||||
(concatMap (m: map (config: { inherit (m) file; inherit config; }) (pushDownProperties m.config)) modules);
|
(concatMap (m: map (config: { inherit (m) file; inherit config; }) (pushDownProperties m.config)) modules);
|
||||||
|
|
||||||
mergeModules' = prefix: options: configs:
|
mergeModules' = check: prefix: options: configs:
|
||||||
let names = concatMap (m: attrNames m.options) options;
|
let
|
||||||
in listToAttrs (map (name: {
|
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’.
|
# We're descending into attribute ‘name’.
|
||||||
inherit name;
|
inherit name;
|
||||||
value =
|
value =
|
||||||
|
@ -105,8 +109,8 @@ rec {
|
||||||
in
|
in
|
||||||
throw "The option `${showOption loc}' in `${firstOption.file}' is a prefix of options in `${firstNonOption.file}'."
|
throw "The option `${showOption loc}' in `${firstOption.file}' is a prefix of options in `${firstNonOption.file}'."
|
||||||
else
|
else
|
||||||
mergeModules' loc decls defns;
|
mergeModules' check loc decls defns;
|
||||||
}) names);
|
}) declaredNames));
|
||||||
|
|
||||||
/* Merge multiple option declarations into a single declaration. In
|
/* Merge multiple option declarations into a single declaration. In
|
||||||
general, there should be only one declaration of each option.
|
general, there should be only one declaration of each option.
|
||||||
|
|
|
@ -182,11 +182,11 @@ rec {
|
||||||
let
|
let
|
||||||
coerce = def: if builtins.isFunction def then def else { config = def; };
|
coerce = def: if builtins.isFunction def then def else { config = def; };
|
||||||
modules = opts' ++ map coerce defs;
|
modules = opts' ++ map coerce defs;
|
||||||
in (evalModules' args.prefix modules args).config;
|
in (evalModules { inherit modules args; prefix = args.prefix; }).config;
|
||||||
getSubOptions = prefix: (evalModules' prefix opts'
|
getSubOptions = prefix: (evalModules
|
||||||
# FIXME: hack to get shit to evaluate.
|
{ modules = opts'; inherit prefix;
|
||||||
{ name = ""; }
|
# FIXME: hack to get shit to evaluate.
|
||||||
).options;
|
args = { name = ""; }; }).options;
|
||||||
};
|
};
|
||||||
|
|
||||||
# Obsolete alternative to configOf. It takes its option
|
# Obsolete alternative to configOf. It takes its option
|
||||||
|
|
|
@ -7,19 +7,21 @@
|
||||||
, baseModules ? import ../modules/module-list.nix
|
, baseModules ? import ../modules/module-list.nix
|
||||||
, extraArgs ? {}
|
, extraArgs ? {}
|
||||||
, modules
|
, modules
|
||||||
|
, check ? true
|
||||||
}:
|
}:
|
||||||
|
|
||||||
let extraArgs_ = extraArgs; pkgs_ = pkgs; system_ = system; in
|
let extraArgs_ = extraArgs; pkgs_ = pkgs; system_ = system; in
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
|
|
||||||
# These are the NixOS modules that constitute the system configuration.
|
|
||||||
configComponents = modules ++ baseModules;
|
|
||||||
|
|
||||||
# Merge the option definitions in all modules, forming the full
|
# Merge the option definitions in all modules, forming the full
|
||||||
# system configuration. It's not checked for undeclared options.
|
# system configuration.
|
||||||
systemModule =
|
systemModule =
|
||||||
pkgs.lib.evalModules configComponents extraArgs;
|
pkgs.lib.evalModules {
|
||||||
|
modules = modules ++ baseModules;
|
||||||
|
args = extraArgs;
|
||||||
|
inherit check;
|
||||||
|
};
|
||||||
|
|
||||||
config = systemModule.config;
|
config = systemModule.config;
|
||||||
|
|
||||||
|
@ -54,6 +56,7 @@ rec {
|
||||||
# define nixpkgs.config, so it's pointless to evaluate them.
|
# define nixpkgs.config, so it's pointless to evaluate them.
|
||||||
baseModules = [ ../modules/misc/nixpkgs.nix ];
|
baseModules = [ ../modules/misc/nixpkgs.nix ];
|
||||||
pkgs = import ./nixpkgs.nix { system = system_; config = {}; };
|
pkgs = import ./nixpkgs.nix { system = system_; config = {}; };
|
||||||
|
check = false;
|
||||||
}).config.nixpkgs;
|
}).config.nixpkgs;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,13 +16,15 @@ let
|
||||||
system.nixosRevision = config.system.nixosRevision;
|
system.nixosRevision = config.system.nixosRevision;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
eval = evalModules {
|
||||||
|
modules = [ versionModule ] ++ baseModules;
|
||||||
|
args = (removeAttrs extraArgs ["config" "options"]) // { modules = [ ]; };
|
||||||
|
};
|
||||||
|
|
||||||
manual = import ../../../doc/manual {
|
manual = import ../../../doc/manual {
|
||||||
inherit pkgs;
|
inherit pkgs;
|
||||||
revision = config.system.nixosRevision;
|
revision = config.system.nixosRevision;
|
||||||
options = (evalModules ([ versionModule ] ++ baseModules)
|
options = eval.options;
|
||||||
(removeAttrs extraArgs ["config" "options"]) // {
|
|
||||||
modules = [ ];
|
|
||||||
}).options;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
entry = "${manual.manual}/share/doc/nixos/manual.html";
|
entry = "${manual.manual}/share/doc/nixos/manual.html";
|
||||||
|
|
Loading…
Reference in New Issue