Replace a counter intuitive behaviour of module evaluations.
- types.nix: Introduce a new flag named "delayProperties" which define either that properties should be evaluated (when false) or that they should be delaied through the type structure. - properties.nix: Generalized the delayProperties function to make it work with the iter functions of option types. - modules.nix: Replace evalProperties by a condition based on the value of the "delayProperties" flag of the option type. If the flag does not exists or if it is false, then the system behaves as always. Otherwise it delays the properties from the current value to each values contained inside it. svn path=/nixpkgs/trunk/; revision=17736
This commit is contained in:
parent
fd0396037a
commit
bb16a7f08d
|
@ -113,9 +113,17 @@ rec {
|
|||
value
|
||||
) module;
|
||||
|
||||
|
||||
delayModule = module:
|
||||
moduleApply { config = delayProperties; } module;
|
||||
|
||||
evalDefinitions = opt: values:
|
||||
if opt ? type && opt.type.delayProperties then
|
||||
map (delayPropertiesTemplate opt.type.iter opt.name) values
|
||||
else
|
||||
evalProperties values;
|
||||
|
||||
|
||||
selectModule = name: m:
|
||||
{ inherit (m) key;
|
||||
} // (
|
||||
|
@ -243,7 +251,7 @@ rec {
|
|||
opt.extraConfigs;
|
||||
|
||||
in if hasOpt && isOption opt then
|
||||
let defs = evalProperties values; in
|
||||
let defs = evalDefinitions opt values; in
|
||||
lib.addErrorContext "${eol
|
||||
}while evaluating the option '${addName name}'.${eol
|
||||
}${errorSource (modulesOf name)}${eol
|
||||
|
|
|
@ -69,18 +69,21 @@ rec {
|
|||
# Move properties from the current attribute set to the attribute
|
||||
# contained in this attribute set. This trigger property handlers called
|
||||
# `onDelay' and `onGlobalDelay'.
|
||||
delayProperties = attrs:
|
||||
delayPropertiesWithIter = iter: path: attrs:
|
||||
let cleanAttrs = rmProperties attrs; in
|
||||
if isProperty attrs then
|
||||
lib.mapAttrs (a: v:
|
||||
iter (a: v:
|
||||
lib.addErrorContext "while moving properties on the attribute `${a}'." (
|
||||
triggerPropertiesGlobalDelay a (
|
||||
triggerPropertiesDelay a (
|
||||
copyProperties attrs v
|
||||
)))) cleanAttrs
|
||||
)))) path cleanAttrs
|
||||
else
|
||||
attrs;
|
||||
|
||||
delayProperties = # implicit attrs argument.
|
||||
delayPropertiesWithIter (f: p: v: lib.mapAttrs f v) "";
|
||||
|
||||
# Call onDelay functions.
|
||||
triggerPropertiesDelay = name: attrs:
|
||||
let
|
||||
|
|
|
@ -19,7 +19,8 @@ rec {
|
|||
# iter (iterate on all elements contained in this type)
|
||||
# fold (fold all elements contained in this type)
|
||||
# hasOptions (boolean: whatever this option contains an option set)
|
||||
# path (path contatenated to the option name contained contained in the option set)
|
||||
# delayProperties (boolean: should properties go through the evaluation of this option)
|
||||
# docPath (path concatenated to the option name contained in the option set)
|
||||
isOptionType = attrs: typeOf attrs == "option-type";
|
||||
mkOptionType =
|
||||
{ name
|
||||
|
@ -31,10 +32,11 @@ rec {
|
|||
, docPath ? lib.id
|
||||
# If the type can contains option sets.
|
||||
, hasOptions ? false
|
||||
, delayProperties ? false
|
||||
}:
|
||||
|
||||
{ _type = "option-type";
|
||||
inherit name check merge iter fold docPath hasOptions;
|
||||
inherit name check merge iter fold docPath hasOptions delayProperties;
|
||||
};
|
||||
|
||||
|
||||
|
@ -73,6 +75,7 @@ rec {
|
|||
check = lib.traceValIfNot isDerivation;
|
||||
};
|
||||
|
||||
listOf = types.list;
|
||||
list = elemType: mkOptionType {
|
||||
name = "list of ${elemType.name}s";
|
||||
check = value: lib.traceValIfNot isList value && all elemType.check value;
|
||||
|
@ -81,6 +84,10 @@ rec {
|
|||
fold = op: nul: list: lib.fold (e: l: elemType.fold op l e) nul list;
|
||||
docPath = path: elemType.docPath (path + ".*");
|
||||
inherit (elemType) hasOptions;
|
||||
|
||||
# You cannot define multiple configurations of one entity, therefore
|
||||
# no reason justify to delay properties inside list elements.
|
||||
delayProperties = false;
|
||||
};
|
||||
|
||||
attrsOf = elemType: mkOptionType {
|
||||
|
@ -91,7 +98,7 @@ rec {
|
|||
iter = f: path: set: lib.mapAttrs (name: elemType.iter f (path + "." + name)) set;
|
||||
fold = op: nul: set: fold (e: l: elemType.fold op l e) nul (lib.attrValues set);
|
||||
docPath = path: elemType.docPath (path + ".<name>");
|
||||
inherit (elemType) hasOptions;
|
||||
inherit (elemType) hasOptions delayProperties;
|
||||
};
|
||||
|
||||
uniq = elemType: mkOptionType {
|
||||
|
@ -118,6 +125,7 @@ rec {
|
|||
merge = lib.id;
|
||||
check = x: lib.traceValIfNot builtins.isAttrs x;
|
||||
hasOptions = true;
|
||||
delayProperties = true;
|
||||
};
|
||||
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue