summary refs log tree commit diff
path: root/lib/customisation.nix
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2013-10-10 13:28:21 +0200
committerEelco Dolstra <eelco.dolstra@logicblox.com>2013-10-10 13:28:21 +0200
commit5fef92c4a0c91153e3edac3a61a232581765074a (patch)
tree291d684d0ef71e200e6d8ab5c33fc1aca467cbb3 /lib/customisation.nix
parent2a537fb369d1479748fe233261eaadfa5c2fa930 (diff)
downloadnixpkgs-5fef92c4a0c91153e3edac3a61a232581765074a.tar
nixpkgs-5fef92c4a0c91153e3edac3a61a232581765074a.tar.gz
nixpkgs-5fef92c4a0c91153e3edac3a61a232581765074a.tar.bz2
nixpkgs-5fef92c4a0c91153e3edac3a61a232581765074a.tar.lz
nixpkgs-5fef92c4a0c91153e3edac3a61a232581765074a.tar.xz
nixpkgs-5fef92c4a0c91153e3edac3a61a232581765074a.tar.zst
nixpkgs-5fef92c4a0c91153e3edac3a61a232581765074a.zip
Move pkgs/lib/ to lib/
Diffstat (limited to 'lib/customisation.nix')
-rw-r--r--lib/customisation.nix116
1 files changed, 116 insertions, 0 deletions
diff --git a/lib/customisation.nix b/lib/customisation.nix
new file mode 100644
index 00000000000..bfa61169efb
--- /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;
+}