From 570a103136cef7180a681d0c550fa9149488ccbc Mon Sep 17 00:00:00 2001 From: Marc Weber Date: Tue, 2 Dec 2008 12:26:36 +0000 Subject: [PATCH] adding mergeAttrsByFunc function - its easiy to customize how a name should be merged - the merge function is passed by the attr set itself (and can be overridden/ extended this way) This code can probably be shortened using zip and the like as proposed by Nicolas Pierron (mailinglist) svn path=/nixpkgs/trunk/; revision=13544 --- pkgs/lib/default.nix | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/pkgs/lib/default.nix b/pkgs/lib/default.nix index 1b54fd00ea8..137d5dee501 100644 --- a/pkgs/lib/default.nix +++ b/pkgs/lib/default.nix @@ -676,6 +676,45 @@ rec { else throw "error mergeAttrsNoOverride, attribute ${n} given in both attributes - no merge func defined" else __getAttr n attrs2 # add attribute not existing in attr1 )) attrs1 (__attrNames attrs2); + + + # example usage: + # mergeAttrByFunc { + # inherit mergeAttrBy; # defined below + # buildInputs = [ a b ]; + # } { + # buildInputs = [ c d ]; + # }; + # will result in + # { mergeAttrsBy = [...]; buildInputs = [ a b c d ]; } + # is used by prepareDerivationArgs and can be used when composing using + # foldArgs, composedArgsAndFun or applyAndFun. Example: composableDerivation in all-packages.nix + mergeAttrByFunc = x : y : + let + mergeAttrBy2 = { mergeAttrBy=mergeAttr; } + // (maybeAttr "mergeAttrBy" {} x) + // (maybeAttr "mergeAttrBy" {} y); in + mergeAttrs [ + x y + (mapAttrs ( a : v : # merge special names using given functions + if (__hasAttr a x) + then if (__hasAttr a y) + then v (__getAttr a x) (__getAttr a y) # both have attr, use merge func + else (__getAttr a x) # only x has attr + else (__getAttr a y) # only y has attr) + ) (removeAttrs mergeAttrBy2 + # don't merge attrs which are neither in x nor y + (filter (a : (! __hasAttr a x) && (! __hasAttr a y) ) + (__attrNames mergeAttrBy2)) + ) + ) + ]; + mergeAttrsByFunc = fold mergeAttrByFunc {}; + # sane defaults (same name as attr name so that inherit can be used) + mergeAttrBy = # { buildInputs = concatList; [...]; passthru = mergeAttr; [..]; } + listToAttrs (map (n : nv n concatList) [ "buildInputs" "propagatedBuildInputs" "configureFlags" "prePhases" "postAll" ]) + // listToAttrs (map (n : nv n mergeAttr) [ "passthru" "meta" ]); + # returns atribute values as a list flattenAttrs = set : map ( attr : builtins.getAttr attr set) (attrNames set); mapIf = cond : f : fold ( x : l : if (cond x) then [(f x)] ++ l else l) [];