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:
Nicolas Pierron 2009-10-09 18:11:30 +00:00
parent fd0396037a
commit bb16a7f08d
3 changed files with 26 additions and 7 deletions

View file

@ -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

View file

@ -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

View file

@ -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;
};
};