summaryrefslogtreecommitdiffstats
path: root/lib
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
parent2a537fb369d1479748fe233261eaadfa5c2fa930 (diff)
Move pkgs/lib/ to lib/
Diffstat (limited to 'lib')
-rw-r--r--lib/attrsets.nix329
-rw-r--r--lib/composable-derivation.nix54
-rw-r--r--lib/customisation.nix116
-rw-r--r--lib/debug.nix119
-rw-r--r--lib/default.nix31
-rw-r--r--lib/licenses.nix235
-rw-r--r--lib/lists.nix235
-rw-r--r--lib/maintainers.nix65
-rw-r--r--lib/meta.nix48
-rw-r--r--lib/misc.nix431
-rw-r--r--lib/modules.nix380
-rw-r--r--lib/options.nix315
-rw-r--r--lib/platforms.nix16
-rw-r--r--lib/properties.nix464
-rw-r--r--lib/sources.nix29
-rw-r--r--lib/strings-with-deps.nix78
-rw-r--r--lib/strings.nix190
-rw-r--r--lib/systems.nix126
-rw-r--r--lib/tests.nix113
-rw-r--r--lib/trivial.nix38
-rw-r--r--lib/types.nix226
21 files changed, 3638 insertions, 0 deletions
diff --git a/lib/attrsets.nix b/lib/attrsets.nix
new file mode 100644
index 000000000000..01d51779c809
--- /dev/null
+++ b/lib/attrsets.nix
@@ -0,0 +1,329 @@
+# Operations on attribute sets.
+
+with {
+ inherit (builtins) head tail isString;
+ inherit (import ./trivial.nix) or;
+ inherit (import ./default.nix) fold;
+ inherit (import ./strings.nix) concatStringsSep;
+ inherit (import ./lists.nix) concatMap concatLists all deepSeqList;
+ inherit (import ./misc.nix) maybeAttr;
+};
+
+rec {
+ inherit (builtins) attrNames listToAttrs hasAttr isAttrs getAttr;
+
+
+ /* Return an attribute from nested attribute sets. For instance
+ ["x" "y"] applied to some set e returns e.x.y, if it exists. The
+ default value is returned otherwise. */
+ attrByPath = attrPath: default: e:
+ let attr = head attrPath;
+ in
+ if attrPath == [] then e
+ else if builtins ? hasAttr && hasAttr attr e
+ then attrByPath (tail attrPath) default (getAttr attr e)
+ else default;
+
+
+ /* Return nested attribute set in which an attribute is set. For instance
+ ["x" "y"] applied with some value v returns `x.y = v;' */
+ setAttrByPath = attrPath: value:
+ if attrPath == [] then value
+ else listToAttrs [(
+ nameValuePair (head attrPath) (setAttrByPath (tail attrPath) value)
+ )];
+
+
+ getAttrFromPath = attrPath: set:
+ let errorMsg = "cannot find attribute `" + concatStringsSep "." attrPath + "'";
+ in attrByPath attrPath (abort errorMsg) set;
+
+
+ /* Return the specified attributes from a set.
+
+ Example:
+ attrVals ["a" "b" "c"] as
+ => [as.a as.b as.c]
+ */
+ attrVals = nameList: set:
+ map (x: 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: concatLists (map (s: if hasAttr attr s then [(getAttr attr s)] else []) l);
+
+
+ /* Filter an attribute set by removing all attributes for which the
+ given predicate return false.
+
+ Example:
+ filterAttrs (n: v: n == "foo") { foo = 1; bar = 2; }
+ => { foo = 1; }
+ */
+ filterAttrs = pred: set:
+ listToAttrs (fold (n: ys: let v = getAttr n set; in if pred n v then [(nameValuePair n v)] ++ ys else ys) [] (attrNames set));
+
+
+ /* foldAttrs: apply fold functions to values grouped by key. Eg accumulate values as list:
+ foldAttrs (n: a: [n] ++ a) [] [{ a = 2; } { a = 3; }]
+ => { a = [ 2 3 ]; }
+ */
+ foldAttrs = op: nul: list_of_attrs:
+ fold (n: a:
+ fold (name: o:
+ o // (listToAttrs [{inherit name; value = op (getAttr name n) (maybeAttr name nul a); }])
+ ) a (attrNames n)
+ ) {} list_of_attrs;
+
+
+ /* Recursively collect sets that verify a given predicate named `pred'
+ from the set `attrs'. The recursion is stopped when the predicate is
+ verified.
+
+ Type:
+ collect ::
+ (AttrSet -> Bool) -> AttrSet -> AttrSet
+
+ Example:
+ collect builtins.isList { a = { b = ["b"]; }; c = [1]; }
+ => [["b"] [1]]
+
+ collect (x: x ? outPath)
+ { a = { outPath = "a/"; }; b = { outPath = "b/"; }; }
+ => [{ outPath = "a/"; } { outPath = "b/"; }]
+ */
+ collect = pred: attrs:
+ if pred attrs then
+ [ attrs ]
+ else if builtins.isAttrs attrs then
+ concatMap (collect pred) (attrValues attrs)
+ else
+ [];
+
+
+ /* 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 (getAttr attr set))) (attrNames set));
+
+
+ /* Like `mapAttrs', but allows the name of each attribute to be
+ changed in addition to the value. The applied function should
+ return both the new name and value as a `nameValuePair'.
+
+ Example:
+ mapAttrs' (name: value: nameValuePair ("foo_" + name) ("bar-" + value))
+ { x = "a"; y = "b"; }
+ => { foo_x = "bar-a"; foo_y = "bar-b"; }
+ */
+ mapAttrs' = f: set:
+ listToAttrs (map (attr: f attr (getAttr attr set)) (attrNames set));
+
+
+ /* Call a function for each attribute in the given set and return
+ the result in a list.
+
+ Example:
+ mapAttrsToList (name: value: name + value)
+ { x = "a"; y = "b"; }
+ => [ "xa" "yb" ]
+ */
+ mapAttrsToList = f: attrs:
+ map (name: f name (getAttr name attrs)) (attrNames attrs);
+
+
+ /* Like `mapAttrs', except that it recursively applies itself to
+ attribute sets. Also, the first argument of the argument
+ function is a *list* of the names of the containing attributes.
+
+ Type:
+ mapAttrsRecursive ::
+ ([String] -> a -> b) -> AttrSet -> AttrSet
+
+ 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 = mapAttrsRecursiveCond (as: true);
+
+
+ /* Like `mapAttrsRecursive', but it takes an additional predicate
+ function that tells it whether to recursive into an attribute
+ set. If it returns false, `mapAttrsRecursiveCond' does not
+ recurse, but does apply the map function. It is returns true, it
+ does recurse, and does not apply the map function.
+
+ Type:
+ mapAttrsRecursiveCond ::
+ (AttrSet -> Bool) -> ([String] -> a -> b) -> AttrSet -> AttrSet
+
+ Example:
+ # To prevent recursing into derivations (which are attribute
+ # sets with the attribute "type" equal to "derivation"):
+ mapAttrsRecursiveCond
+ (as: !(as ? "type" && as.type == "derivation"))
+ (x: ... do something ...)
+ attrs
+ */
+ mapAttrsRecursiveCond = cond: f: set:
+ let
+ recurse = path: set:
+ let
+ g =
+ name: value:
+ if isAttrs value && cond value
+ then recurse (path ++ [name]) value
+ else f (path ++ [name]) value;
+ in mapAttrs g set;
+ in recurse [] set;
+
+
+ /* Generate an attribute set by mapping a function over a list of
+ attribute names.
+
+ Example:
+ genAttrs [ "foo" "bar" ] (name: "x_" + name)
+ => { foo = "x_foo"; bar = "x_bar"; }
+ */
+ genAttrs = names: f:
+ listToAttrs (map (n: nameValuePair n (f n)) names);
+
+
+ /* Check whether the argument is a derivation. */
+ isDerivation = x: isAttrs x && x ? type && x.type == "derivation";
+
+
+ /* If the Boolean `cond' is true, return the attribute set `as',
+ otherwise an empty attribute set. */
+ optionalAttrs = cond: as: if cond then as else {};
+
+
+ /* Merge sets of attributes and use the function f to merge attributes
+ values. */
+ zipAttrsWithNames = names: f: sets:
+ listToAttrs (map (name: {
+ inherit name;
+ value = f name (catAttrs name sets);
+ }) names);
+
+ # implentation note: Common names appear multiple times in the list of
+ # names, hopefully this does not affect the system because the maximal
+ # laziness avoid computing twice the same expression and listToAttrs does
+ # not care about duplicated attribute names.
+ zipAttrsWith = f: sets: zipWithNames (concatMap attrNames sets) f sets;
+
+ zipAttrs = zipAttrsWith (name: values: values);
+
+ /* backward compatibility */
+ zipWithNames = zipAttrsWithNames;
+ zip = builtins.trace "lib.zip is deprecated, use lib.zipAttrsWith instead" zipAttrsWith;
+
+
+ /* Does the same as the update operator '//' except that attributes are
+ merged until the given pedicate is verified. The predicate should
+ accept 3 arguments which are the path to reach the attribute, a part of
+ the first attribute set and a part of the second attribute set. When
+ the predicate is verified, the value of the first attribute set is
+ replaced by the value of the second attribute set.
+
+ Example:
+ recursiveUpdateUntil (path: l: r: path == ["foo"]) {
+ # first attribute set
+ foo.bar = 1;
+ foo.baz = 2;
+ bar = 3;
+ } {
+ #second attribute set
+ foo.bar = 1;
+ foo.quz = 2;
+ baz = 4;
+ }
+
+ returns: {
+ foo.bar = 1; # 'foo.*' from the second set
+ foo.quz = 2; #
+ bar = 3; # 'bar' from the first set
+ baz = 4; # 'baz' from the second set
+ }
+
+ */
+ recursiveUpdateUntil = pred: lhs: rhs:
+ let f = attrPath:
+ zipAttrsWith (n: values:
+ if tail values == []
+ || pred attrPath (head (tail values)) (head values) then
+ head values
+ else
+ f (attrPath ++ [n]) values
+ );
+ in f [] [rhs lhs];
+
+ /* A recursive variant of the update operator ‘//’. The recusion
+ stops when one of the attribute values is not an attribute set,
+ in which case the right hand side value takes precedence over the
+ left hand side value.
+
+ Example:
+ recursiveUpdate {
+ boot.loader.grub.enable = true;
+ boot.loader.grub.device = "/dev/hda";
+ } {
+ boot.loader.grub.device = "";
+ }
+
+ returns: {
+ boot.loader.grub.enable = true;
+ boot.loader.grub.device = "";
+ }
+
+ */
+ recursiveUpdate = lhs: rhs:
+ recursiveUpdateUntil (path: lhs: rhs:
+ !(isAttrs lhs && isAttrs rhs)
+ ) lhs rhs;
+
+ matchAttrs = pattern: attrs:
+ fold or false (attrValues (zipAttrsWithNames (attrNames pattern) (n: values:
+ let pat = head values; val = head (tail values); in
+ if length values == 1 then false
+ else if isAttrs pat then isAttrs val && matchAttrs head values
+ else pat == val
+ ) [pattern attrs]));
+
+ # override only the attributes that are already present in the old set
+ # useful for deep-overriding
+ overrideExisting = old: new:
+ old // listToAttrs (map (attr: nameValuePair attr (attrByPath [attr] (getAttr attr old) new)) (attrNames old));
+
+ deepSeqAttrs = x: y: deepSeqList (attrValues x) y;
+}
diff --git a/lib/composable-derivation.nix b/lib/composable-derivation.nix
new file mode 100644
index 000000000000..1099bd152bf6
--- /dev/null
+++ b/lib/composable-derivation.nix
@@ -0,0 +1,54 @@
+{lib, pkgs} :
+let inherit (lib) nv nvs; in
+{
+ # see for example:
+ # - development/interpreters/php_configurable/default.nix
+ # - .. search composableDerivation in all-packages.nix ..
+ #
+ # You should be able to override anything you like easily
+ # grep the mailinglist by title "python proposal" (dec 08)
+ # -> http://mail.cs.uu.nl/pipermail/nix-dev/2008-December/001571.html
+ # to see why this got complicated when using all its features
+ # TODO add newer example using new syntax (kernel derivation proposal -> mailinglist)
+ composableDerivation = {
+ mkDerivation ? pkgs.stdenv.mkDerivation,
+
+ # list of functions to be applied before defaultOverridableDelayableArgs removes removeAttrs names
+ # prepareDerivationArgs handles derivation configurations
+ applyPreTidy ? [ lib.prepareDerivationArgs ],
+
+ # consider adding addtional elements by derivation.merge { removeAttrs = ["elem"]; };
+ removeAttrs ? ["cfg" "flags"]
+
+ }: (lib.defaultOverridableDelayableArgs ( a: mkDerivation a)
+ {
+ inherit applyPreTidy removeAttrs;
+ }).merge;
+
+ # some utility functions
+ # use this function to generate flag attrs for prepareDerivationArgs
+ # E nable D isable F eature
+ edf = {name, feat ? name, enable ? {}, disable ? {} , value ? ""}:
+ nvs name {
+ set = {
+ configureFlags = ["--enable-${feat}${if value == "" then "" else "="}${value}"];
+ } // enable;
+ unset = {
+ configureFlags = ["--disable-${feat}"];
+ } // disable;
+ };
+
+ # same for --with and --without-
+ # W ith or W ithout F eature
+ wwf = {name, feat ? name, enable ? {}, disable ? {}, value ? ""}:
+ nvs name {
+ set = enable // {
+ configureFlags = ["--with-${feat}${if value == "" then "" else "="}${value}"]
+ ++ lib.maybeAttr "configureFlags" [] enable;
+ };
+ unset = disable // {
+ configureFlags = ["--without-${feat}"]
+ ++ lib.maybeAttr "configureFlags" [] disable;
+ };
+ };
+}
diff --git a/lib/customisation.nix b/lib/customisation.nix
new file mode 100644
index 000000000000..bfa61169efb1
--- /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;
+}
diff --git a/lib/debug.nix b/lib/debug.nix
new file mode 100644
index 000000000000..d627bc861abb
--- /dev/null
+++ b/lib/debug.nix
@@ -0,0 +1,119 @@
+let lib = import ./default.nix;
+
+inherit (builtins) trace attrNamesToStr isAttrs isFunction isList isInt
+ isString isBool head substring attrNames;
+
+inherit (lib) all id mapAttrsFlatten elem;
+
+in
+
+rec {
+
+
+ # Wrapper aroung the primop `addErrorContext', which shouldn't used
+ # directly. It evaluates and returns `val', but if an evaluation
+ # error occurs, the text in `msg' is added to the error context
+ # (stack trace) printed by Nix.
+ addErrorContext =
+ if builtins ? addErrorContext
+ then builtins.addErrorContext
+ else msg: val: val;
+
+ addErrorContextToAttrs = lib.mapAttrs (a : v : lib.addErrorContext "while evaluating ${a}" v);
+
+
+ traceVal = if builtins ? trace then x: (builtins.trace x x) else x: x;
+ traceXMLVal = if builtins ? trace then x: (builtins.trace (builtins.toXML x) x) else x: x;
+ traceXMLValMarked = str: if builtins ? trace then x: (builtins.trace ( str + builtins.toXML x) x) else x: x;
+
+ # this can help debug your code as well - designed to not produce thousands of lines
+ traceShowVal = x : trace (showVal x) x;
+ traceShowValMarked = str: x: trace (str + showVal x) x;
+ attrNamesToStr = a : lib.concatStringsSep "; " (map (x : "${x}=") (attrNames a));
+ showVal = x :
+ if isAttrs x then
+ if x ? outPath then "x is a derivation, name ${if x ? name then x.name else "<no name>"}, { ${attrNamesToStr x} }"
+ else "x is attr set { ${attrNamesToStr x} }"
+ else if isFunction x then "x is a function"
+ else if x == [] then "x is an empty list"
+ else if isList x then "x is a list, first element is: ${showVal (head x)}"
+ else if x == true then "x is boolean true"
+ else if x == false then "x is boolean false"
+ else if x == null then "x is null"
+ else if isInt x then "x is an integer `${toString x}'"
+ else if isString x then "x is a string `${substring 0 50 x}...'"
+ else "x is probably a path `${substring 0 50 (toString x)}...'";
+
+ # trace the arguments passed to function and its result
+ # maybe rewrite these functions in a traceCallXml like style. Then one function is enough
+ traceCall = n : f : a : let t = n2 : x : traceShowValMarked "${n} ${n2}:" x; in t "result" (f (t "arg 1" a));
+ traceCall2 = n : f : a : b : let t = n2 : x : traceShowValMarked "${n} ${n2}:" x; in t "result" (f (t "arg 1" a) (t "arg 2" b));
+ traceCall3 = n : f : a : b : c : let t = n2 : x : traceShowValMarked "${n} ${n2}:" x; in t "result" (f (t "arg 1" a) (t "arg 2" b) (t "arg 3" c));
+
+ traceValIfNot = c: x:
+ if c x then true else trace (showVal x) false;
+
+ /* Evaluate a set of tests. A test is an attribute set {expr,
+ expected}, denoting an expression and its expected result. The
+ result is a list of failed tests, each represented as {name,
+ expected, actual}, denoting the attribute name of the failing
+ test and its expected and actual results. Used for regression
+ testing of the functions in lib; see tests.nix for an example.
+ Only tests having names starting with "test" are run.
+ Add attr { tests = ["testName"]; } to run these test only
+ */
+ runTests = tests: lib.concatLists (lib.attrValues (lib.mapAttrs (name: test:
+ let testsToRun = if tests ? tests then tests.tests else [];
+ in if (substring 0 4 name == "test" || elem name testsToRun)
+ && ((testsToRun == []) || elem name tests.tests)
+ && (test.expr != test.expected)
+
+ then [ { inherit name; expected = test.expected; result = test.expr; } ]
+ else [] ) tests));
+
+ # create a test assuming that list elements are true
+ # usage: { testX = allTrue [ true ]; }
+ testAllTrue = expr : { inherit expr; expected = map (x: true) expr; };
+
+ # evaluate everything once so that errors will occur earlier
+ # hacky: traverse attrs by adding a dummy
+ # ignores functions (should this behavior change?) See strictf
+ #
+ # Note: This should be a primop! Something like seq of haskell would be nice to
+ # have as well. It's used fore debugging only anyway
+ strict = x :
+ let
+ traverse = x :
+ if isString x then true
+ else if isAttrs x then
+ if x ? outPath then true
+ else all id (mapAttrsFlatten (n: traverse) x)
+ else if isList x then
+ all id (map traverse x)
+ else if isBool x then true
+ else if isFunction x then true
+ else if isInt x then true
+ else if x == null then true
+ else true; # a (store) path?
+ in if traverse x then x else throw "else never reached";
+
+ # example: (traceCallXml "myfun" id 3) will output something like
+ # calling myfun arg 1: 3 result: 3
+ # this forces deep evaluation of all arguments and the result!
+ # note: if result doesn't evaluate you'll get no trace at all (FIXME)
+ # args should be printed in any case
+ traceCallXml = a:
+ if !isInt a then
+ traceCallXml 1 "calling ${a}\n"
+ else
+ let nr = a;
+ in (str: expr:
+ if isFunction expr then
+ (arg:
+ traceCallXml (builtins.add 1 nr) "${str}\n arg ${builtins.toString nr} is \n ${builtins.toXML (strict arg)}" (expr arg)
+ )
+ else
+ let r = strict expr;
+ in builtins.trace "${str}\n result:\n${builtins.toXML r}" r
+ );
+}
diff --git a/lib/default.nix b/lib/default.nix
new file mode 100644
index 000000000000..dea82ee077eb
--- /dev/null
+++ b/lib/default.nix
@@ -0,0 +1,31 @@
+let
+
+ trivial = import ./trivial.nix;
+ lists = import ./lists.nix;
+ strings = import ./strings.nix;
+ stringsWithDeps = import ./strings-with-deps.nix;
+ attrsets = import ./attrsets.nix;
+ sources = import ./sources.nix;
+ modules = import ./modules.nix;
+ options = import ./options.nix;
+ properties = import ./properties.nix;
+ types = import ./types.nix;
+ meta = import ./meta.nix;
+ debug = import ./debug.nix;
+ misc = import ./misc.nix;
+ maintainers = import ./maintainers.nix;
+ platforms = import ./platforms.nix;
+ systems = import ./systems.nix;
+ customisation = import ./customisation.nix;
+ licenses = import ./licenses.nix;
+
+in
+ { inherit trivial lists strings stringsWithDeps attrsets sources options
+ properties modules types meta debug maintainers licenses platforms systems;
+ }
+ # !!! don't include everything at top-level; perhaps only the most
+ # commonly used functions.
+ // trivial // lists // strings // stringsWithDeps // attrsets // sources
+ // properties // options // types // meta // debug // misc // modules
+ // systems
+ // customisation
diff --git a/lib/licenses.nix b/lib/licenses.nix
new file mode 100644
index 000000000000..55517c5e1e5e
--- /dev/null
+++ b/lib/licenses.nix
@@ -0,0 +1,235 @@
+{
+ /* License identifiers loosely based on: http://fedoraproject.org/wiki/Licensing
+ * If you cannot find your license here, then look for a similar license or
+ * add it to this list. The URL mentioned above is a good source for inspiration.
+ */
+
+ artistic2 = {
+ shortName = "Artistic 2.0";
+ fullName = "Artistic 2.0";
+ url = "http://opensource.org/licenses/artistic-license-2.0.php";
+ };
+
+ agpl3 = {
+ shortName = "AGPLv3";
+ fullName = "GNU Affero General Public License version 3 only";
+ url = https://www.gnu.org/licenses/agpl.html;
+ };
+
+ agpl3Plus = {
+ shortName = "AGPLv3+";
+ fullName = "GNU Affero General Public License version 3 or later";
+ url = https://www.gnu.org/licenses/agpl.html;
+ };
+
+ amd = {
+ shortName = "amd";
+ fullName = "AMD License Agreement";
+ url = "http://developer.amd.com/amd-license-agreement/";
+ };
+
+ amdadl = {
+ shortName = "amd-adl";
+ fullName = "amd-adl license";
+ url = "http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/licenses/AMD-ADL?revision=1.1";
+ };
+
+ # Apple Public Source License 2.0;
+ # http://opensource.org/licenses/APSL-2.0
+ apsl20 = "APSL 2.0";
+
+ asl20 = {
+ shortName = "ASL2.0";
+ fullName = "Apache Software License 2.0";
+ url = http://www.apache.org/licenses/LICENSE-2.0;
+ };
+
+ boost = {
+ shortName = "boost";
+ fullName = "Boost Software License";
+ url = http://www.boost.org/LICENSE_1_0.txt;
+ };
+
+ bsd2 = {
+ shortName = "BSD-2";
+ fullName = "BSD license (2 clause)";
+ url = http://opensource.org/licenses/BSD-2-Clause;
+ };
+
+ bsd3 = {
+ shortName = "BSD-3";
+ fullName = "BSD license (3 clause)";
+ url = http://opensource.org/licenses/BSD-3-Clause;
+ };
+
+ bsdOriginal = {
+ shortName = "BSD-original";
+ fullName = "Original BSD license with advertising clause";
+ url = https://fedoraproject.org/wiki/Licensing/BSD;
+ };
+
+ cddl = {
+ shortName = "CDDL";
+ fullName = "Common Development Distribution License ";
+ url = http://www.opensolaris.org/os/licensing/cddllicense.txt;
+ };
+
+ cpl10 = {
+ shortName = "CPL 1.0";
+ fullName = "Common Public License version 1.0";
+ url = http://www.eclipse.org/legal/cpl-v10.html;
+ };
+
+ epl10 = {
+ shortName = "EPL 1.0";
+ fullName = "Eclipse Public License version 1.0";
+ url = http://www.eclipse.org/legal/epl-v10.html;
+ };
+
+ gpl2 = "GPLv2";
+
+ gpl2Oss = {
+ shortName = "GPLv2+OSS";
+ fullName = "GNU General Public License version 2 only (with OSI approved licenses linking exception)";
+ url = http://www.mysql.com/about/legal/licensing/foss-exception;
+ };
+
+ # GNU General Public License version 2 or later;
+ # http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ gpl2Plus = "GPLv2+";
+
+ gpl3 = {
+ shortName = "GPLv3";
+ fullName = "GNU General Public License version 3 only";
+ url = http://www.fsf.org/licensing/licenses/gpl.html;
+ };
+
+ gpl3Plus = {
+ shortName = "GPLv3+";
+ fullName = "GNU General Public License version 3 or later";
+ url = http://www.fsf.org/licensing/licenses/gpl.html;
+ };
+
+ gpl3ClasspathPlus = {
+ shortName = "GPLv3+classpath+";
+ fullName = "GNU General Public License version 3 or later (with Classpath exception)";
+ url = https://fedoraproject.org/wiki/Licensing/GPL_Classpath_Exception;
+ };
+
+ isc = {
+ shortName = "ISC";
+ fullName = "Internet Systems Consortium License";
+ url = http://www.opensource.org/licenses/ISC;
+ };
+
+ ipl10 = {
+ shortName = "IPL 1.0";
+ fullName = "IBM Public License Version 1.0";
+ url = http://www.ibm.com/developerworks/opensource/library/os-i18n2/os-ipl.html;
+ };
+
+ ijg = {
+ shortName = "IJG";
+ fullName = "Independent JPEG Group License";
+ url = https://fedoraproject.org/wiki/Licensing/IJG;
+ };
+
+ libtiff = {
+ shortName = "libtiff";
+ fullName = "libtiff license";
+ url = https://fedoraproject.org/wiki/Licensing/libtiff;
+ };
+
+ lgpl2 = "LGPLv2";
+
+ lgpl2Plus = {
+ shortName = "LGPLv2+";
+ fullName = "GNU Library General Public License version 2 or later";
+ url = http://www.gnu.org/licenses/old-licenses/lgpl-2.0.html;
+ };
+
+ lgpl21 = "LGPLv2.1";
+
+ lgpl21Plus = {
+ shortName = "LGPLv2.1+";
+ fullName = "GNU Lesser General Public License version 2.1 or later";
+ url = http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html;
+ };
+
+