|
|
|
|
@@ -20,16 +20,16 @@ rec {
|
|
|
|
|
(y x);
|
|
|
|
|
defaultMerge = x: y: x // (defaultMergeArg x y);
|
|
|
|
|
foldArgs = merger: f: init: x:
|
|
|
|
|
let arg=(merger init (defaultMergeArg init x));
|
|
|
|
|
let arg = (merger init (defaultMergeArg init x));
|
|
|
|
|
# now add the function with composed args already applied to the final attrs
|
|
|
|
|
base = (setAttrMerge "passthru" {} (f arg)
|
|
|
|
|
( z : z // rec {
|
|
|
|
|
( z: z // rec {
|
|
|
|
|
function = foldArgs merger f arg;
|
|
|
|
|
args = (lib.attrByPath ["passthru" "args"] {} z) // x;
|
|
|
|
|
} ));
|
|
|
|
|
withStdOverrides = base // {
|
|
|
|
|
override = base.passthru.function;
|
|
|
|
|
} ;
|
|
|
|
|
};
|
|
|
|
|
in
|
|
|
|
|
withStdOverrides;
|
|
|
|
|
|
|
|
|
|
@@ -49,16 +49,16 @@ rec {
|
|
|
|
|
#
|
|
|
|
|
# examples: see test cases "res" below;
|
|
|
|
|
overridableDelayableArgs =
|
|
|
|
|
f : # the function applied to the arguments
|
|
|
|
|
initial : # you pass attrs, the functions below are passing a function taking the fix argument
|
|
|
|
|
f: # the function applied to the arguments
|
|
|
|
|
initial: # you pass attrs, the functions below are passing a function taking the fix argument
|
|
|
|
|
let
|
|
|
|
|
takeFixed = if isFunction initial then initial else (fixed : initial); # transform initial to an expression always taking the fixed argument
|
|
|
|
|
tidy = args :
|
|
|
|
|
tidy = args:
|
|
|
|
|
let # apply all functions given in "applyPreTidy" in sequence
|
|
|
|
|
applyPreTidyFun = fold ( n : a : x : n ( a x ) ) lib.id (maybeAttr "applyPreTidy" [] args);
|
|
|
|
|
applyPreTidyFun = fold ( n: a: x: n ( a x ) ) lib.id (maybeAttr "applyPreTidy" [] args);
|
|
|
|
|
in removeAttrs (applyPreTidyFun args) ( ["applyPreTidy"] ++ (maybeAttr "removeAttrs" [] args) ); # tidy up args before applying them
|
|
|
|
|
fun = n : x :
|
|
|
|
|
let newArgs = fixed :
|
|
|
|
|
fun = n: x:
|
|
|
|
|
let newArgs = fixed:
|
|
|
|
|
let args = takeFixed fixed;
|
|
|
|
|
mergeFun = args.${n};
|
|
|
|
|
in if isAttrs x then (mergeFun args x)
|
|
|
|
|
@@ -70,14 +70,14 @@ rec {
|
|
|
|
|
merge = fun "mergeFun";
|
|
|
|
|
replace = fun "keepFun";
|
|
|
|
|
};
|
|
|
|
|
defaultOverridableDelayableArgs = f :
|
|
|
|
|
defaultOverridableDelayableArgs = f:
|
|
|
|
|
let defaults = {
|
|
|
|
|
mergeFun = mergeAttrByFunc; # default merge function. merge strategie (concatenate lists, strings) is given by mergeAttrBy
|
|
|
|
|
keepFun = a : b : { inherit (a) removeAttrs mergeFun keepFun mergeAttrBy; } // b; # even when using replace preserve these values
|
|
|
|
|
keepFun = a: b: { inherit (a) removeAttrs mergeFun keepFun mergeAttrBy; } // b; # even when using replace preserve these values
|
|
|
|
|
applyPreTidy = []; # list of functions applied to args before args are tidied up (usage case : prepareDerivationArgs)
|
|
|
|
|
mergeAttrBy = mergeAttrBy // {
|
|
|
|
|
applyPreTidy = a : b : a ++ b;
|
|
|
|
|
removeAttrs = a : b: a ++ b;
|
|
|
|
|
applyPreTidy = a: b: a ++ b;
|
|
|
|
|
removeAttrs = a: b: a ++ b;
|
|
|
|
|
};
|
|
|
|
|
removeAttrs = ["mergeFun" "keepFun" "mergeAttrBy" "removeAttrs" "fixed" ]; # before applying the arguments to the function make sure these names are gone
|
|
|
|
|
};
|
|
|
|
|
@@ -86,7 +86,7 @@ rec {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# rec { # an example of how composedArgsAndFun can be used
|
|
|
|
|
# a = composedArgsAndFun (x : x) { a = ["2"]; meta = { d = "bar";}; };
|
|
|
|
|
# a = composedArgsAndFun (x: x) { a = ["2"]; meta = { d = "bar";}; };
|
|
|
|
|
# # meta.d will be lost ! It's your task to preserve it (eg using a merge function)
|
|
|
|
|
# b = a.passthru.function { a = [ "3" ]; meta = { d2 = "bar2";}; };
|
|
|
|
|
# # instead of passing/ overriding values you can use a merge function:
|
|
|
|
|
@@ -142,21 +142,21 @@ rec {
|
|
|
|
|
|
|
|
|
|
# Input : attrSet, [[name default] ...], [ [flagname reqs..] ... ]
|
|
|
|
|
# Output : are reqs satisfied? It's asserted.
|
|
|
|
|
checkReqs = attrSet : argList : condList :
|
|
|
|
|
checkReqs = attrSet: argList: condList:
|
|
|
|
|
(
|
|
|
|
|
fold lib.and true
|
|
|
|
|
(map (x: let name = (head x) ; in
|
|
|
|
|
(map (x: let name = (head x); in
|
|
|
|
|
|
|
|
|
|
((checkFlag attrSet name) ->
|
|
|
|
|
(fold lib.and true
|
|
|
|
|
(map (y: let val=(getValue attrSet argList y); in
|
|
|
|
|
(val!=null) && (val!=false))
|
|
|
|
|
(tail x))))) condList)) ;
|
|
|
|
|
(tail x))))) condList));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# This function has O(n^2) performance.
|
|
|
|
|
uniqList = {inputList, acc ? []} :
|
|
|
|
|
let go = xs : acc :
|
|
|
|
|
uniqList = { inputList, acc ? [] }:
|
|
|
|
|
let go = xs: acc:
|
|
|
|
|
if xs == []
|
|
|
|
|
then []
|
|
|
|
|
else let x = head xs;
|
|
|
|
|
@@ -164,20 +164,20 @@ rec {
|
|
|
|
|
in y ++ go (tail xs) (y ++ acc);
|
|
|
|
|
in go inputList acc;
|
|
|
|
|
|
|
|
|
|
uniqListExt = {inputList, outputList ? [],
|
|
|
|
|
getter ? (x : x), compare ? (x: y: x==y)}:
|
|
|
|
|
uniqListExt = { inputList,
|
|
|
|
|
outputList ? [],
|
|
|
|
|
getter ? (x: x),
|
|
|
|
|
compare ? (x: y: x==y) }:
|
|
|
|
|
if inputList == [] then outputList else
|
|
|
|
|
let x=head inputList;
|
|
|
|
|
let x = head inputList;
|
|
|
|
|
isX = y: (compare (getter y) (getter x));
|
|
|
|
|
newOutputList = outputList ++
|
|
|
|
|
(if any isX outputList then [] else [x]);
|
|
|
|
|
in uniqListExt {outputList=newOutputList;
|
|
|
|
|
in uniqListExt { outputList = newOutputList;
|
|
|
|
|
inputList = (tail inputList);
|
|
|
|
|
inherit getter compare;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
condConcat = name: list: checker:
|
|
|
|
|
if list == [] then name else
|
|
|
|
|
if checker (head list) then
|
|
|
|
|
@@ -207,7 +207,7 @@ rec {
|
|
|
|
|
modifySumArgs = f: x: innerModifySumArgs f x {};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
innerClosePropagation = acc : xs :
|
|
|
|
|
innerClosePropagation = acc: xs:
|
|
|
|
|
if xs == []
|
|
|
|
|
then acc
|
|
|
|
|
else let y = head xs;
|
|
|
|
|
@@ -227,31 +227,31 @@ rec {
|
|
|
|
|
closePropagation = list: (uniqList {inputList = (innerClosePropagation [] list);});
|
|
|
|
|
|
|
|
|
|
# calls a function (f attr value ) for each record item. returns a list
|
|
|
|
|
mapAttrsFlatten = f : r : map (attr: f attr r.${attr}) (attrNames r);
|
|
|
|
|
mapAttrsFlatten = f: r: map (attr: f attr r.${attr}) (attrNames r);
|
|
|
|
|
|
|
|
|
|
# attribute set containing one attribute
|
|
|
|
|
nvs = name : value : listToAttrs [ (nameValuePair name value) ];
|
|
|
|
|
nvs = name: value: listToAttrs [ (nameValuePair name value) ];
|
|
|
|
|
# adds / replaces an attribute of an attribute set
|
|
|
|
|
setAttr = set : name : v : set // (nvs name v);
|
|
|
|
|
setAttr = set: name: v: set // (nvs name v);
|
|
|
|
|
|
|
|
|
|
# setAttrMerge (similar to mergeAttrsWithFunc but only merges the values of a particular name)
|
|
|
|
|
# setAttrMerge "a" [] { a = [2];} (x : x ++ [3]) -> { a = [2 3]; }
|
|
|
|
|
# setAttrMerge "a" [] { } (x : x ++ [3]) -> { a = [ 3]; }
|
|
|
|
|
setAttrMerge = name : default : attrs : f :
|
|
|
|
|
# setAttrMerge "a" [] { a = [2];} (x: x ++ [3]) -> { a = [2 3]; }
|
|
|
|
|
# setAttrMerge "a" [] { } (x: x ++ [3]) -> { a = [ 3]; }
|
|
|
|
|
setAttrMerge = name: default: attrs: f:
|
|
|
|
|
setAttr attrs name (f (maybeAttr name default attrs));
|
|
|
|
|
|
|
|
|
|
# Using f = a : b = b the result is similar to //
|
|
|
|
|
# Using f = a: b = b the result is similar to //
|
|
|
|
|
# merge attributes with custom function handling the case that the attribute
|
|
|
|
|
# exists in both sets
|
|
|
|
|
mergeAttrsWithFunc = f : set1 : set2 :
|
|
|
|
|
fold (n: set : if set ? ${n}
|
|
|
|
|
mergeAttrsWithFunc = f: set1: set2:
|
|
|
|
|
fold (n: set: if set ? ${n}
|
|
|
|
|
then setAttr set n (f set.${n} set2.${n})
|
|
|
|
|
else set )
|
|
|
|
|
(set2 // set1) (attrNames set2);
|
|
|
|
|
|
|
|
|
|
# merging two attribute set concatenating the values of same attribute names
|
|
|
|
|
# eg { a = 7; } { a = [ 2 3 ]; } becomes { a = [ 7 2 3 ]; }
|
|
|
|
|
mergeAttrsConcatenateValues = mergeAttrsWithFunc ( a : b : (toList a) ++ (toList b) );
|
|
|
|
|
mergeAttrsConcatenateValues = mergeAttrsWithFunc ( a: b: (toList a) ++ (toList b) );
|
|
|
|
|
|
|
|
|
|
# merges attributes using //, if a name exisits in both attributes
|
|
|
|
|
# an error will be triggered unless its listed in mergeLists
|
|
|
|
|
@@ -262,8 +262,8 @@ rec {
|
|
|
|
|
# ! deprecated, use mergeAttrByFunc instead
|
|
|
|
|
mergeAttrsNoOverride = { mergeLists ? ["buildInputs" "propagatedBuildInputs"],
|
|
|
|
|
overrideSnd ? [ "buildPhase" ]
|
|
|
|
|
} : attrs1 : attrs2 :
|
|
|
|
|
fold (n: set :
|
|
|
|
|
}: attrs1: attrs2:
|
|
|
|
|
fold (n: set:
|
|
|
|
|
setAttr set n ( if set ? ${n}
|
|
|
|
|
then # merge
|
|
|
|
|
if elem n mergeLists # attribute contains list, merge them by concatenating
|
|
|
|
|
@@ -286,14 +286,14 @@ rec {
|
|
|
|
|
# { mergeAttrsBy = [...]; buildInputs = [ a b c d ]; }
|
|
|
|
|
# is used by prepareDerivationArgs, defaultOverridableDelayableArgs and can be used when composing using
|
|
|
|
|
# foldArgs, composedArgsAndFun or applyAndFun. Example: composableDerivation in all-packages.nix
|
|
|
|
|
mergeAttrByFunc = x : y :
|
|
|
|
|
mergeAttrByFunc = x: y:
|
|
|
|
|
let
|
|
|
|
|
mergeAttrBy2 = { mergeAttrBy=lib.mergeAttrs; }
|
|
|
|
|
mergeAttrBy2 = { mergeAttrBy = lib.mergeAttrs; }
|
|
|
|
|
// (maybeAttr "mergeAttrBy" {} x)
|
|
|
|
|
// (maybeAttr "mergeAttrBy" {} y); in
|
|
|
|
|
fold lib.mergeAttrs {} [
|
|
|
|
|
x y
|
|
|
|
|
(mapAttrs ( a : v : # merge special names using given functions
|
|
|
|
|
(mapAttrs ( a: v: # merge special names using given functions
|
|
|
|
|
if x ? ${a}
|
|
|
|
|
then if y ? ${a}
|
|
|
|
|
then v x.${a} y.${a} # both have attr, use merge func
|
|
|
|
|
@@ -313,7 +313,7 @@ rec {
|
|
|
|
|
#
|
|
|
|
|
# This function is best explained by an example:
|
|
|
|
|
#
|
|
|
|
|
# {version ? "2.x"} :
|
|
|
|
|
# {version ? "2.x"}:
|
|
|
|
|
#
|
|
|
|
|
# mkDerivation (mergeAttrsByVersion "package-name" version
|
|
|
|
|
# { # version specific settings
|
|
|
|
|
@@ -346,21 +346,24 @@ rec {
|
|
|
|
|
# See misc.nix -> versionedDerivation
|
|
|
|
|
# discussion: nixpkgs: pull/310
|
|
|
|
|
mergeAttrsByVersion = name: version: attrsByVersion: base:
|
|
|
|
|
mergeAttrsByFuncDefaultsClean [ { name = "${name}-${version}"; } base (maybeAttr version (throw "bad version ${version} for ${name}") attrsByVersion)];
|
|
|
|
|
mergeAttrsByFuncDefaultsClean [ { name = "${name}-${version}"; }
|
|
|
|
|
base
|
|
|
|
|
(maybeAttr version (throw "bad version ${version} for ${name}") attrsByVersion)
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
# sane defaults (same name as attr name so that inherit can be used)
|
|
|
|
|
mergeAttrBy = # { buildInputs = concatList; [...]; passthru = mergeAttr; [..]; }
|
|
|
|
|
listToAttrs (map (n : nameValuePair n lib.concat)
|
|
|
|
|
listToAttrs (map (n: nameValuePair n lib.concat)
|
|
|
|
|
[ "nativeBuildInputs" "buildInputs" "propagatedBuildInputs" "configureFlags" "prePhases" "postAll" "patches" ])
|
|
|
|
|
// listToAttrs (map (n : nameValuePair n lib.mergeAttrs) [ "passthru" "meta" "cfg" "flags" ])
|
|
|
|
|
// listToAttrs (map (n : nameValuePair n (a: b: "${a}\n${b}") ) [ "preConfigure" "postInstall" ])
|
|
|
|
|
// listToAttrs (map (n: nameValuePair n lib.mergeAttrs) [ "passthru" "meta" "cfg" "flags" ])
|
|
|
|
|
// listToAttrs (map (n: nameValuePair n (a: b: "${a}\n${b}") ) [ "preConfigure" "postInstall" ])
|
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
# prepareDerivationArgs tries to make writing configurable derivations easier
|
|
|
|
|
# example:
|
|
|
|
|
# prepareDerivationArgs {
|
|
|
|
|
# mergeAttrBy = {
|
|
|
|
|
# myScript = x : y : x ++ "\n" ++ y;
|
|
|
|
|
# myScript = x: y: x ++ "\n" ++ y;
|
|
|
|
|
# };
|
|
|
|
|
# cfg = {
|
|
|
|
|
# readlineSupport = true;
|
|
|
|
|
@@ -392,10 +395,10 @@ rec {
|
|
|
|
|
# TODO use args.mergeFun here as well?
|
|
|
|
|
prepareDerivationArgs = args:
|
|
|
|
|
let args2 = { cfg = {}; flags = {}; } // args;
|
|
|
|
|
flagName = name : "${name}Support";
|
|
|
|
|
cfgWithDefaults = (listToAttrs (map (n : nameValuePair (flagName n) false) (attrNames args2.flags)))
|
|
|
|
|
flagName = name: "${name}Support";
|
|
|
|
|
cfgWithDefaults = (listToAttrs (map (n: nameValuePair (flagName n) false) (attrNames args2.flags)))
|
|
|
|
|
// args2.cfg;
|
|
|
|
|
opts = attrValues (mapAttrs (a : v :
|
|
|
|
|
opts = attrValues (mapAttrs (a: v:
|
|
|
|
|
let v2 = if v ? set || v ? unset then v else { set = v; };
|
|
|
|
|
n = if cfgWithDefaults.${flagName a} then "set" else "unset";
|
|
|
|
|
attr = maybeAttr n {} v2; in
|
|
|
|
|
|