From d8e1f6c976f851f10cce0c09d37a2cb5b62df345 Mon Sep 17 00:00:00 2001 From: Marc Weber Date: Tue, 2 Dec 2008 12:26:53 +0000 Subject: [PATCH] adding lib function composableDerivation providing easy setups of flags and configurations for derivations. configuration is passed via passthru automatically, additional names can be merged with final attrs in an automatic sensible way even supporting fix. fun and funMerge idea by Michael Raskin svn path=/nixpkgs/trunk/; revision=13546 --- pkgs/lib/default.nix | 21 +++++++++++++++++++-- pkgs/top-level/all-packages.nix | 14 ++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/pkgs/lib/default.nix b/pkgs/lib/default.nix index 01aecfeae8cd..445dcd8ffd0a 100644 --- a/pkgs/lib/default.nix +++ b/pkgs/lib/default.nix @@ -43,7 +43,24 @@ rec { let arg=(merger init (defaultMergeArg init x)); in # now add the function with composed args already applied to the final attrs setAttrMerge "passthru" {} (f arg) ( x : x // { function = foldArgs merger f arg; } ); - + + # returns f x // { passthru.fun = y : f (merge x y); } while preserving other passthru names. + # example: let ex = applyAndFun (x : removeAttrs x ["fixed"]) (mergeOrApply mergeAttr) {name = 6;}; + # usage1 = ex.passthru.fun { name = 7; }; # result: { name = 7;} + # usage2 = ex.passthru.fun (a: a // {name = __add a.name 1; }); # result: { a = 7; } + # fix usage: + # usage3a = ex.passthru.fun (a: a // {name2 = a.fixed.toBePassed; }); # usage3a will fail because toBePassed is not yet given + # usage3b usage3a.passthru.fun { toBePassed = "foo";}; # result { name = 7; name2 = "foo"; toBePassed = "foo"; fixed = ; } + applyAndFun = f : merge : x : assert (__isAttrs x || __isFunction x); + let takeFix = if (__isFunction x) then x else (attr: merge attr x); in + setAttrMerge "passthru" {} (fix (fixed : f (takeFix {inherit fixed;}))) + ( y : y // + { + fun = z : applyAndFun f merge (fixed: merge (takeFix fixed) z); + funMerge = z : applyAndFun f merge (fixed: let e = takeFix fixed; in e // merge e z); + } ); + mergeOrApply = merge : x : y : if (__isFunction y) then y x else merge x y; + # rec { # an example of how composedArgsAndFun can be used # 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) @@ -770,7 +787,7 @@ rec { else throw "assertion of flag ${a} of derivation ${args.name} failed" ) args2.flags ); in removeAttrs - (fold (mergeOrApply mergeAttrByFunc) {} ([args] ++ opts)) + (mergeAttrsByFunc ([args] ++ opts)) ["flags" "cfg" "mergeAttrBy" "fixed" ]; # fixed may be passed as fix argument or such # supportFlag functions for convinience sFlagEnable = { name, buildInputs ? [], propagatedBuildInputs ? [] } : { diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 00744531e8a0..e7bf2abd2c18 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -474,6 +474,20 @@ let inherit pkgs; }; + # see new python derivations for example.. + # You should be able to override anything you like easily + composableDerivation = { + # modify args before applying stdenv.mkDerivation, this should remove at least attrs removeAttrsBy + f ? lib.prepareDerivationArgs, + stdenv ? pkgs.stdenv, + # initial set of arguments to be passed to stdenv.mkDerivation passing prepareDerivationArgs by default + initial ? {}, + # example func : (x: x // { x.buildInputs ++ ["foo"] }), but see mergeAttrByFunc which does this for you + merge ? (lib.mergeOrApply lib.mergeAttrByFunc) + }: lib.applyAndFun + (args: stdenv.mkDerivation (f args)) + merge + (merge { inherit (lib) mergeAttrBy; } initial); ### TOOLS