From 5fef92c4a0c91153e3edac3a61a232581765074a Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 10 Oct 2013 13:28:21 +0200 Subject: Move pkgs/lib/ to lib/ --- lib/customisation.nix | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 lib/customisation.nix (limited to 'lib/customisation.nix') diff --git a/lib/customisation.nix b/lib/customisation.nix new file mode 100644 index 0000000000000..bfa61169efb1e --- /dev/null +++ b/lib/customisation.nix @@ -0,0 +1,116 @@ +let lib = import ./default.nix; + inherit (builtins) getAttr attrNames isFunction; + +in + +rec { + + + /* `overrideDerivation drv f' takes a derivation (i.e., the result + of a call to the builtin function `derivation') and returns a new + derivation in which the attributes of the original are overriden + according to the function `f'. The function `f' is called with + the original derivation attributes. + + `overrideDerivation' allows certain "ad-hoc" customisation + scenarios (e.g. in ~/.nixpkgs/config.nix). For instance, if you + want to "patch" the derivation returned by a package function in + Nixpkgs to build another version than what the function itself + provides, you can do something like this: + + mySed = overrideDerivation pkgs.gnused (oldAttrs: { + name = "sed-4.2.2-pre"; + src = fetchurl { + url = ftp://alpha.gnu.org/gnu/sed/sed-4.2.2-pre.tar.bz2; + sha256 = "11nq06d131y4wmf3drm0yk502d2xc6n5qy82cg88rb9nqd2lj41k"; + }; + patches = []; + }); + + For another application, see build-support/vm, where this + function is used to build arbitrary derivations inside a QEMU + virtual machine. */ + + overrideDerivation = drv: f: + let + newDrv = derivation (drv.drvAttrs // (f drv)); + in addPassthru newDrv ( + { meta = drv.meta or {}; + passthru = if drv ? passthru then drv.passthru else {}; + } + // + (drv.passthru or {}) + // + (if (drv ? crossDrv && drv ? nativeDrv) + then { + crossDrv = overrideDerivation drv.crossDrv f; + nativeDrv = overrideDerivation drv.nativeDrv f; + } + else { })); + + + # usage: (you can use override multiple times) + # let d = makeOverridable stdenv.mkDerivation { name = ..; buildInputs; } + # noBuildInputs = d.override { buildInputs = []; } + # additionalBuildInputs = d.override ( args : args // { buildInputs = args.buildInputs ++ [ additional ]; } ) + makeOverridable = f: origArgs: + let + ff = f origArgs; + in + if builtins.isAttrs ff then (ff // + { override = newArgs: + makeOverridable f (origArgs // (if builtins.isFunction newArgs then newArgs origArgs else newArgs)); + deepOverride = newArgs: + makeOverridable f (lib.overrideExisting (lib.mapAttrs (deepOverrider newArgs) origArgs) newArgs); + }) + else ff; + + deepOverrider = newArgs: name: x: if builtins.isAttrs x then ( + if x ? deepOverride then (x.deepOverride newArgs) else + if x ? override then (x.override newArgs) else + x) else x; + + + /* Call the package function in the file `fn' with the required + arguments automatically. The function is called with the + arguments `args', but any missing arguments are obtained from + `autoArgs'. This function is intended to be partially + parameterised, e.g., + + callPackage = callPackageWith pkgs; + pkgs = { + libfoo = callPackage ./foo.nix { }; + libbar = callPackage ./bar.nix { }; + }; + + If the `libbar' function expects an argument named `libfoo', it is + automatically passed as an argument. Overrides or missing + arguments can be supplied in `args', e.g. + + libbar = callPackage ./bar.nix { + libfoo = null; + enableX11 = true; + }; + */ + callPackageWith = autoArgs: fn: args: + let f = if builtins.isFunction fn then fn else import fn; in + makeOverridable f ((builtins.intersectAttrs (builtins.functionArgs f) autoArgs) // args); + + /* Add attributes to each output of a derivation without changing the derivation itself */ + addPassthru = drv: passthru: + let + outputs = drv.outputs or [ "out" ]; + + commonAttrs = drv // (builtins.listToAttrs outputsList) // + ({ all = map (x: x.value) outputsList; }) // passthru; + + outputToAttrListElement = outputName: + { name = outputName; + value = commonAttrs // { + inherit (builtins.getAttr outputName drv) outPath drvPath type outputName; + }; + }; + + outputsList = map outputToAttrListElement outputs; + in builtins.getAttr drv.outputName commonAttrs; +} -- cgit 1.4.1