Add mkMerge and obsolete mkThenElse.

svn path=/nixpkgs/trunk/; revision=33796
This commit is contained in:
Nicolas Pierron 2012-04-15 23:31:48 +00:00
parent a9c51d7af3
commit 8a67709183
2 changed files with 61 additions and 14 deletions

View file

@ -41,29 +41,31 @@ rec {
# attributes.
unifyModuleSyntax = m:
let
getImports = m:
delayedModule = delayProperties m;
getImports =
if m ? config || m ? options then
attrByPath ["imports"] [] m
else
toList (rmProperties (attrByPath ["require"] [] (delayProperties m)));
toList (rmProperties (attrByPath ["require"] [] delayedModule));
getImportedPaths = m: filter isPath (getImports m);
getImportedSets = m: filter (x: !isPath x) (getImports m);
getImportedPaths = filter isPath getImports;
getImportedSets = filter (x: !isPath x) getImports;
getConfig =
removeAttrs delayedModule ["require" "key"];
getConfig = m:
removeAttrs (delayProperties m) ["require" "key"];
in
if isModule m then
{ key = "<unknown location>"; } // m
else
{
key = "<unknown location>";
imports = getImportedPaths m;
config = getConfig m;
imports = getImportedPaths;
config = getConfig;
} // (
if getImportedSets m != [] then
assert tail (getImportedSets m) == [];
{ options = head (getImportedSets m); }
if getImportedSets != [] then
assert tail getImportedSets == [];
{ options = head getImportedSets; }
else
{}
);
@ -124,9 +126,25 @@ rec {
value
) module;
# Handle mkMerge function left behind after a delay property.
moduleFlattenMerge = module:
if module ? config &&
isProperty module.config &&
isMerge module.config.property
then
(map (cfg: { key = module.key; config = cfg; }) module.config.content)
++ [ (module // { config = {}; }) ]
else
[ module ];
# Handle mkMerge attributes which are left behind by previous delay
# properties and convert them into a list of modules. Delay properties
# inside the config attribute of a module and create a second module if a
# mkMerge attribute was left behind.
#
# Module -> [ Module ]
delayModule = module:
moduleApply { config = delayProperties; } module;
map (moduleApply { config = delayProperties; }) (moduleFlattenMerge module);
evalDefinitions = opt: values:
if opt ? type && opt.type.delayOnGlobalEval then
@ -170,7 +188,7 @@ rec {
addName = name:
if path == "" then name else path + "." + name;
modules = map delayModule modules_;
modules = concatLists (map delayModule modules_);
modulesOf = name: filterModules name modules;
declarationsOf = name: filter (m: m ? options) (modulesOf name);

View file

@ -82,7 +82,19 @@ rec {
attrs;
delayProperties = # implicit attrs argument.
delayPropertiesWithIter (f: p: v: lib.mapAttrs f v) "";
let
# mapAttrs except that it also recurse into potential mkMerge
# functions. This may cause a strictness issue because looking the
# type of a string implies evaluating it.
iter = fun: path: value:
lib.mapAttrs (attr: val:
if isProperty val && isMerge val.property then
val // { content = map (fun attr) val.content; }
else
fun attr val
) value;
in
delayPropertiesWithIter iter "";
# Call onDelay functions.
triggerPropertiesDelay = name: attrs:
@ -179,6 +191,22 @@ rec {
copyProperties = attrs: newAttrs:
foldProperty id (x: newAttrs) attrs;
/* Merge. */
# Create "merge" statement which is skipped by the delayProperty function
# and interpreted by the underlying system using properties (modules).
# Create a "Merge" property which only contains a condition.
isMerge = attrs: (typeOf attrs) == "merge";
mkMerge = content: mkProperty {
property = {
_type = "merge";
onDelay = name: val: throw "mkMerge is not the first of the list of properties.";
onEval = val: throw "mkMerge is not allowed on option definitions.";
};
inherit content;
};
/* If. ThenElse. Always. */
# create "if" statement that can be delayed on sets until a "then-else" or
@ -202,6 +230,7 @@ rec {
isThenElse = attrs: (typeOf attrs) == "then-else";
mkThenElse = attrs:
assert attrs ? thenPart && attrs ? elsePart;
__trace "Obsolete usage of mkThenElse, replace it by mkMerge."
mkProperty {
property = {
_type = "then-else";