* Moved mapAttrs to attrsets.nix.
* Added a function mapAttrsRecursive, which is like mapAttrs, but recursively applies itself to attribute sets. * Commented and cleaned up some functions. svn path=/nixpkgs/trunk/; revision=14495
This commit is contained in:
parent
e629ce0e07
commit
b53ef57554
|
@ -3,16 +3,18 @@
|
||||||
with {
|
with {
|
||||||
inherit (builtins) head tail;
|
inherit (builtins) head tail;
|
||||||
inherit (import ./default.nix) fold;
|
inherit (import ./default.nix) fold;
|
||||||
|
inherit (import ./strings.nix) concatStringsSep;
|
||||||
};
|
};
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
inherit (builtins) attrNames listToAttrs hasAttr isAttrs;
|
inherit (builtins) attrNames listToAttrs hasAttr isAttrs;
|
||||||
|
|
||||||
|
|
||||||
# Return an attribute from nested attribute sets. For instance ["x"
|
/* Return an attribute from nested attribute sets. For instance
|
||||||
# "y"] applied to some set e returns e.x.y, if it exists. The
|
["x" "y"] applied to some set e returns e.x.y, if it exists. The
|
||||||
# default value is returned otherwise. !!! there is also
|
default value is returned otherwise. !!! there is also
|
||||||
# builtins.getAttr (is there a better name for this function?)
|
builtins.getAttr (is there a better name for this function?)
|
||||||
|
*/
|
||||||
getAttr = attrPath: default: e:
|
getAttr = attrPath: default: e:
|
||||||
let attr = head attrPath;
|
let attr = head attrPath;
|
||||||
in
|
in
|
||||||
|
@ -21,14 +23,80 @@ rec {
|
||||||
then getAttr (tail attrPath) default (builtins.getAttr attr e)
|
then getAttr (tail attrPath) default (builtins.getAttr attr e)
|
||||||
else default;
|
else default;
|
||||||
|
|
||||||
# ordered by name
|
|
||||||
attrValues = attrs: attrVals (__attrNames attrs) attrs;
|
|
||||||
|
|
||||||
attrVals = nameList : attrSet :
|
getAttrFromPath = attrPath: set:
|
||||||
map (x: builtins.getAttr x attrSet) nameList;
|
let errorMsg = "cannot find attribute `" + concatStringsSep "." attrPath + "'";
|
||||||
|
in getAttr attrPath (abort errorMsg) set;
|
||||||
|
|
||||||
|
|
||||||
# iterates over a list of attributes collecting the attribute attr if it exists
|
/* Return the specified attributes from a set.
|
||||||
catAttrs = attr : l : fold ( s : l : if (hasAttr attr s) then [(builtins.getAttr attr s)] ++ l else l) [] l;
|
|
||||||
|
Example:
|
||||||
|
attrVals ["a" "b" "c"] as
|
||||||
|
=> [as.a as.b as.c]
|
||||||
|
*/
|
||||||
|
attrVals = nameList: set:
|
||||||
|
map (x: builtins.getAttr x set) nameList;
|
||||||
|
|
||||||
|
|
||||||
}
|
/* Return the values of all attributes in the given set, sorted by
|
||||||
|
attribute name.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
attrValues {c = 3; a = 1; b = 2;}
|
||||||
|
=> [1 2 3]
|
||||||
|
*/
|
||||||
|
attrValues = attrs: attrVals (attrNames attrs) attrs;
|
||||||
|
|
||||||
|
|
||||||
|
/* Collect each attribute named `attr' from a list of attribute
|
||||||
|
sets. Sets that don't contain the named attribute are ignored.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
catAttrs "a" [{a = 1;} {b = 0;} {a = 2;}]
|
||||||
|
=> [1 2]
|
||||||
|
*/
|
||||||
|
catAttrs = attr: l: fold (s: l: if hasAttr attr s then [(builtins.getAttr attr s)] ++ l else l) [] l;
|
||||||
|
|
||||||
|
|
||||||
|
/* Utility function that creates a {name, value} pair as expected by
|
||||||
|
builtins.listToAttrs. */
|
||||||
|
nameValuePair = name: value: { inherit name value; };
|
||||||
|
|
||||||
|
|
||||||
|
/* Apply a function to each element in an attribute set. The
|
||||||
|
function takes two arguments --- the attribute name and its value
|
||||||
|
--- and returns the new value for the attribute. The result is a
|
||||||
|
new attribute set.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
mapAttrs (name: value: name + "-" + value)
|
||||||
|
{x = "foo"; y = "bar";}
|
||||||
|
=> {x = "x-foo"; y = "y-bar";}
|
||||||
|
*/
|
||||||
|
mapAttrs = f: set:
|
||||||
|
listToAttrs (map (attr: nameValuePair attr (f attr (builtins.getAttr attr set))) (attrNames set));
|
||||||
|
|
||||||
|
|
||||||
|
/* Like `mapAttrs', except that it recursively applies itself to
|
||||||
|
values that attribute sets. Also, the first argument is a *list*
|
||||||
|
of the names of the containing attributes.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
mapAttrsRecursive (path: value: concatStringsSep "-" (path ++ [value]))
|
||||||
|
{ n = { a = "A"; m = { b = "B"; c = "C"; }; }; d = "D"; }
|
||||||
|
=> { n = { a = "n-a-A"; m = { b = "n-m-b-B"; c = "n-m-c-C"; }; }; d = "d-D"; }
|
||||||
|
*/
|
||||||
|
mapAttrsRecursive =
|
||||||
|
let
|
||||||
|
recurse = path: f: set:
|
||||||
|
let
|
||||||
|
g =
|
||||||
|
name: value:
|
||||||
|
if isAttrs value
|
||||||
|
then recurse (path ++ [name]) f value
|
||||||
|
else f (path ++ [name]) value;
|
||||||
|
in mapAttrs g set;
|
||||||
|
in recurse [];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -236,14 +236,8 @@ rec {
|
||||||
# should be renamed to mapAttrsFlatten
|
# should be renamed to mapAttrsFlatten
|
||||||
mapRecordFlatten = f : r : map (attr: f attr (builtins.getAttr attr r) ) (attrNames r);
|
mapRecordFlatten = f : r : map (attr: f attr (builtins.getAttr attr r) ) (attrNames r);
|
||||||
|
|
||||||
# maps a function on each attr value
|
|
||||||
# f = attr : value : ..
|
|
||||||
mapAttrs = f : r : listToAttrs ( mapRecordFlatten (a : v : nv a ( f a v ) ) r);
|
|
||||||
|
|
||||||
# to be used with listToAttrs (_a_ttribute _v_alue)
|
|
||||||
nv = name : value : { inherit name value; };
|
|
||||||
# attribute set containing one attribute
|
# attribute set containing one attribute
|
||||||
nvs = name : value : listToAttrs [ (nv name value) ];
|
nvs = name : value : listToAttrs [ (nameValuePair name value) ];
|
||||||
# adds / replaces an attribute of an attribute set
|
# adds / replaces an attribute of an attribute set
|
||||||
setAttr = set : name : v : set // (nvs name v);
|
setAttr = set : name : v : set // (nvs name v);
|
||||||
|
|
||||||
|
@ -322,8 +316,8 @@ rec {
|
||||||
mergeAttrsByFuncDefaults = foldl mergeAttrByFunc { inherit mergeAttrBy; };
|
mergeAttrsByFuncDefaults = foldl mergeAttrByFunc { inherit mergeAttrBy; };
|
||||||
# sane defaults (same name as attr name so that inherit can be used)
|
# sane defaults (same name as attr name so that inherit can be used)
|
||||||
mergeAttrBy = # { buildInputs = concatList; [...]; passthru = mergeAttr; [..]; }
|
mergeAttrBy = # { buildInputs = concatList; [...]; passthru = mergeAttr; [..]; }
|
||||||
listToAttrs (map (n : nv n lib.concat) [ "buildInputs" "propagatedBuildInputs" "configureFlags" "prePhases" "postAll" ])
|
listToAttrs (map (n : nameValuePair n lib.concat) [ "buildInputs" "propagatedBuildInputs" "configureFlags" "prePhases" "postAll" ])
|
||||||
// listToAttrs (map (n : nv n lib.mergeAttrs) [ "passthru" "meta" "cfg" "flags" ]);
|
// listToAttrs (map (n : nameValuePair n lib.mergeAttrs) [ "passthru" "meta" "cfg" "flags" ]);
|
||||||
|
|
||||||
# returns atribute values as a list
|
# returns atribute values as a list
|
||||||
flattenAttrs = set : map ( attr : builtins.getAttr attr set) (attrNames set);
|
flattenAttrs = set : map ( attr : builtins.getAttr attr set) (attrNames set);
|
||||||
|
@ -332,7 +326,7 @@ rec {
|
||||||
# pick attrs subset_attr_names and apply f
|
# pick attrs subset_attr_names and apply f
|
||||||
subsetmap = f : attrs : subset_attr_names :
|
subsetmap = f : attrs : subset_attr_names :
|
||||||
listToAttrs (fold ( attr : r : if __hasAttr attr attrs
|
listToAttrs (fold ( attr : r : if __hasAttr attr attrs
|
||||||
then r ++ [ ( nv attr ( f (__getAttr attr attrs) ) ) ] else r ) []
|
then r ++ [ ( nameValuePair attr ( f (__getAttr attr attrs) ) ) ] else r ) []
|
||||||
subset_attr_names );
|
subset_attr_names );
|
||||||
|
|
||||||
# prepareDerivationArgs tries to make writing configurable derivations easier
|
# prepareDerivationArgs tries to make writing configurable derivations easier
|
||||||
|
@ -372,7 +366,7 @@ rec {
|
||||||
prepareDerivationArgs = args:
|
prepareDerivationArgs = args:
|
||||||
let args2 = { cfg = {}; flags = {}; } // args;
|
let args2 = { cfg = {}; flags = {}; } // args;
|
||||||
flagName = name : "${name}Support";
|
flagName = name : "${name}Support";
|
||||||
cfgWithDefaults = (listToAttrs (map (n : nv (flagName n) false) (attrNames args2.flags)))
|
cfgWithDefaults = (listToAttrs (map (n : nameValuePair (flagName n) false) (attrNames args2.flags)))
|
||||||
// args2.cfg;
|
// args2.cfg;
|
||||||
opts = flattenAttrs (mapAttrs (a : v :
|
opts = flattenAttrs (mapAttrs (a : v :
|
||||||
let v2 = if (v ? set || v ? unset) then v else { set = v; };
|
let v2 = if (v ? set || v ? unset) then v else { set = v; };
|
||||||
|
|
Loading…
Reference in New Issue