diff options
author | Nicolas Pierron <nicolas.b.pierron@gmail.com> | 2012-04-15 23:31:48 +0000 |
---|---|---|
committer | Nicolas Pierron <nicolas.b.pierron@gmail.com> | 2012-04-15 23:31:48 +0000 |
commit | 8a677091830176ba5e820f5421e7d6f7eb938f8c (patch) | |
tree | 9ac4d09cf8b5efbabfe8dce5b06fd7c359686cc0 /pkgs | |
parent | a9c51d7af3bd5c6b633d56afe1cb854b967e5c57 (diff) | |
download | nixlib-8a677091830176ba5e820f5421e7d6f7eb938f8c.tar nixlib-8a677091830176ba5e820f5421e7d6f7eb938f8c.tar.gz nixlib-8a677091830176ba5e820f5421e7d6f7eb938f8c.tar.bz2 nixlib-8a677091830176ba5e820f5421e7d6f7eb938f8c.tar.lz nixlib-8a677091830176ba5e820f5421e7d6f7eb938f8c.tar.xz nixlib-8a677091830176ba5e820f5421e7d6f7eb938f8c.tar.zst nixlib-8a677091830176ba5e820f5421e7d6f7eb938f8c.zip |
Add mkMerge and obsolete mkThenElse.
svn path=/nixpkgs/trunk/; revision=33796
Diffstat (limited to 'pkgs')
-rw-r--r-- | pkgs/lib/modules.nix | 46 | ||||
-rw-r--r-- | pkgs/lib/properties.nix | 31 |
2 files changed, 62 insertions, 15 deletions
diff --git a/pkgs/lib/modules.nix b/pkgs/lib/modules.nix index 8ecb04156e78..eb528f141fe2 100644 --- a/pkgs/lib/modules.nix +++ b/pkgs/lib/modules.nix @@ -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); diff --git a/pkgs/lib/properties.nix b/pkgs/lib/properties.nix index d7df14f716f5..0d864b0c553c 100644 --- a/pkgs/lib/properties.nix +++ b/pkgs/lib/properties.nix @@ -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"; |