diff options
Diffstat (limited to 'pkgs/lib')
-rw-r--r-- | pkgs/lib/attrsets.nix | 329 | ||||
-rw-r--r-- | pkgs/lib/composable-derivation.nix | 54 | ||||
-rw-r--r-- | pkgs/lib/customisation.nix | 116 | ||||
-rw-r--r-- | pkgs/lib/debug.nix | 119 | ||||
-rw-r--r-- | pkgs/lib/default.nix | 31 | ||||
-rw-r--r-- | pkgs/lib/licenses.nix | 235 | ||||
-rw-r--r-- | pkgs/lib/lists.nix | 235 | ||||
-rw-r--r-- | pkgs/lib/maintainers.nix | 65 | ||||
-rw-r--r-- | pkgs/lib/meta.nix | 48 | ||||
-rw-r--r-- | pkgs/lib/misc.nix | 431 | ||||
-rw-r--r-- | pkgs/lib/modules.nix | 380 | ||||
-rw-r--r-- | pkgs/lib/options.nix | 315 | ||||
-rw-r--r-- | pkgs/lib/platforms.nix | 16 | ||||
-rw-r--r-- | pkgs/lib/properties.nix | 464 | ||||
-rw-r--r-- | pkgs/lib/sources.nix | 29 | ||||
-rw-r--r-- | pkgs/lib/strings-with-deps.nix | 78 | ||||
-rw-r--r-- | pkgs/lib/strings.nix | 190 | ||||
-rw-r--r-- | pkgs/lib/systems.nix | 126 | ||||
-rw-r--r-- | pkgs/lib/tests.nix | 113 | ||||
-rw-r--r-- | pkgs/lib/trivial.nix | 38 | ||||
-rw-r--r-- | pkgs/lib/types.nix | 226 |
21 files changed, 0 insertions, 3638 deletions
diff --git a/pkgs/lib/attrsets.nix b/pkgs/lib/attrsets.nix deleted file mode 100644 index 01d51779c8099..0000000000000 --- a/pkgs/lib/attrsets.nix +++ /dev/null @@ -1,329 +0,0 @@ -# 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/pkgs/lib/composable-derivation.nix b/pkgs/lib/composable-derivation.nix deleted file mode 100644 index 1099bd152bf64..0000000000000 --- a/pkgs/lib/composable-derivation.nix +++ /dev/null @@ -1,54 +0,0 @@ -{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/pkgs/lib/customisation.nix b/pkgs/lib/customisation.nix deleted file mode 100644 index bfa61169efb1e..0000000000000 --- a/pkgs/lib/customisation.nix +++ /dev/null @@ -1,116 +0,0 @@ -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/pkgs/lib/debug.nix b/pkgs/lib/debug.nix deleted file mode 100644 index d627bc861abb7..0000000000000 --- a/pkgs/lib/debug.nix +++ /dev/null @@ -1,119 +0,0 @@ -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/pkgs/lib/default.nix b/pkgs/lib/default.nix deleted file mode 100644 index dea82ee077ebb..0000000000000 --- a/pkgs/lib/default.nix +++ /dev/null @@ -1,31 +0,0 @@ -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/pkgs/lib/licenses.nix b/pkgs/lib/licenses.nix deleted file mode 100644 index 55517c5e1e5e4..0000000000000 --- a/pkgs/lib/licenses.nix +++ /dev/null @@ -1,235 +0,0 @@ -{ - /* 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; - }; - - llgpl21 = { - shortName = "LLGPLv2.1"; - fullName = "Lisp LGPL; GNU Lesser General Public License version 2.1 with Franz Inc. preamble for clarification of LGPL terms in context of Lisp"; - url = http://opensource.franz.com/preamble.html; - }; - - lgpl3 = { - shortName = "LGPLv3"; - fullName = "GNU Lesser General Public License version 3 only"; - url = http://www.fsf.org/licensing/licenses/lgpl.html; - }; - - lgpl3Plus = { - shortName = "LGPLv3+"; - fullName = "GNU Lesser General Public License version 3 or later"; - url = http://www.fsf.org/licensing/licenses/lgpl.html; - }; - - mit = { - shortName = "MIT"; - fullName = "MIT/X11 license"; - url = http://www.opensource.org/licenses/mit-license.php; - }; - - mpl11 = { - shortName = "MPL1.1"; - fullName = "Mozilla Public License version 1.1"; - url = http://www.mozilla.org/MPL/MPL-1.1.html; - }; - - openssl = { - shortName = "openssl"; - fullName = "OpenSSL license"; - url = http://www.openssl.org/source/license.html; - }; - - publicDomain = { - shortName = "Public Domain"; - fullname = "Public Domain"; - }; - - psfl = { - shortName = "PSFL"; - fullName = "Python Software Foundation License"; - url = http://docs.python.org/license.html; - }; - - tcltk = { - shortName = "Tcl/Tk"; - fullName = "Tcl/Tk license"; - url = http://www.tcl.tk/software/tcltk/license.html; - }; - - unfree = "unfree"; - - unfreeRedistributable = "unfree-redistributable"; - - unfreeRedistributableFirmware = "unfree-redistributable-firmware"; - - zlib = { - shortName = "zlib"; - fullName = "zlib license"; - url = http://www.gzip.org/zlib/zlib_license.html; - }; - - zpt20 = { - shortName = "ZPT2.0"; - fullName = "Zope Public License 2.0"; - url = "http://old.zope.org/Resources/License/ZPL-2.0"; - }; - - zpt21 = { - shortName = "ZPT2.1"; - fullName = "Zope Public License 2.1"; - url = "http://old.zope.org/Resources/License/ZPL-2.1"; - }; -} diff --git a/pkgs/lib/lists.nix b/pkgs/lib/lists.nix deleted file mode 100644 index 578686ae36684..0000000000000 --- a/pkgs/lib/lists.nix +++ /dev/null @@ -1,235 +0,0 @@ -# General list operations. -let - inherit (import ./trivial.nix) deepSeq; - - inc = builtins.add 1; - - dec = n: builtins.sub n 1; - - inherit (builtins) elemAt; -in rec { - inherit (builtins) head tail length isList add sub lessThan; - - - # Create a list consisting of a single element. `singleton x' is - # sometimes more convenient with respect to indentation than `[x]' - # when x spans multiple lines. - singleton = x: [x]; - - - # "Fold" a binary function `op' between successive elements of - # `list' with `nul' as the starting value, i.e., `fold op nul [x_1 - # x_2 ... x_n] == op x_1 (op x_2 ... (op x_n nul))'. (This is - # Haskell's foldr). - fold = op: nul: list: - let - len = length list; - fold' = n: - if n == len - then nul - else op (elemAt list n) (fold' (inc n)); - in fold' 0; - - # Left fold: `fold op nul [x_1 x_2 ... x_n] == op (... (op (op nul - # x_1) x_2) ... x_n)'. - foldl = op: nul: list: - let - len = length list; - foldl' = n: - if n == minus1 - then nul - else op (foldl' (dec n)) (elemAt list n); - in foldl' (dec (length list)); - - minus1 = dec 0; - - - # map with index: `imap (i: v: "${v}-${toString i}") ["a" "b"] == - # ["a-1" "b-2"]' - imap = f: list: - let - len = length list; - imap' = n: - if n == len - then [] - else [ (f (inc n) (elemAt list n)) ] ++ imap' (inc n); - in imap' 0; - - - # Concatenate a list of lists. - concatLists = builtins.concatLists or (fold (x: y: x ++ y) []); - - - # Map and concatenate the result. - concatMap = f: list: concatLists (map f list); - - - # Flatten the argument into a single list; that is, nested lists are - # spliced into the top-level lists. E.g., `flatten [1 [2 [3] 4] 5] - # == [1 2 3 4 5]' and `flatten 1 == [1]'. - flatten = x: - if isList x - then fold (x: y: (flatten x) ++ y) [] x - else [x]; - - - # Filter a list using a predicate; that is, return a list containing - # every element from `list' for which `pred' returns true. - filter = - builtins.filter or - (pred: list: - fold (x: y: if pred x then [x] ++ y else y) [] list); - - - # Remove elements equal to 'e' from a list. Useful for buildInputs. - remove = e: filter (x: x != e); - - - # Return true if `list' has an element `x'. - elem = - builtins.elem or - (x: list: fold (a: bs: x == a || bs) false list); - - - # Find the sole element in the list matching the specified - # predicate, returns `default' if no such element exists, or - # `multiple' if there are multiple matching elements. - findSingle = pred: default: multiple: list: - let found = filter pred list; len = length found; - in if len == 0 then default - else if len != 1 then multiple - else head found; - - - # Find the first element in the list matching the specified - # predicate or returns `default' if no such element exists. - findFirst = pred: default: list: - let found = filter pred list; - in if found == [] then default else head found; - - - # Return true iff function `pred' returns true for at least element - # of `list'. - any = pred: fold (x: y: if pred x then true else y) false; - - - # Return true iff function `pred' returns true for all elements of - # `list'. - all = pred: fold (x: y: if pred x then y else false) true; - - - # Return a singleton list or an empty list, depending on a boolean - # value. Useful when building lists with optional elements - # (e.g. `++ optional (system == "i686-linux") flashplayer'). - optional = cond: elem: if cond then [elem] else []; - - - # Return a list or an empty list, dependening on a boolean value. - optionals = cond: elems: if cond then elems else []; - - - # If argument is a list, return it; else, wrap it in a singleton - # list. If you're using this, you should almost certainly - # reconsider if there isn't a more "well-typed" approach. - toList = x: if builtins.isList x then x else [x]; - - - # Return a list of integers from `first' up to and including `last'. - range = first: last: - if builtins.lessThan last first - then [] - else [first] ++ range (builtins.add first 1) last; - - - # Partition the elements of a list in two lists, `right' and - # `wrong', depending on the evaluation of a predicate. - partition = pred: - fold (h: t: - if pred h - then { right = [h] ++ t.right; wrong = t.wrong; } - else { right = t.right; wrong = [h] ++ t.wrong; } - ) { right = []; wrong = []; }; - - - zipListsWith = f: fst: snd: - let - len1 = length fst; - len2 = length snd; - len = if builtins.lessThan len1 len2 then len1 else len2; - zipListsWith' = n: - if n != len then - [ (f (elemAt fst n) (elemAt snd n)) ] - ++ zipListsWith' (inc n) - else []; - in zipListsWith' 0; - - zipLists = zipListsWith (fst: snd: { inherit fst snd; }); - - - # Reverse the order of the elements of a list. - reverseList = fold (e: acc: acc ++ [ e ]) []; - - # Sort a list based on a comparator function which compares two - # elements and returns true if the first argument is strictly below - # the second argument. The returned list is sorted in an increasing - # order. The implementation does a quick-sort. - sort = strictLess: list: - let - len = length list; - first = head list; - pivot' = n: acc@{ left, right }: let el = elemAt list n; next = pivot' (inc n); in - if n == len - then acc - else if strictLess first el - then next { inherit left; right = [ el ] ++ right; } - else - next { left = [ el ] ++ left; inherit right; }; - pivot = pivot' 1 { left = []; right = []; }; - in - if lessThan len 2 then list - else (sort strictLess pivot.left) ++ [ first ] ++ (sort strictLess pivot.right); - - - # Return the first (at most) N elements of a list. - take = count: list: - let - len = length list; - take' = n: - if n == len || n == count - then [] - else - [ (elemAt list n) ] ++ take' (inc n); - in take' 0; - - - # Remove the first (at most) N elements of a list. - drop = count: list: - let - len = length list; - drop' = n: - if n == minus1 || lessThan n count - then [] - else - drop' (dec n) ++ [ (elemAt list n) ]; - in drop' (dec len); - - - last = list: - assert list != []; elemAt list (dec (length list)); - - - # Zip two lists together. - zipTwoLists = xs: ys: - let - len1 = length xs; - len2 = length ys; - len = if lessThan len1 len2 then len1 else len2; - zipTwoLists' = n: - if n != len then - [ { first = elemAt xs n; second = elemAt ys n; } ] - ++ zipTwoLists' (inc n) - else []; - in zipTwoLists' 0; - - deepSeqList = xs: y: if any (x: deepSeq x false) xs then y else y; -} diff --git a/pkgs/lib/maintainers.nix b/pkgs/lib/maintainers.nix deleted file mode 100644 index 06c71b2b7ac86..0000000000000 --- a/pkgs/lib/maintainers.nix +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- coding: utf-8; -*- */ - -{ - /* Add your name and email address here. Keep the list - alphabetically sorted. */ - - aforemny = "Alexander Foremny <alexanderforemny@googlemail.com>"; - algorith = "Dries Van Daele <dries_van_daele@telenet.be>"; - all = "Nix Committers <nix-commits@lists.science.uu.nl>"; - amiddelk = "Arie Middelkoop <amiddelk@gmail.com>"; - amorsillo = "Andrew Morsillo <andrew.morsillo@gmail.com>"; - andres = "Andres Loeh <ksnixos@andres-loeh.de>"; - antono = "Antono Vasiljev <self@antono.info>"; - astsmtl = "Alexander Tsamutali <astsmtl@yandex.ru>"; - aszlig = "aszlig <aszlig@redmoonstudios.org>"; - bbenoist = "Baptist BENOIST <return_0@live.com>"; - bjg = "Brian Gough <bjg@gnu.org>"; - bjornfor = "Bjørn Forsman <bjorn.forsman@gmail.com>"; - bluescreen303 = "Mathijs Kwik <mathijs@bluescreen303.nl>"; - bodil = "Bodil Stokke <nix@bodil.org>"; - chaoflow = "Florian Friesdorf <flo@chaoflow.net>"; - coconnor = "Corey O'Connor <coreyoconnor@gmail.com>"; - coroa = "Jonas Hörsch <jonas@chaoflow.net>"; - edwtjo = "Edward Tjörnhammar <ed@cflags.cc>"; - eelco = "Eelco Dolstra <eelco.dolstra@logicblox.com>"; - ertes = "Ertugrul Söylemez <es@ertes.de>"; - garbas = "Rok Garbas <rok@garbas.si>"; - goibhniu = "Cillian de Róiste <cillian.deroiste@gmail.com>"; - guibert = "David Guibert <david.guibert@gmail.com>"; - iElectric = "Domen Kozar <domen@dev.si>"; - iyzsong = "Song Wenwu <iyzsong@gmail.com>"; - jcumming = "Jack Cummings <jack@mudshark.org>"; - kkallio = "Karn Kallio <tierpluspluslists@gmail.com>"; - lovek323 = "Jason O'Conal <jason@oconal.id.au>"; - ludo = "Ludovic Courtès <ludo@gnu.org>"; - marcweber = "Marc Weber <marco-oweber@gmx.de>"; - modulistic = "Pablo Costa <modulistic@gmail.com>"; - mornfall = "Petr Ročkai <me@mornfall.net>"; - ocharles = "Oliver Charles <ollie@ocharles.org.uk>"; - offline = "Jaka Hudoklin <jakahudoklin@gmail.com>"; - orbitz = "Malcolm Matalka <mmatalka@gmail.com>"; - page = "Carles Pagès <page@cubata.homelinux.net>"; - phreedom = "Evgeny Egorochkin <phreedom@yandex.ru>"; - pierron = "Nicolas B. Pierron <nixos@nbp.name>"; - piotr = "Piotr Pietraszkiewicz <ppietrasa@gmail.com>"; - pSub = "Pascal Wittmann <mail@pascal-wittmann.de>"; - qknight = "Joachim Schiele <js@lastlog.de>"; - raskin = "Michael Raskin <7c6f434c@mail.ru>"; - rickynils = "Rickard Nilsson <rickynils@gmail.com>"; - rob = "Rob Vermaas <rob.vermaas@gmail.com>"; - roconnor = "Russell O'Connor <roconnor@theorem.ca>"; - sander = "Sander van der Burg <s.vanderburg@tudelft.nl>"; - shlevy = "Shea Levy <shea@shealevy.com>"; - simons = "Peter Simons <simons@cryp.to>"; - smironov = "Sergey Mironov <ierton@gmail.com>"; - thammers = "Tobias Hammerschmidt <jawr@gmx.de>"; - the-kenny = "Moritz Ulrich <moritz@tarn-vedra.de>"; - urkud = "Yury G. Kudryashov <urkud+nix@ya.ru>"; - vcunat = "Vladimír Čunát <vcunat@gmail.com>"; - viric = "Lluís Batlle i Rossell <viric@viric.name>"; - vizanto = "Danny Wilson <danny@prime.vc>"; - winden = "Antonio Vargas Gonzalez <windenntw@gmail.com>"; - z77z = "Marco Maggesi <maggesi@math.unifi.it>"; - zef = "Zef Hemel <zef@zef.me>"; -} diff --git a/pkgs/lib/meta.nix b/pkgs/lib/meta.nix deleted file mode 100644 index a5afce9e0cb1d..0000000000000 --- a/pkgs/lib/meta.nix +++ /dev/null @@ -1,48 +0,0 @@ -/* Some functions for manipulating meta attributes, as well as the - name attribute. */ - -rec { - - - /* Add to or override the meta attributes of the given - derivation. - - Example: - addMetaAttrs {description = "Bla blah";} somePkg - */ - addMetaAttrs = newAttrs: drv: - drv // { meta = (if drv ? meta then drv.meta else {}) // newAttrs; }; - - - /* Change the symbolic name of a package for presentation purposes - (i.e., so that nix-env users can tell them apart). - */ - setName = name: drv: drv // {inherit name;}; - - - /* Like `setName', but takes the previous name as an argument. - - Example: - updateName (oldName: oldName + "-experimental") somePkg - */ - updateName = updater: drv: drv // {name = updater (drv.name);}; - - - /* Append a suffix to the name of a package. !!! the suffix should - really be appended *before* the version, at least most of the - time. - */ - appendToName = suffix: updateName (name: "${name}-${suffix}"); - - - /* Decrease the nix-env priority of the package, i.e., other - versions/variants of the package will be preferred. - */ - lowPrio = drv: addMetaAttrs { priority = "10"; } drv; - - /* Increase the nix-env priority of the package, i.e., this - version/variant of the package will be preferred. - */ - hiPrio = drv: addMetaAttrs { priority = "-10"; } drv; - -} diff --git a/pkgs/lib/misc.nix b/pkgs/lib/misc.nix deleted file mode 100644 index 19e5081009de8..0000000000000 --- a/pkgs/lib/misc.nix +++ /dev/null @@ -1,431 +0,0 @@ -let lib = import ./default.nix; - inherit (builtins) isFunction hasAttr getAttr head tail isList isAttrs isInt attrNames; - -in - -with import ./lists.nix; -with import ./attrsets.nix; -with import ./strings.nix; - -rec { - - # returns default if env var is not set - maybeEnv = name: default: - let value = builtins.getEnv name; in - if value == "" then default else value; - - defaultMergeArg = x : y: if builtins.isAttrs y then - y - else - (y x); - defaultMerge = x: y: x // (defaultMergeArg x y); - foldArgs = merger: f: 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 { - function = foldArgs merger f arg; - args = (lib.attrByPath ["passthru" "args"] {} z) // x; - } )); - withStdOverrides = base // { - override = base.passthru.function; - deepOverride = a : (base.passthru.function ((lib.mapAttrs (lib.deepOverrider a) base.passthru.args) // a)); - } ; - in - withStdOverrides; - - - # predecessors: proposed replacement for applyAndFun (which has a bug cause it merges twice) - # the naming "overridableDelayableArgs" tries to express that you can - # - override attr values which have been supplied earlier - # - use attr values before they have been supplied by accessing the fix point - # name "fixed" - # f: the (delayed overridden) arguments are applied to this - # - # initial: initial attrs arguments and settings. see defaultOverridableDelayableArgs - # - # returns: f applied to the arguments // special attributes attrs - # a) merge: merge applied args with new args. Wether an argument is overridden depends on the merge settings - # b) replace: this let's you replace and remove names no matter which merge function has been set - # - # 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 - let - takeFixed = if isFunction initial then initial else (fixed : initial); # transform initial to an expression always taking the fixed argument - tidy = args : - let # apply all functions given in "applyPreTidy" in sequence - 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 : - let args = takeFixed fixed; - mergeFun = getAttr n args; - in if isAttrs x then (mergeFun args x) - else assert isFunction x; - mergeFun args (x ( args // { inherit fixed; })); - in overridableDelayableArgs f newArgs; - in - (f (tidy (lib.fix takeFixed))) // { - merge = fun "mergeFun"; - replace = fun "keepFun"; - }; - 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 - 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; - }; - removeAttrs = ["mergeFun" "keepFun" "mergeAttrBy" "removeAttrs" "fixed" ]; # before applying the arguments to the function make sure these names are gone - }; - in (overridableDelayableArgs f defaults).merge; - - - - # 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) - # b = a.passthru.function { a = [ "3" ]; meta = { d2 = "bar2";}; }; - # # instead of passing/ overriding values you can use a merge function: - # c = b.passthru.function ( x: { a = x.a ++ ["4"]; }); # consider using (maybeAttr "a" [] x) - # } - # result: - # { - # a = { a = ["2"]; meta = { d = "bar"; }; passthru = { function = .. }; }; - # b = { a = ["3"]; meta = { d2 = "bar2"; }; passthru = { function = .. }; }; - # c = { a = ["3" "4"]; meta = { d2 = "bar2"; }; passthru = { function = .. }; }; - # # c2 is equal to c - # } - composedArgsAndFun = f: foldArgs defaultMerge f {}; - - - # shortcut for attrByPath ["name"] default attrs - maybeAttrNullable = name: default: attrs: - if attrs == null then default else - if __hasAttr name attrs then (__getAttr name attrs) else default; - - # shortcut for attrByPath ["name"] default attrs - maybeAttr = name: default: attrs: - if __hasAttr name attrs then (__getAttr name attrs) else default; - - - # Return the second argument if the first one is true or the empty version - # of the second argument. - ifEnable = cond: val: - if cond then val - else if builtins.isList val then [] - else if builtins.isAttrs val then {} - # else if builtins.isString val then "" - else if val == true || val == false then false - else null; - - - # Return true only if there is an attribute and it is true. - checkFlag = attrSet: name: - if name == "true" then true else - if name == "false" then false else - if (elem name (attrByPath ["flags"] [] attrSet)) then true else - attrByPath [name] false attrSet ; - - - # Input : attrSet, [ [name default] ... ], name - # Output : its value or default. - getValue = attrSet: argList: name: - ( attrByPath [name] (if checkFlag attrSet name then true else - if argList == [] then null else - let x = builtins.head argList; in - if (head x) == name then - (head (tail x)) - else (getValue attrSet - (tail argList) name)) attrSet ); - - - # Input : attrSet, [[name default] ...], [ [flagname reqs..] ... ] - # Output : are reqs satisfied? It's asserted. - checkReqs = attrSet : argList : condList : - ( - fold lib.and true - (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)) ; - - - # This function has O(n^2) performance. - uniqList = {inputList, acc ? []} : - let go = xs : acc : - if xs == [] - then [] - else let x = head xs; - y = if elem x acc then [] else [x]; - in y ++ go (tail xs) (y ++ acc); - in go inputList acc; - - uniqListExt = {inputList, outputList ? [], - getter ? (x : x), compare ? (x: y: x==y)}: - if inputList == [] then outputList else - let x=head inputList; - isX = y: (compare (getter y) (getter x)); - newOutputList = outputList ++ - (if any isX outputList then [] else [x]); - in uniqListExt {outputList=newOutputList; - inputList = (tail inputList); - inherit getter compare; - }; - - - - condConcat = name: list: checker: - if list == [] then name else - if checker (head list) then - condConcat - (name + (head (tail list))) - (tail (tail list)) - checker - else condConcat - name (tail (tail list)) checker; - - lazyGenericClosure = {startSet, operator}: - let - work = list: doneKeys: result: - if list == [] then - result - else - let x = head list; key = x.key; in - if elem key doneKeys then - work (tail list) doneKeys result - else - work (tail list ++ operator x) ([key] ++ doneKeys) ([x] ++ result); - in - work startSet [] []; - - genericClosure = - if builtins ? genericClosure then builtins.genericClosure - else lazyGenericClosure; - - innerModifySumArgs = f: x: a: b: if b == null then (f a b) // x else - innerModifySumArgs f x (a // b); - modifySumArgs = f: x: innerModifySumArgs f x {}; - - - innerClosePropagation = acc : xs : - if xs == [] - then acc - else let y = head xs; - ys = tail xs; - in if ! isAttrs y - then innerClosePropagation acc ys - else let acc' = [y] ++ acc; - in innerClosePropagation - acc' - (uniqList { inputList = (maybeAttrNullable "propagatedBuildInputs" [] y) - ++ (maybeAttrNullable "propagatedNativeBuildInputs" [] y) - ++ ys; - acc = acc'; - } - ); - - 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 (builtins.getAttr attr r) ) (attrNames r); - - # attribute set containing one attribute - nvs = name : value : listToAttrs [ (nameValuePair name value) ]; - # adds / replaces an attribute of an attribute set - 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 : - setAttr attrs name (f (maybeAttr name default attrs)); - - # 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 (__hasAttr n set) - then setAttr set n (f (__getAttr n set) (__getAttr n set2)) - 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) ); - - # merges attributes using //, if a name exisits in both attributes - # an error will be triggered unless its listed in mergeLists - # so you can mergeAttrsNoOverride { buildInputs = [a]; } { buildInputs = [a]; } {} to get - # { buildInputs = [a b]; } - # merging buildPhase does'nt really make sense. The cases will be rare where appending /prefixing will fit your needs? - # in these cases the first buildPhase will override the second one - # ! deprecated, use mergeAttrByFunc instead - mergeAttrsNoOverride = { mergeLists ? ["buildInputs" "propagatedBuildInputs"], - overrideSnd ? [ "buildPhase" ] - } : attrs1 : attrs2 : - fold (n: set : - setAttr set n ( if (__hasAttr n set) - then # merge - if elem n mergeLists # attribute contains list, merge them by concatenating - then (__getAttr n attrs2) ++ (__getAttr n attrs1) - else if elem n overrideSnd - then __getAttr n attrs1 - else throw "error mergeAttrsNoOverride, attribute ${n} given in both attributes - no merge func defined" - else __getAttr n attrs2 # add attribute not existing in attr1 - )) attrs1 (__attrNames attrs2); - - - # example usage: - # mergeAttrByFunc { - # inherit mergeAttrBy; # defined below - # buildInputs = [ a b ]; - # } { - # buildInputs = [ c d ]; - # }; - # will result in - # { 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 : - let - 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 - if (hasAttr a x) - then if (hasAttr a y) - then v (getAttr a x) (getAttr a y) # both have attr, use merge func - else (getAttr a x) # only x has attr - else (getAttr a y) # only y has attr) - ) (removeAttrs mergeAttrBy2 - # don't merge attrs which are neither in x nor y - (filter (a : (! hasAttr a x) && (! hasAttr a y) ) - (attrNames mergeAttrBy2)) - ) - ) - ]; - mergeAttrsByFuncDefaults = foldl mergeAttrByFunc { inherit mergeAttrBy; }; - mergeAttrsByFuncDefaultsClean = list: removeAttrs (mergeAttrsByFuncDefaults list) ["mergeAttrBy"]; - - # merge attrs based on version key into mkDerivation args, see mergeAttrBy to learn about smart merge defaults - # - # This function is best explained by an example: - # - # {version ? "2.x"} : - # - # mkDerivation (mergeAttrsByVersion "package-name" version - # { # version specific settings - # "git" = { src = ..; preConfigre = "autogen.sh"; buildInputs = [automake autoconf libtool]; }; - # "2.x" = { src = ..; }; - # } - # { // shared settings - # buildInputs = [ common build inputs ]; - # meta = { .. } - # } - # ) - # - # Please note that e.g. Eelco Dolstra usually prefers having one file for - # each version. On the other hand there are valuable additional design goals - # - readability - # - do it once only - # - try to avoid duplication - # - # Marc Weber and Michael Raskin sometimes prefer keeping older - # versions around for testing and regression tests - as long as its cheap to - # do so. - # - # Very often it just happens that the "shared" code is the bigger part. - # Then using this function might be appropriate. - # - # Be aware that its easy to cause recompilations in all versions when using - # this function - also if derivations get too complex splitting into multiple - # files is the way to go. - # - # 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)]; - - # 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) - [ "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" ]) - ; - - # prepareDerivationArgs tries to make writing configurable derivations easier - # example: - # prepareDerivationArgs { - # mergeAttrBy = { - # myScript = x : y : x ++ "\n" ++ y; - # }; - # cfg = { - # readlineSupport = true; - # }; - # flags = { - # readline = { - # set = { - # configureFlags = [ "--with-compiler=${compiler}" ]; - # buildInputs = [ compiler ]; - # pass = { inherit compiler; READLINE=1; }; - # assertion = compiler.dllSupport; - # myScript = "foo"; - # }; - # unset = { configureFlags = ["--without-compiler"]; }; - # }; - # }; - # src = ... - # buildPhase = '' ... ''; - # name = ... - # myScript = "bar"; - # }; - # if you don't have need for unset you can omit the surrounding set = { .. } attr - # all attrs except flags cfg and mergeAttrBy will be merged with the - # additional data from flags depending on config settings - # It's used in composableDerivation in all-packages.nix. It's also used - # heavily in the new python and libs implementation - # - # should we check for misspelled cfg options? - # 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))) - // args2.cfg; - opts = attrValues (mapAttrs (a : v : - let v2 = if v ? set || v ? unset then v else { set = v; }; - n = if (getAttr (flagName a) cfgWithDefaults) then "set" else "unset"; - attr = maybeAttr n {} v2; in - if (maybeAttr "assertion" true attr) - then attr - else throw "assertion of flag ${a} of derivation ${args.name} failed" - ) args2.flags ); - in removeAttrs - (mergeAttrsByFuncDefaults ([args] ++ opts ++ [{ passthru = cfgWithDefaults; }])) - ["flags" "cfg" "mergeAttrBy" ]; - - - nixType = x: - if isAttrs x then - if x ? outPath then "derivation" - else "aattrs" - else if isFunction x then "function" - else if isList x then "list" - else if x == true then "bool" - else if x == false then "bool" - else if x == null then "null" - else if isInt x then "int" - else "string"; - -} diff --git a/pkgs/lib/modules.nix b/pkgs/lib/modules.nix deleted file mode 100644 index acd10e7bf5769..0000000000000 --- a/pkgs/lib/modules.nix +++ /dev/null @@ -1,380 +0,0 @@ -# NixOS module handling. - -let lib = import ./default.nix; in - -with { inherit (builtins) head; }; -with import ./trivial.nix; -with import ./lists.nix; -with import ./misc.nix; -with import ./attrsets.nix; -with import ./options.nix; -with import ./properties.nix; - -rec { - - # Unfortunately this can also be a string. - isPath = x: !( - builtins.isFunction x - || builtins.isAttrs x - || builtins.isInt x - || builtins.isBool x - || builtins.isList x - ); - - - importIfPath = path: - if isPath path then - import path - else - path; - - - applyIfFunction = f: arg: - if builtins.isFunction f then - f arg - else - f; - - - isModule = m: - (m ? config && isAttrs m.config && ! isOption m.config) - || (m ? options && isAttrs m.options && ! isOption m.options); - - - # Convert module to a set which has imports / options and config - # attributes. - unifyModuleSyntax = m: - let - delayedModule = delayProperties m; - - getImports = - toList (rmProperties (delayedModule.require or [])); - getImportedPaths = filter isPath getImports; - getImportedSets = filter (x: !isPath x) getImports; - - getConfig = - removeAttrs delayedModule ["require" "key" "imports"]; - - in - if isModule m then - { key = "<unknown location>"; } // m - else - { key = "<unknown location>"; - imports = (m.imports or []) ++ getImportedPaths; - config = getConfig; - } // ( - if getImportedSets != [] then - assert length getImportedSets == 1; - { options = head getImportedSets; } - else - {} - ); - - - unifyOptionModule = {key ? "<unknown location>"}: name: index: m: (args: - let - module = lib.applyIfFunction m args; - key_ = rec { - file = key; - option = name; - number = index; - outPath = key; - }; - in if lib.isModule module then - { key = key_; } // module - else - { key = key_; options = module; } - ); - - - moduleClosure = initModules: args: - let - moduleImport = origin: index: m: - let m' = applyIfFunction (importIfPath m) args; - in (unifyModuleSyntax m') // { - # used by generic closure to avoid duplicated imports. - key = - if isPath m then m - else m'.key or (newModuleName origin index); - }; - - getImports = m: m.imports or []; - - newModuleName = origin: index: - "${origin.key}:<import-${toString index}>"; - - topLevel = { - key = "<top-level>"; - }; - - in - (lazyGenericClosure { - startSet = imap (moduleImport topLevel) initModules; - operator = m: imap (moduleImport m) (getImports m); - }); - - - moduleApply = funs: module: - lib.mapAttrs (name: value: - if builtins.hasAttr name funs then - let fun = lib.getAttr name funs; in - fun value - else - value - ) module; - - - # Handle mkMerge function left behind after a delay property. - moduleFlattenMerge = module: - if module ? config && - isProperty module.config && - isMerge module.config.property - then - (map (cfg: { key = module.key; config = cfg; }) module.config.content) - ++ [ (module // { config = {}; }) ] - else - [ module ]; - - - # Handle mkMerge attributes which are left behind by previous delay - # properties and convert them into a list of modules. Delay properties - # inside the config attribute of a module and create a second module if a - # mkMerge attribute was left behind. - # - # Module -> [ Module ] - delayModule = module: - map (moduleApply { config = delayProperties; }) (moduleFlattenMerge module); - - - evalDefinitions = opt: values: - if opt.type.delayOnGlobalEval or false then - map (delayPropertiesWithIter opt.type.iter opt.name) - (evalLocalProperties values) - else - evalProperties values; - - - selectModule = name: m: - { inherit (m) key; - } // ( - if m ? options && builtins.hasAttr name m.options then - { options = lib.getAttr name m.options; } - else {} - ) // ( - if m ? config && builtins.hasAttr name m.config then - { config = lib.getAttr name m.config; } - else {} - ); - - filterModules = name: modules: - filter (m: m ? config || m ? options) ( - map (selectModule name) modules - ); - - - modulesNames = modules: - lib.concatMap (m: [] - ++ optionals (m ? options) (lib.attrNames m.options) - ++ optionals (m ? config) (lib.attrNames m.config) - ) modules; - - - moduleZip = funs: modules: - lib.mapAttrs (name: fun: - fun (catAttrs name modules) - ) funs; - - - moduleMerge = path: modules: - let modules_ = modules; in - let - addName = name: - if path == "" then name else path + "." + name; - - modules = concatLists (map delayModule modules_); - - modulesOf = name: filterModules name modules; - declarationsOf = name: filter (m: m ? options) (modulesOf name); - definitionsOf = name: filter (m: m ? config ) (modulesOf name); - - recurseInto = name: - moduleMerge (addName name) (modulesOf name); - - recurseForOption = name: modules: args: - moduleMerge name ( - moduleClosure modules args - ); - - errorSource = modules: - "The error may come from the following files:\n" + ( - lib.concatStringsSep "\n" ( - map (m: - if m ? key then toString m.key else "<unknown location>" - ) modules - ) - ); - - eol = "\n"; - - allNames = modulesNames modules; - - getResults = m: - let fetchResult = s: mapAttrs (n: v: v.result) s; in { - options = fetchResult m.options; - config = fetchResult m.config; - }; - - endRecursion = { options = {}; config = {}; }; - - in if modules == [] then endRecursion else - getResults (fix (crossResults: moduleZip { - options = lib.zipWithNames allNames (name: values: rec { - config = lib.getAttr name crossResults.config; - - declarations = declarationsOf name; - declarationSources = - map (m: { - source = m.key; - }) declarations; - - hasOptions = values != []; - isOption = any lib.isOption values; - - decls = # add location to sub-module options. - map (m: - mapSubOptions - (unifyOptionModule {inherit (m) key;} name) - m.options - ) declarations; - - decl = - lib.addErrorContext "${eol - }while enhancing option `${addName name}':${eol - }${errorSource declarations}${eol - }" ( - addOptionMakeUp - { name = addName name; recurseInto = recurseForOption; } - (mergeOptionDecls decls) - ); - - value = decl // (with config; { - inherit (config) isNotDefined; - isDefined = ! isNotDefined; - declarations = declarationSources; - definitions = definitionSources; - config = strictResult; - }); - - recurse = (recurseInto name).options; - - result = - if isOption then value - else if !hasOptions then {} - else if all isAttrs values then recurse - else - throw "${eol - }Unexpected type where option declarations are expected.${eol - }${errorSource declarations}${eol - }"; - - }); - - config = lib.zipWithNames allNames (name: values_: rec { - option = lib.getAttr name crossResults.options; - - definitions = definitionsOf name; - definitionSources = - map (m: { - source = m.key; - value = m.config; - }) definitions; - - values = values_ ++ - optionals (option.isOption && option.decl ? extraConfigs) - option.decl.extraConfigs; - - defs = evalDefinitions option.decl values; - - isNotDefined = defs == []; - - value = - lib.addErrorContext "${eol - }while evaluating the option `${addName name}':${eol - }${errorSource (modulesOf name)}${eol - }" ( - let opt = option.decl; in - opt.apply ( - if isNotDefined then - opt.default or (throw "Option `${addName name}' not defined and does not have a default value.") - else opt.merge defs - ) - ); - - strictResult = builtins.tryEval (builtins.toXML value); - - recurse = (recurseInto name).config; - - configIsAnOption = v: isOption (rmProperties v); - errConfigIsAnOption = - let badModules = filter (m: configIsAnOption m.config) definitions; in - "${eol - }Option ${addName name} is defined in the configuration section.${eol - }${errorSource badModules}${eol - }"; - - errDefinedWithoutDeclaration = - let badModules = definitions; in - "${eol - }Option '${addName name}' defined without option declaration.${eol - }${errorSource badModules}${eol - }"; - - result = - if option.isOption then value - else if !option.hasOptions then throw errDefinedWithoutDeclaration - else if any configIsAnOption values then throw errConfigIsAnOption - else if all isAttrs values then recurse - # plain value during the traversal - else throw errDefinedWithoutDeclaration; - - }); - } modules)); - - - fixMergeModules = initModules: {...}@args: - lib.fix (result: - # This trick avoids an infinite loop because names of attribute - # are know and it is not required to evaluate the result of - # moduleMerge to know which attributes are present as arguments. - let module = { inherit (result) options config; }; in - moduleMerge "" ( - moduleClosure initModules (module // args) - ) - ); - - - # Visit all definitions to raise errors related to undeclared options. - checkModule = path: {config, options, ...}@m: - let - eol = "\n"; - addName = name: - if path == "" then name else path + "." + name; - in - if lib.isOption options then - if options ? options then - options.type.fold - (cfg: res: res && checkModule (options.type.docPath path) cfg._args) - true config - else - true - else if isAttrs options && lib.attrNames m.options != [] then - all (name: - lib.addErrorContext "${eol - }while checking the attribute `${addName name}':${eol - }" (checkModule (addName name) (selectModule name m)) - ) (lib.attrNames m.config) - else - builtins.trace "try to evaluate config ${lib.showVal config}." - false; - -} diff --git a/pkgs/lib/options.nix b/pkgs/lib/options.nix deleted file mode 100644 index e8e01083a77a2..0000000000000 --- a/pkgs/lib/options.nix +++ /dev/null @@ -1,315 +0,0 @@ -# Nixpkgs/NixOS option handling. - -let lib = import ./default.nix; in - -with { inherit (builtins) head length; }; -with import ./trivial.nix; -with import ./lists.nix; -with import ./misc.nix; -with import ./attrsets.nix; -with import ./properties.nix; - -rec { - - inherit (lib) isType; - - - isOption = isType "option"; - mkOption = attrs: attrs // { - _type = "option"; - # name (this is the name of the attributem it is automatically generated by the traversal) - # default (value used when no definition exists) - # example (documentation) - # description (documentation) - # type (option type, provide a default merge function and ensure type correctness) - # merge (function used to merge definitions into one definition: [ /type/ ] -> /type/) - # apply (convert the option value to ease the manipulation of the option result) - # options (set of sub-options declarations & definitions) - # extraConfigs (list of possible configurations) - }; - - mkEnableOption = name: mkOption { - default = false; - example = true; - description = "Whether to enable ${name}"; - type = lib.types.bool; - }; - - mapSubOptions = f: opt: - if opt ? options then - opt // { - options = imap f (toList opt.options); - } - else - opt; - - # Make the option declaration more user-friendly by adding default - # settings and some verifications based on the declaration content (like - # type correctness). - addOptionMakeUp = {name, recurseInto}: decl: - let - init = { - inherit name; - merge = mergeDefaultOption; - apply = lib.id; - }; - - functionsFromType = opt: - opt // (builtins.intersectAttrs { merge = 1; check = 1; } (decl.type or {})); - - addDeclaration = opt: opt // decl; - - ensureMergeInputType = opt: - if opt ? check then - opt // { - merge = list: - if all opt.check list then - opt.merge list - else - throw "One of option ${name} values has a bad type."; - } - else opt; - - checkDefault = opt: - if opt ? check && opt ? default then - opt // { - default = - if opt.check opt.default then - opt.default - else - throw "The default value of option ${name} has a bad type."; - } - else opt; - - handleOptionSets = opt: - if opt ? type && opt.type.hasOptions then - let - # Evaluate sub-modules. - subModuleMerge = path: vals: - lib.fix (args: - let - result = recurseInto path (opt.options ++ imap (index: v: args: { - key = rec { - #!!! Would be nice if we had the file the val was from - option = path; - number = index; - outPath = "option ${option} config number ${toString number}"; - }; - } // (lib.applyIfFunction v args)) (toList vals)) args; - name = lib.removePrefix (opt.name + ".") path; - extraArgs = opt.extraArgs or {}; - individualExtraArgs = opt.individualExtraArgs or {}; - in { - inherit (result) config options; - inherit name; - } // - (opt.extraArgs or {}) // - (if hasAttr name individualExtraArgs then getAttr name individualExtraArgs else {}) - ); - - # Add _options in sub-modules to make it viewable from other - # modules. - subModuleMergeConfig = path: vals: - let result = subModuleMerge path vals; in - { _args = result; } // result.config; - - in - opt // { - merge = list: - opt.type.iter - subModuleMergeConfig - opt.name - (opt.merge list); - options = - let path = opt.type.docPath opt.name; in - (subModuleMerge path []).options; - } - else - opt; - in - foldl (opt: f: f opt) init [ - # default settings - functionsFromType - - # user settings - addDeclaration - - # override settings - ensureMergeInputType - checkDefault - handleOptionSets - ]; - - # Merge a list of options containning different field. This is useful to - # separate the merge & apply fields from the interface. - mergeOptionDecls = opts: - if opts == [] then {} - else if length opts == 1 then - let opt = head opts; in - if opt ? options then - opt // { options = toList opt.options; } - else - opt - else - fold (opt1: opt2: - lib.addErrorContext "opt1 = ${lib.showVal opt1}\nopt2 = ${lib.showVal opt2}" ( - # You cannot merge if two options have the same field. - assert opt1 ? default -> ! opt2 ? default; - assert opt1 ? example -> ! opt2 ? example; - assert opt1 ? description -> ! opt2 ? description; - assert opt1 ? merge -> ! opt2 ? merge; - assert opt1 ? apply -> ! opt2 ? apply; - assert opt1 ? type -> ! opt2 ? type; - opt1 // opt2 - // optionalAttrs (opt1 ? options || opt2 ? options) { - options = - (toList (opt1.options or [])) - ++ (toList (opt2.options or [])); - } - // optionalAttrs (opt1 ? extraConfigs || opt2 ? extraConfigs) { - extraConfigs = opt1.extraConfigs or [] ++ opt2.extraConfigs or []; - } - // optionalAttrs (opt1 ? extraArgs || opt2 ? extraArgs) { - extraArgs = opt1.extraArgs or {} // opt2.extraArgs or {}; - } - // optionalAttrs (opt1 ? individualExtraArgs || opt2 ? individualExtraArgs) { - individualExtraArgs = zipAttrsWith (name: values: - if length values == 1 then head values else (head values // (head (tail values))) - ) [ (opt1.individualExtraArgs or {}) (opt2.individualExtraArgs or {}) ]; - } - )) {} opts; - - - # !!! This function will be removed because this can be done with the - # multiple option declarations. - addDefaultOptionValues = defs: opts: opts // - builtins.listToAttrs (map (defName: - { name = defName; - value = - let - defValue = builtins.getAttr defName defs; - optValue = builtins.getAttr defName opts; - in - if isOption defValue - then - # `defValue' is an option. - if hasAttr defName opts - then builtins.getAttr defName opts - else defValue.default - else - # `defValue' is an attribute set containing options. - # So recurse. - if hasAttr defName opts && isAttrs optValue - then addDefaultOptionValues defValue optValue - else addDefaultOptionValues defValue {}; - } - ) (attrNames defs)); - - mergeDefaultOption = list: - if length list == 1 then head list - else if all builtins.isFunction list then x: mergeDefaultOption (map (f: f x) list) - else if all isList list then concatLists list - else if all isAttrs list then fold lib.mergeAttrs {} list - else if all builtins.isBool list then fold lib.or false list - else if all builtins.isString list then lib.concatStrings list - else if all builtins.isInt list && all (x: x == head list) list - then head list - else throw "Cannot merge values."; - - mergeTypedOption = typeName: predicate: merge: list: - if all predicate list then merge list - else throw "Expect a ${typeName}."; - - mergeEnableOption = mergeTypedOption "boolean" - (x: true == x || false == x) (fold lib.or false); - - mergeListOption = mergeTypedOption "list" isList concatLists; - - mergeStringOption = mergeTypedOption "string" - (x: if builtins ? isString then builtins.isString x else x + "") - lib.concatStrings; - - mergeOneOption = list: - if list == [] then abort "This case should never happen." - else if length list != 1 then throw "Multiple definitions. Only one is allowed for this option." - else head list; - - - fixableMergeFun = merge: f: config: - merge ( - # generate the list of option sets. - f config - ); - - fixableMergeModules = merge: initModules: {...}@args: config: - fixableMergeFun merge (config: - lib.moduleClosure initModules (args // { inherit config; }) - ) config; - - - fixableDefinitionsOf = initModules: {...}@args: - fixableMergeModules (modules: (lib.moduleMerge "" modules).config) initModules args; - - fixableDeclarationsOf = initModules: {...}@args: - fixableMergeModules (modules: (lib.moduleMerge "" modules).options) initModules args; - - definitionsOf = initModules: {...}@args: - (lib.fix (module: - fixableMergeModules (lib.moduleMerge "") initModules args module.config - )).config; - - declarationsOf = initModules: {...}@args: - (lib.fix (module: - fixableMergeModules (lib.moduleMerge "") initModules args module.config - )).options; - - - # Generate documentation template from the list of option declaration like - # the set generated with filterOptionSets. - optionAttrSetToDocList = ignore: newOptionAttrSetToDocList; - newOptionAttrSetToDocList = attrs: - let options = collect isOption attrs; in - fold (opt: rest: - let - docOption = { - inherit (opt) name; - description = if opt ? description then opt.description else - throw "Option ${opt.name}: No description."; - - declarations = map (x: toString x.source) opt.declarations; - #definitions = map (x: toString x.source) opt.definitions; - } - // optionalAttrs (opt ? example) { example = scrubOptionValue opt.example; } - // optionalAttrs (opt ? default) { default = scrubOptionValue opt.default; } - // optionalAttrs (opt ? defaultText) { default = opt.defaultText; }; - - subOptions = - if opt ? options then - newOptionAttrSetToDocList opt.options - else - []; - in - [ docOption ] ++ subOptions ++ rest - ) [] options; - - - /* This function recursively removes all derivation attributes from - `x' except for the `name' attribute. This is to make the - generation of `options.xml' much more efficient: the XML - representation of derivations is very large (on the order of - megabytes) and is not actually used by the manual generator. */ - scrubOptionValue = x: - if isDerivation x then { type = "derivation"; drvPath = x.name; outPath = x.name; name = x.name; } - else if isList x then map scrubOptionValue x - else if isAttrs x then mapAttrs (n: v: scrubOptionValue v) (removeAttrs x ["_args"]) - else x; - - - /* For use in the ‘example’ option attribute. It causes the given - text to be included verbatim in documentation. This is necessary - for example values that are not simple values, e.g., - functions. */ - literalExample = text: { _type = "literalExample"; inherit text; }; - - -} diff --git a/pkgs/lib/platforms.nix b/pkgs/lib/platforms.nix deleted file mode 100644 index 8be37d7ed1e7a..0000000000000 --- a/pkgs/lib/platforms.nix +++ /dev/null @@ -1,16 +0,0 @@ -let lists = import ./lists.nix; in - -rec { - gnu = linux; /* ++ hurd ++ kfreebsd ++ ... */ - linux = ["i686-linux" "x86_64-linux" "powerpc-linux" "armv5tel-linux" "armv7l-linux" "mips64el-linux"]; - darwin = ["x86_64-darwin"]; - freebsd = ["i686-freebsd" "x86_64-freebsd" "powerpc-freebsd"]; - openbsd = ["i686-openbsd" "x86_64-openbsd"]; - netbsd = ["i686-netbsd" "x86_64-netbsd"]; - cygwin = ["i686-cygwin"]; - unix = linux ++ darwin ++ freebsd ++ openbsd; - all = linux ++ darwin ++ cygwin ++ freebsd ++ openbsd; - none = []; - allBut = platform: lists.filter (x: platform != x) all; - mesaPlatforms = ["i686-linux" "x86_64-linux" "x86_64-darwin" "armv5tel-linux" "armv6l-linux"]; -} diff --git a/pkgs/lib/properties.nix b/pkgs/lib/properties.nix deleted file mode 100644 index 22aa8d891d8a5..0000000000000 --- a/pkgs/lib/properties.nix +++ /dev/null @@ -1,464 +0,0 @@ -# Nixpkgs/NixOS properties. Generalize the problem of delayable (not yet -# evaluable) properties like mkIf. - -let lib = import ./default.nix; in - -with { inherit (builtins) head tail; }; -with import ./trivial.nix; -with import ./lists.nix; -with import ./misc.nix; -with import ./attrsets.nix; - -rec { - - inherit (lib) isType; - - # Tell that nothing is defined. When properties are evaluated, this type - # is used to remove an entry. Thus if your property evaluation semantic - # implies that you have to mute the content of an attribute, then your - # property should produce this value. - isNotdef = isType "notdef"; - mkNotdef = {_type = "notdef";}; - - # General property type, it has a property attribute and a content - # attribute. The property attribute refers to an attribute set which - # contains a _type attribute and a list of functions which are used to - # evaluate this property. The content attribute is used to stack properties - # on top of each other. - # - # The optional functions which may be contained in the property attribute - # are: - # - onDelay: run on a copied property. - # - onGlobalDelay: run on all copied properties. - # - onEval: run on an evaluated property. - # - onGlobalEval: run on a list of property stack on top of their values. - isProperty = isType "property"; - mkProperty = p@{property, content, ...}: p // { - _type = "property"; - }; - - # Go through the stack of properties and apply the function `op' on all - # property and call the function `nul' on the final value which is not a - # property. The stack is traversed in reversed order. The `op' function - # should expect a property with a content which have been modified. - # - # Warning: The `op' function expects only one argument in order to avoid - # calls to mkProperties as the argument is already a valid property which - # contains the result of the folding inside the content attribute. - foldProperty = op: nul: attrs: - if isProperty attrs then - op (attrs // { - content = foldProperty op nul attrs.content; - }) - else - nul attrs; - - # Simple function which can be used as the `op' argument of the - # foldProperty function. Properties that you don't want to handle can be - # ignored with the `id' function. `isSearched' is a function which should - # check the type of a property and return a boolean value. `thenFun' and - # `elseFun' are functions which behave as the `op' argument of the - # foldProperty function. - foldFilter = isSearched: thenFun: elseFun: attrs: - if isSearched attrs.property then - thenFun attrs - else - elseFun attrs; - - - # Move properties from the current attribute set to the attribute - # contained in this attribute set. This trigger property handlers called - # `onDelay' and `onGlobalDelay'. - delayPropertiesWithIter = iter: path: attrs: - let cleanAttrs = rmProperties attrs; in - if isProperty attrs then - iter (a: v: - lib.addErrorContext "while moving properties on the attribute `${a}':" ( - triggerPropertiesGlobalDelay a ( - triggerPropertiesDelay a ( - copyProperties attrs v - )))) path cleanAttrs - else - attrs; - - delayProperties = # implicit attrs argument. - let - # mapAttrs except that it also recurse into potential mkMerge - # functions. This may cause a strictness issue because looking the - # type of a string implies evaluating it. - iter = fun: path: value: - lib.mapAttrs (attr: val: - if isProperty val && isMerge val.property then - val // { content = map (fun attr) val.content; } - else - fun attr val - ) value; - in - delayPropertiesWithIter iter ""; - - # Call onDelay functions. - triggerPropertiesDelay = name: attrs: - let - callOnDelay = p@{property, ...}: - if property ? onDelay then - property.onDelay name p - else - p; - in - foldProperty callOnDelay id attrs; - - # Call onGlobalDelay functions. - triggerPropertiesGlobalDelay = name: attrs: - let - globalDelayFuns = uniqListExt { - getter = property: property._type; - inputList = foldProperty (p@{property, content, ...}: - if property ? onGlobalDelay then - [ property ] ++ content - else - content - ) (a: []) attrs; - }; - - callOnGlobalDelay = property: content: - property.onGlobalDelay name content; - in - fold callOnGlobalDelay attrs globalDelayFuns; - - # Expect a list of values which may have properties and return the same - # list of values where all properties have been evaluated and where all - # ignored values are removed. This trigger property handlers called - # `onEval' and `onGlobalEval'. - evalProperties = valList: - if valList != [] then - filter (x: !isNotdef x) ( - triggerPropertiesGlobalEval ( - evalLocalProperties valList - ) - ) - else - valList; - - evalLocalProperties = valList: - filter (x: !isNotdef x) ( - map triggerPropertiesEval valList - ); - - # Call onEval function - triggerPropertiesEval = val: - foldProperty (p@{property, ...}: - if property ? onEval then - property.onEval p - else - p - ) id val; - - # Call onGlobalEval function - triggerPropertiesGlobalEval = valList: - let - globalEvalFuns = uniqListExt { - getter = property: property._type; - inputList = - fold (attrs: list: - foldProperty (p@{property, content, ...}: - if property ? onGlobalEval then - [ property ] ++ content - else - content - ) (a: list) attrs - ) [] valList; - }; - - callOnGlobalEval = property: valList: property.onGlobalEval valList; - in - fold callOnGlobalEval valList globalEvalFuns; - - # Remove all properties on top of a value and return the value. - rmProperties = - foldProperty (p@{content, ...}: content) id; - - # Copy properties defined on a value on another value. - copyProperties = attrs: newAttrs: - foldProperty id (x: newAttrs) attrs; - - /* Merge. */ - - # Create "merge" statement which is skipped by the delayProperty function - # and interpreted by the underlying system using properties (modules). - - # Create a "Merge" property which only contains a condition. - isMerge = isType "merge"; - mkMerge = content: mkProperty { - property = { - _type = "merge"; - onDelay = name: val: throw "mkMerge is not the first of the list of properties."; - onEval = val: throw "mkMerge is not allowed on option definitions."; - }; - inherit content; - }; - - /* If. ThenElse. Always. */ - - # create "if" statement that can be delayed on sets until a "then-else" or - # "always" set is reached. When an always set is reached the condition - # is ignore. - - # Create a "If" property which only contains a condition. - isIf = isType "if"; - mkIf = condition: content: mkProperty { - property = { - _type = "if"; - onGlobalDelay = onIfGlobalDelay; - onEval = onIfEval; - inherit condition; - }; - inherit content; - }; - - mkAssert = assertion: message: content: - mkIf - (if assertion then true else throw "\nFailed assertion: ${message}") - content; - - # Evaluate the "If" statements when either "ThenElse" or "Always" - # statement is encountered. Otherwise it removes multiple If statements and - # replaces them by one "If" statement where the condition is the list of all - # conditions joined with a "and" operation. - onIfGlobalDelay = name: content: - let - # extract if statements and non-if statements and repectively put them - # in the attribute list and attrs. - ifProps = - foldProperty - (foldFilter (p: isIf p) - # then, push the condition inside the list list - (p@{property, content, ...}: - { inherit (content) attrs; - list = [property] ++ content.list; - } - ) - # otherwise, add the propertie. - (p@{property, content, ...}: - { inherit (content) list; - attrs = p // { content = content.attrs; }; - } - ) - ) - (attrs: { list = []; inherit attrs; }) - content; - - # compute the list of if statements. - evalIf = content: condition: list: - if list == [] then - mkIf condition content - else - let p = head list; in - evalIf content (condition && p.condition) (tail list); - in - evalIf ifProps.attrs true ifProps.list; - - # Evaluate the condition of the "If" statement to either get the value or - # to ignore the value. - onIfEval = p@{property, content, ...}: - if property.condition then - content - else - mkNotdef; - - /* mkOverride */ - - # Create an "Override" statement which allow the user to define - # priorities between values. The default priority is 100. The lowest - # priorities are kept. The template argument must reproduce the same - # attribute set hierarchy to override leaves of the hierarchy. - isOverride = isType "override"; - mkOverrideTemplate = priority: template: content: mkProperty { - property = { - _type = "override"; - onDelay = onOverrideDelay; - onGlobalEval = onOverrideGlobalEval; - inherit priority template; - }; - inherit content; - }; - - # Like mkOverrideTemplate, but without the template argument. - mkOverride = priority: content: mkOverrideTemplate priority {} content; - - # Sugar to override the default value of the option by making a new - # default value based on the configuration. - mkDefaultValue = mkOverride 1000; - mkDefault = mkOverride 1000; - mkForce = mkOverride 50; - mkStrict = mkOverride 0; - - # Make the template traversal in function of the property traversal. If - # the template define a non-empty attribute set, then the property is - # copied only on all mentionned attributes inside the template. - # Otherwise, the property is kept on all sub-attribute definitions. - onOverrideDelay = name: p@{property, content, ...}: - let inherit (property) template; in - if isAttrs template && template != {} then - if hasAttr name template then - p // { - property = p.property // { - template = builtins.getAttr name template; - }; - } - # Do not override the attribute \name\ - else - content - # Override values defined inside the attribute \name\. - else - p; - - # Keep values having lowest priority numbers only throwing away those having - # a higher priority assigned. - onOverrideGlobalEval = valList: - let - defaultPrio = 100; - - inherit (builtins) lessThan; - - getPrioVal = - foldProperty - (foldFilter isOverride - (p@{property, content, ...}: - if content ? priority && lessThan content.priority property.priority then - content - else - content // { - inherit (property) priority; - } - ) - (p@{property, content, ...}: - content // { - value = p // { content = content.value; }; - } - ) - ) (value: { inherit value; }); - - addDefaultPrio = x: - if x ? priority then x - else x // { priority = defaultPrio; }; - - prioValList = map (x: addDefaultPrio (getPrioVal x)) valList; - - higherPrio = - if prioValList == [] then - defaultPrio - else - fold (x: min: - if lessThan x.priority min then - x.priority - else - min - ) (head prioValList).priority (tail prioValList); - in - map (x: - if x.priority == higherPrio then - x.value - else - mkNotdef - ) prioValList; - - /* mkOrder */ - - # Order definitions based on there index value. This property is useful - # when the result of the merge function depends on the order on the - # initial list. (e.g. concatStrings) Definitions are ordered based on - # their rank. The lowest ranked definition would be the first to element - # of the list used by the merge function. And the highest ranked - # definition would be the last. Definitions which does not have any rank - # value have the default rank of 100. - isOrder = isType "order"; - mkOrder = rank: content: mkProperty { - property = { - _type = "order"; - onGlobalEval = onOrderGlobalEval; - inherit rank; - }; - inherit content; - }; - - mkHeader = mkOrder 10; - mkFooter = mkOrder 1000; - - # Fetch the rank of each definition (add the default rank is none) and - # sort them based on their ranking. - onOrderGlobalEval = valList: - let - defaultRank = 100; - - inherit (builtins) lessThan; - - getRankVal = - foldProperty - (foldFilter isOrder - (p@{property, content, ...}: - if content ? rank then - content - else - content // { - inherit (property) rank; - } - ) - (p@{property, content, ...}: - content // { - value = p // { content = content.value; }; - } - ) - ) (value: { inherit value; }); - - addDefaultRank = x: - if x ? rank then x - else x // { rank = defaultRank; }; - - rankValList = map (x: addDefaultRank (getRankVal x)) valList; - - cmp = x: y: - builtins.lessThan x.rank y.rank; - in - map (x: x.value) (sort cmp rankValList); - - /* mkFixStrictness */ - - # This is a hack used to restore laziness on some option definitions. - # Some option definitions are evaluated when they are not used. This - # error is caused by the strictness of type checking builtins. Builtins - # like 'isAttrs' are too strict because they have to evaluate their - # arguments to check if the type is correct. This evaluation, cause the - # strictness of properties. - # - # Properties can be stacked on top of each other. The stackability of - # properties on top of the option definition is nice for user manipulation - # but require to check if the content of the property is not another - # property. Such testing implies to verify if this is an attribute set - # and if it possess the type 'property'. (see isProperty & typeOf/isType) - # - # To avoid strict evaluation of option definitions, 'mkFixStrictness' is - # introduced. This property protects an option definition by replacing - # the base of the stack of properties by 'mkNotDef', when this property is - # evaluated it returns the original definition. - # - # This property is useful over any elements which depends on options which - # are raising errors when they get evaluated without the proper settings. - # - # Plain list and attribute set are lazy structures, which means that the - # container gets evaluated but not the content. Thus, using this property - # on top of plain list or attribute set is pointless. - # - # This is a Hack, you should avoid it! - - # This property has a long name because you should avoid it. - isFixStrictness = attrs: (typeOf attrs) == "fix-strictness"; - mkFixStrictness = value: - mkProperty { - property = { - _type = "fix-strictness"; - onEval = p: value; - }; - content = mkNotdef; - }; - -} diff --git a/pkgs/lib/sources.nix b/pkgs/lib/sources.nix deleted file mode 100644 index 6f8554d340be3..0000000000000 --- a/pkgs/lib/sources.nix +++ /dev/null @@ -1,29 +0,0 @@ -# Functions for copying sources to the Nix store. - -let lib = import ./default.nix; in - -rec { - - - # Bring in a path as a source, filtering out all Subversion and CVS - # directories, as well as backup files (*~). - cleanSource = - let filter = name: type: let baseName = baseNameOf (toString name); in ! ( - # Filter out Subversion and CVS directories. - (type == "directory" && (baseName == ".git" || baseName == ".svn" || baseName == "CVS")) || - # Filter out backup files. - (lib.hasSuffix "~" baseName) - ); - in src: builtins.filterSource filter src; - - - # Get all files ending with the specified suffices from the given - # directory. E.g. `sourceFilesBySuffices ./dir [".xml" ".c"]'. - sourceFilesBySuffices = path: exts: - let filter = name: type: - let base = baseNameOf (toString name); - in type != "directory" && lib.any (ext: lib.hasSuffix ext base) exts; - in builtins.filterSource filter path; - - -} diff --git a/pkgs/lib/strings-with-deps.nix b/pkgs/lib/strings-with-deps.nix deleted file mode 100644 index 3ad3e5991506c..0000000000000 --- a/pkgs/lib/strings-with-deps.nix +++ /dev/null @@ -1,78 +0,0 @@ -/* -Usage: - - You define you custom builder script by adding all build steps to a list. - for example: - builder = writeScript "fsg-4.4-builder" - (textClosure [doUnpack addInputs preBuild doMake installPhase doForceShare]); - - a step is defined by noDepEntry, fullDepEntry or packEntry. - To ensure that prerequisite are met those are added before the task itself by - textClosureDupList. Duplicated items are removed again. - - See trace/nixpkgs/trunk/pkgs/top-level/builder-defs.nix for some predefined build steps - - Attention: - - let - pkgs = (import /etc/nixos/nixpkgs/pkgs/top-level/all-packages.nix) {}; - in let - inherit (pkgs.stringsWithDeps) fullDepEntry packEntry noDepEntry textClosureMap; - inherit (pkgs.lib) id; - - nameA = noDepEntry "Text a"; - nameB = fullDepEntry "Text b" ["nameA"]; - nameC = fullDepEntry "Text c" ["nameA"]; - - stages = { - nameHeader = noDepEntry "#! /bin/sh \n"; - inherit nameA nameB nameC; - }; - in - textClosureMap id stages - [ "nameHeader" "nameA" "nameB" "nameC" - nameC # <- added twice. add a dep entry if you know that it will be added once only [1] - "nameB" # <- this will not be added again because the attr name (reference) is used - ] - - # result: Str("#! /bin/sh \n\nText a\nText b\nText c\nText c",[]) - - [1] maybe this behaviour should be removed to keep things simple (?) -*/ - -with import ./lists.nix; -with import ./attrsets.nix; -with import ./strings.nix; - -rec { - - /* !!! The interface of this function is kind of messed up, since - it's way too overloaded and almost but not quite computes a - topological sort of the depstrings. */ - - textClosureList = predefined: arg: - let - f = done: todo: - if todo == [] then {result = []; inherit done;} - else - let entry = head todo; in - if isAttrs entry then - let x = f done entry.deps; - y = f x.done (tail todo); - in { result = x.result ++ [entry.text] ++ y.result; - done = y.done; - } - else if hasAttr entry done then f done (tail todo) - else f (done // listToAttrs [{name = entry; value = 1;}]) ([(builtins.getAttr entry predefined)] ++ tail todo); - in (f {} arg).result; - - textClosureMap = f: predefined: names: - concatStringsSep "\n" (map f (textClosureList predefined names)); - - noDepEntry = text: {inherit text; deps = [];}; - fullDepEntry = text: deps: {inherit text deps;}; - packEntry = deps: {inherit deps; text="";}; - - stringAfter = deps: text: { inherit text deps; }; - -} diff --git a/pkgs/lib/strings.nix b/pkgs/lib/strings.nix deleted file mode 100644 index 024a9ac7d7a27..0000000000000 --- a/pkgs/lib/strings.nix +++ /dev/null @@ -1,190 +0,0 @@ -/* String manipulation functions. */ - -let lib = import ./default.nix; - -inherit (builtins) add sub lessThan length; - -in - -rec { - inherit (builtins) stringLength substring head tail; - - - # Concatenate a list of strings. - concatStrings = lib.fold (x: y: x + y) ""; - - - # Map a function over a list and concatenate the resulting strings. - concatMapStrings = f: list: concatStrings (map f list); - concatImapStrings = f: list: concatStrings (lib.imap f list); - - - # Place an element between each element of a list, e.g., - # `intersperse "," ["a" "b" "c"]' returns ["a" "," "b" "," "c"]. - intersperse = separator: list: - if list == [] || length list == 1 - then list - else [(head list) separator] - ++ (intersperse separator (tail list)); - - - # Concatenate a list of strings with a separator between each element, e.g. - # concatStringsSep " " ["foo" "bar" "xyzzy"] == "foo bar xyzzy" - concatStringsSep = separator: list: - concatStrings (intersperse separator list); - - - # Construct a Unix-style search path consisting of each `subDir" - # directory of the given list of packages. For example, - # `makeSearchPath "bin" ["x" "y" "z"]' returns "x/bin:y/bin:z/bin". - makeSearchPath = subDir: packages: - concatStringsSep ":" (map (path: path + "/" + subDir) packages); - - - # Construct a library search path (such as RPATH) containing the - # libraries for a set of packages, e.g. "${pkg1}/lib:${pkg2}/lib:...". - makeLibraryPath = makeSearchPath "lib"; - - - # Idem for Perl search paths. - makePerlPath = makeSearchPath "lib/perl5/site_perl"; - - - # Dependening on the boolean `cond', return either the given string - # or the empty string. - optionalString = cond: string: if cond then string else ""; - - - # Determine whether a filename ends in the given suffix. - hasSuffix = ext: fileName: - let lenFileName = stringLength fileName; - lenExt = stringLength ext; - in !(lessThan lenFileName lenExt) && - substring (sub lenFileName lenExt) lenFileName fileName == ext; - - - # Convert a string to a list of characters (i.e. singleton strings). - # For instance, "abc" becomes ["a" "b" "c"]. This allows you to, - # e.g., map a function over each character. However, note that this - # will likely be horribly inefficient; Nix is not a general purpose - # programming language. Complex string manipulations should, if - # appropriate, be done in a derivation. - stringToCharacters = s: let l = stringLength s; in - if l == 0 - then [] - else map (p: substring p 1 s) (lib.range 0 (sub l 1)); - - - # Manipulate a string charcater by character and replace them by strings - # before concatenating the results. - stringAsChars = f: s: - concatStrings ( - map f (stringToCharacters s) - ); - - - # same as vim escape function. - # Each character contained in list is prefixed by "\" - escape = list : string : - stringAsChars (c: if lib.elem c list then "\\${c}" else c) string; - - - # still ugly slow. But more correct now - # [] for zsh - escapeShellArg = lib.escape (stringToCharacters "\\ ';$`()|<>\t*[]"); - - - # replace characters by their substitutes. This function is equivalent to - # the `tr' command except that one character can be replace by multiple - # ones. e.g., - # replaceChars ["<" ">"] ["<" ">"] "<foo>" returns "<foo>". - replaceChars = del: new: s: - let - subst = c: - (lib.fold - (sub: res: if sub.fst == c then sub else res) - {fst = c; snd = c;} (lib.zipLists del new) - ).snd; - in - stringAsChars subst s; - - - # Case conversion utilities - lowerChars = stringToCharacters "abcdefghijklmnopqrstuvwxyz"; - upperChars = stringToCharacters "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - toLower = replaceChars upperChars lowerChars; - toUpper = replaceChars lowerChars upperChars; - - - # Compares strings not requiring context equality - # Obviously, a workaround but works on all Nix versions - eqStrings = a: b: (a+(substring 0 0 b)) == ((substring 0 0 a)+b); - - - # Cut a string with a separator and produces a list of strings which were - # separated by this separator. e.g., - # `splitString "." "foo.bar.baz"' returns ["foo" "bar" "baz"]. - splitString = sep: s: - let - sepLen = stringLength sep; - sLen = stringLength s; - lastSearch = sub sLen sepLen; - startWithSep = startAt: - substring startAt sepLen s == sep; - - recurse = index: startAt: - let cutUntil = i: [(substring startAt (sub i startAt) s)]; in - if lessThan index lastSearch then - if startWithSep index then - let restartAt = add index sepLen; in - cutUntil index ++ recurse restartAt restartAt - else - recurse (add index 1) startAt - else - cutUntil sLen; - in - recurse 0 0; - - - # return the suffix of the second argument if the first argument match its - # prefix. e.g., - # `removePrefix "foo." "foo.bar.baz"' returns "bar.baz". - removePrefix = pre: s: - let - preLen = stringLength pre; - sLen = stringLength s; - in - if pre == substring 0 preLen s then - substring preLen (sub sLen preLen) s - else - s; - - # Return true iff string v1 denotes a version older than v2. - versionOlder = v1: v2: builtins.compareVersions v2 v1 == 1; - - - # Return true iff string v1 denotes a version equal to or newer than v2. - versionAtLeast = v1: v2: !versionOlder v1 v2; - - - # Get the version of the specified derivation, as specified in its - # ‘name’ attribute. - getVersion = drv: (builtins.parseDrvName drv.name).version; - - - # Extract name with version from URL. Ask for separator which is - # supposed to start extension - nameFromURL = url: sep: let - components = splitString "/" url; - filename = lib.last components; - name = builtins.head (splitString sep filename); - in - assert ! eqStrings name filename; - name; - - - # Create an --{enable,disable}-<feat> string that can be passed to - # standard GNU Autoconf scripts. - enableFeature = enable: feat: "--${if enable then "enable" else "disable"}-${feat}"; - -} diff --git a/pkgs/lib/systems.nix b/pkgs/lib/systems.nix deleted file mode 100644 index 1ef869fb01208..0000000000000 --- a/pkgs/lib/systems.nix +++ /dev/null @@ -1,126 +0,0 @@ -# Define the list of system with their properties. Only systems tested for -# Nixpkgs are listed below - -with import ./lists.nix; -with import ./types.nix; -with import ./attrsets.nix; - -let - lib = import ./default.nix; - setTypes = type: - mapAttrs (name: value: - setType type ({inherit name;} // value) - ); -in - -rec { - - isSignificantByte = isType "significant-byte"; - significantBytes = setTypes "significant-byte" { - bigEndian = {}; - littleEndian = {}; - }; - - - isCpuType = x: typeOf x == "cpu-type" - && elem x.bits [8 16 32 64 128] - && (builtins.lessThan 8 x.bits -> isSignificantByte x.significantByte); - - cpuTypes = with significantBytes; - setTypes "cpu-type" { - arm = { bits = 32; significantByte = littleEndian; }; - armv5tel = { bits = 32; significantByte = littleEndian; }; - armv7l = { bits = 32; significantByte = littleEndian; }; - i686 = { bits = 32; significantByte = littleEndian; }; - powerpc = { bits = 32; significantByte = bigEndian; }; - x86_64 = { bits = 64; significantByte = littleEndian; }; - }; - - - isExecFormat = isType "exec-format"; - execFormats = setTypes "exec-format" { - aout = {}; # a.out - elf = {}; - macho = {}; - pe = {}; - unknow = {}; - }; - - - isKernel = isType "kernel"; - kernels = with execFormats; - setTypes "kernel" { - cygwin = { execFormat = pe; }; - darwin = { execFormat = macho; }; - freebsd = { execFormat = elf; }; - linux = { execFormat = elf; }; - netbsd = { execFormat = elf; }; - none = { execFormat = unknow; }; - openbsd = { execFormat = elf; }; - win32 = { execFormat = pe; }; - }; - - - isArchitecture = isType "architecture"; - architectures = setTypes "architecture" { - apple = {}; - pc = {}; - unknow = {}; - }; - - - isSystem = x: typeOf x == "system" - && isCpuType x.cpu - && isArchitecture x.arch - && isKernel x.kernel; - - mkSystem = { - cpu ? cpuTypes.i686, - arch ? architectures.pc, - kernel ? kernels.linux, - name ? "${cpu.name}-${arch.name}-${kernel.name}" - }: setType "system" { - inherit name cpu arch kernel; - }; - - - isDarwin = matchAttrs { kernel = kernels.darwin; }; - isLinux = matchAttrs { kernel = kernels.linux; }; - isi686 = matchAttrs { cpu = cpuTypes.i686; }; - is64Bit = matchAttrs { cpu = { bits = 64; }; }; - - - # This should revert the job done by config.guess from the gcc compiler. - mkSystemFromString = s: let - l = lib.splitString "-" s; - - getCpu = name: - attrByPath [name] (throw "Unknow cpuType `${name}'.") - cpuTypes; - getArch = name: - attrByPath [name] (throw "Unknow architecture `${name}'.") - architectures; - getKernel = name: - attrByPath [name] (throw "Unknow kernel `${name}'.") - kernels; - - system = - if builtins.length l == 2 then - mkSystem rec { - name = s; - cpu = getCpu (head l); - arch = - if isDarwin system - then architectures.apple - else architectures.pc; - kernel = getKernel (head (tail l)); - } - else - mkSystem { - name = s; - cpu = getCpu (head l); - arch = getArch (head (tail l)); - kernel = getKernel (head (tail (tail l))); - }; - in assert isSystem system; system; -} diff --git a/pkgs/lib/tests.nix b/pkgs/lib/tests.nix deleted file mode 100644 index 298bdffc37906..0000000000000 --- a/pkgs/lib/tests.nix +++ /dev/null @@ -1,113 +0,0 @@ -let inherit (builtins) add; in -with import ./default.nix; - -runTests { - - testId = { - expr = id 1; - expected = 1; - }; - - testConst = { - expr = const 2 3; - expected = 2; - }; - - /* - testOr = { - expr = or true false; - expected = true; - }; - */ - - testAnd = { - expr = and true false; - expected = false; - }; - - testFix = { - expr = fix (x: {a = if x ? a then "a" else "b";}); - expected = {a = "a";}; - }; - - testConcatMapStrings = { - expr = concatMapStrings (x: x + ";") ["a" "b" "c"]; - expected = "a;b;c;"; - }; - - testConcatStringsSep = { - expr = concatStringsSep "," ["a" "b" "c"]; - expected = "a,b,c"; - }; - - testFilter = { - expr = filter (x: x != "a") ["a" "b" "c" "a"]; - expected = ["b" "c"]; - }; - - testFold = { - expr = fold (builtins.add) 0 (range 0 100); - expected = 5050; - }; - - testTake = testAllTrue [ - ([] == (take 0 [ 1 2 3 ])) - ([1] == (take 1 [ 1 2 3 ])) - ([ 1 2 ] == (take 2 [ 1 2 3 ])) - ([ 1 2 3 ] == (take 3 [ 1 2 3 ])) - ([ 1 2 3 ] == (take 4 [ 1 2 3 ])) - ]; - - testFoldAttrs = { - expr = foldAttrs (n: a: [n] ++ a) [] [ - { a = 2; b = 7; } - { a = 3; c = 8; } - ]; - expected = { a = [ 2 3 ]; b = [7]; c = [8];}; - }; - - testOverridableDelayableArgsTest = { - expr = - let res1 = defaultOverridableDelayableArgs id {}; - res2 = defaultOverridableDelayableArgs id { a = 7; }; - res3 = let x = defaultOverridableDelayableArgs id { a = 7; }; - in (x.merge) { b = 10; }; - res4 = let x = defaultOverridableDelayableArgs id { a = 7; }; - in (x.merge) ( x: { b = 10; }); - res5 = let x = defaultOverridableDelayableArgs id { a = 7; }; - in (x.merge) ( x: { a = add x.a 3; }); - res6 = let x = defaultOverridableDelayableArgs id { a = 7; mergeAttrBy = { a = add; }; }; - y = x.merge {}; - in (y.merge) { a = 10; }; - - resRem7 = res6.replace (a : removeAttrs a ["a"]); - - resReplace6 = let x = defaultOverridableDelayableArgs id { a = 7; mergeAttrBy = { a = add; }; }; - x2 = x.merge { a = 20; }; # now we have 27 - in (x2.replace) { a = 10; }; # and override the value by 10 - - # fixed tests (delayed args): (when using them add some comments, please) - resFixed1 = - let x = defaultOverridableDelayableArgs id ( x : { a = 7; c = x.fixed.b; }); - y = x.merge (x : { name = "name-${builtins.toString x.fixed.c}"; }); - in (y.merge) { b = 10; }; - strip = attrs : removeAttrs attrs ["merge" "replace"]; - in all id - [ ((strip res1) == { }) - ((strip res2) == { a = 7; }) - ((strip res3) == { a = 7; b = 10; }) - ((strip res4) == { a = 7; b = 10; }) - ((strip res5) == { a = 10; }) - ((strip res6) == { a = 17; }) - ((strip resRem7) == {}) - ((strip resFixed1) == { a = 7; b = 10; c =10; name = "name-10"; }) - ]; - expected = true; - }; - - testSort = { - expr = sort builtins.lessThan [ 40 2 30 42 ]; - expected = [2 30 40 42]; - }; - -} diff --git a/pkgs/lib/trivial.nix b/pkgs/lib/trivial.nix deleted file mode 100644 index 8af3474f2a671..0000000000000 --- a/pkgs/lib/trivial.nix +++ /dev/null @@ -1,38 +0,0 @@ -with { - inherit (import ./lists.nix) deepSeqList; - inherit (import ./attrsets.nix) deepSeqAttrs; -}; - -rec { - - # Identity function. - id = x: x; - - # Constant function. - const = x: y: x; - - # Named versions corresponding to some builtin operators. - concat = x: y: x ++ y; - or = x: y: x || y; - and = x: y: x && y; - mergeAttrs = x: y: x // y; - - # Take a function and evaluate it with its own returned value. - fix = f: let result = f result; in result; - - # Flip the order of the arguments of a binary function. - flip = f: a: b: f b a; - - # `seq x y' evaluates x, then returns y. That is, it forces strict - # evaluation of its first argument. - seq = x: y: if x == null then y else y; - - # Like `seq', but recurses into lists and attribute sets to force evaluation - # of all list elements/attributes. - deepSeq = x: y: - if builtins.isList x - then deepSeqList x y - else if builtins.isAttrs x - then deepSeqAttrs x y - else seq x y; -} diff --git a/pkgs/lib/types.nix b/pkgs/lib/types.nix deleted file mode 100644 index 156d72ac5e73e..0000000000000 --- a/pkgs/lib/types.nix +++ /dev/null @@ -1,226 +0,0 @@ -# Definitions related to run-time type checking. Used in particular -# to type-check NixOS configurations. - -let lib = import ./default.nix; in - -with import ./lists.nix; -with import ./attrsets.nix; -with import ./options.nix; -with import ./trivial.nix; - -rec { - - isType = type: x: (x._type or "") == type; - hasType = x: isAttrs x && x ? _type; - typeOf = x: x._type or ""; - - setType = typeName: value: value // { - _type = typeName; - }; - - - # name (name of the type) - # check (check the config value. Before returning false it should trace the bad value eg using traceValIfNot) - # merge (default merge function) - # iter (iterate on all elements contained in this type) - # fold (fold all elements contained in this type) - # hasOptions (boolean: whatever this option contains an option set) - # delayOnGlobalEval (boolean: should properties go through the evaluation of this option) - # docPath (path concatenated to the option name contained in the option set) - isOptionType = isType "option-type"; - mkOptionType = - { name - , check ? (x: true) - , merge ? mergeDefaultOption - # Handle complex structure types. - , iter ? (f: path: v: f path v) - , fold ? (op: nul: v: op v nul) - , docPath ? lib.id - # If the type can contains option sets. - , hasOptions ? false - , delayOnGlobalEval ? false - }: - - { _type = "option-type"; - inherit name check merge iter fold docPath hasOptions delayOnGlobalEval; - }; - - - types = rec { - - bool = mkOptionType { - name = "boolean"; - check = lib.traceValIfNot builtins.isBool; - merge = fold lib.or false; - }; - - int = mkOptionType { - name = "integer"; - check = lib.traceValIfNot builtins.isInt; - }; - - string = mkOptionType { - name = "string"; - check = lib.traceValIfNot builtins.isString; - merge = lib.concatStrings; - }; - - # Like ‘string’, but add newlines between every value. Useful for - # configuration file contents. - lines = mkOptionType { - name = "string"; - check = lib.traceValIfNot builtins.isString; - merge = lib.concatStringsSep "\n"; - }; - - envVar = mkOptionType { - name = "environment variable"; - inherit (string) check; - merge = lib.concatStringsSep ":"; - }; - - attrs = mkOptionType { - name = "attribute set"; - check = lib.traceValIfNot isAttrs; - merge = fold lib.mergeAttrs {}; - }; - - # derivation is a reserved keyword. - package = mkOptionType { - name = "derivation"; - check = lib.traceValIfNot isDerivation; - }; - - path = mkOptionType { - name = "path"; - # Hacky: there is no ‘isPath’ primop. - check = lib.traceValIfNot (x: builtins.unsafeDiscardStringContext (builtins.substring 0 1 (toString x)) == "/"); - }; - - # drop this in the future: - list = builtins.trace "types.list is deprecated, use types.listOf instead" types.listOf; - - listOf = elemType: mkOptionType { - name = "list of ${elemType.name}s"; - check = value: lib.traceValIfNot isList value && all elemType.check value; - merge = concatLists; - iter = f: path: list: map (elemType.iter f (path + ".*")) list; - fold = op: nul: list: lib.fold (e: l: elemType.fold op l e) nul list; - docPath = path: elemType.docPath (path + ".*"); - inherit (elemType) hasOptions; - - # You cannot define multiple configurations of one entity, therefore - # no reason justify to delay properties inside list elements. - delayOnGlobalEval = false; - }; - - attrsOf = elemType: mkOptionType { - name = "attribute set of ${elemType.name}s"; - check = x: lib.traceValIfNot isAttrs x - && all elemType.check (lib.attrValues x); - merge = lib.zipAttrsWith (name: elemType.merge); - iter = f: path: set: lib.mapAttrs (name: elemType.iter f (path + "." + name)) set; - fold = op: nul: set: fold (e: l: elemType.fold op l e) nul (lib.attrValues set); - docPath = path: elemType.docPath (path + ".<name>"); - inherit (elemType) hasOptions delayOnGlobalEval; - }; - - # List or attribute set of ... - loaOf = elemType: - let - convertIfList = defIdx: def: - if isList def then - listToAttrs ( - flip imap def (elemIdx: elem: - nameValuePair "unnamed-${toString defIdx}.${toString elemIdx}" elem)) - else - def; - listOnly = listOf elemType; - attrOnly = attrsOf elemType; - - in mkOptionType { - name = "list or attribute set of ${elemType.name}s"; - check = x: - if isList x then listOnly.check x - else if isAttrs x then attrOnly.check x - else lib.traceValIfNot (x: false) x; - ## The merge function returns an attribute set - merge = defs: - attrOnly.merge (imap convertIfList defs); - iter = f: path: def: - if isList def then listOnly.iter f path def - else if isAttrs def then attrOnly.iter f path def - else throw "Unexpected value"; - fold = op: nul: def: - if isList def then listOnly.fold op nul def - else if isAttrs def then attrOnly.fold op nul def - else throw "Unexpected value"; - - docPath = path: elemType.docPath (path + ".<name?>"); - inherit (elemType) hasOptions delayOnGlobalEval; - } - ; - - uniq = elemType: mkOptionType { - inherit (elemType) name check iter fold docPath hasOptions; - merge = list: - if length list == 1 then - head list - else - throw "Multiple definitions of ${elemType.name}. Only one is allowed for this option."; - }; - - none = elemType: mkOptionType { - inherit (elemType) name check iter fold docPath hasOptions; - merge = list: - throw "No definitions are allowed for this option."; - }; - - nullOr = elemType: mkOptionType { - inherit (elemType) name merge docPath hasOptions; - check = x: builtins.isNull x || elemType.check x; - iter = f: path: v: if v == null then v else elemType.iter f path v; - fold = op: nul: v: if v == null then nul else elemType.fold op nul v; - }; - - functionTo = elemType: mkOptionType { - name = "function that evaluates to a(n) ${elemType.name}"; - check = lib.traceValIfNot builtins.isFunction; - merge = fns: - args: elemType.merge (map (fn: fn args) fns); - # These are guesses, I don't fully understand iter, fold, delayOnGlobalEval - iter = f: path: v: - args: elemType.iter f path (v args); - fold = op: nul: v: - args: elemType.fold op nul (v args); - inherit (elemType) delayOnGlobalEval; - hasOptions = false; - }; - - # usually used with listOf, attrsOf, loaOf like this: - # users = mkOption { - # type = loaOf optionSet; - # - # # you can omit the list if there is one element only - # options = [ { - # name = mkOption { - # description = "name of the user" - # ... - # }; - # # more options here - # } { more options } ]; - # } - # TODO: !!! document passing options as an argument to optionSet, - # deprecate the current approach. - optionSet = mkOptionType { - name = "option set"; - # merge is done in "options.nix > addOptionMakeUp > handleOptionSets" - merge = lib.id; - check = x: isAttrs x || builtins.isFunction x; - hasOptions = true; - delayOnGlobalEval = true; - }; - - }; - -} |