Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
1{ lib }:
2with builtins; with lib; recursiveUpdate lib (rec {
3
4 versions =
5 let
6 truncate = n: v: concatStringsSep "." (take n (splitVersion v));
7 opTruncate = op: v0: v: let n = length (splitVersion v0); in
8 op (truncate n v) (truncate n v0);
9 in rec {
10
11 /* Get string of the first n parts of a version string.
12
13 Example:
14 - truncate 2 "1.2.3-stuff"
15 => "1.2"
16
17 - truncate 4 "1.2.3-stuff"
18 => "1.2.3.stuff"
19 */
20
21 inherit truncate;
22
23 /* Get string of the first three parts (major, minor and patch)
24 of a version string.
25
26 Example:
27 majorMinorPatch "1.2.3-stuff"
28 => "1.2.3"
29 */
30 majorMinorPatch = truncate 3;
31
32 /* Version comparison predicates,
33 - isGe v0 v <-> v is greater or equal than v0 [*]
34 - isLe v0 v <-> v is lesser or equal than v0 [*]
35 - isGt v0 v <-> v is strictly greater than v0 [*]
36 - isLt v0 v <-> v is strictly lesser than v0 [*]
37 - isEq v0 v <-> v is equal to v0 [*]
38 - range low high v <-> v is between low and high [**]
39
40 [*] truncating v to the same number of digits as v0
41 [**] truncating v to low for the lower bound and high for the upper bound
42
43 Examples:
44 - isGe "8.10" "8.10.1"
45 => true
46 - isLe "8.10" "8.10.1"
47 => true
48 - isGt "8.10" "8.10.1"
49 => false
50 - isGt "8.10.0" "8.10.1"
51 => true
52 - isEq "8.10" "8.10.1"
53 => true
54 - range "8.10" "8.11" "8.11.1"
55 => true
56 - range "8.10" "8.11+" "8.11.0"
57 => false
58 - range "8.10" "8.11+" "8.11+beta1"
59 => false
60
61 */
62 isGe = opTruncate versionAtLeast;
63 isGt = opTruncate (flip versionOlder);
64 isLe = opTruncate (flip versionAtLeast);
65 isLt = opTruncate versionOlder;
66 isEq = opTruncate pred.equal;
67 range = low: high: pred.inter (versions.isGe low) (versions.isLe high);
68 };
69
70 /* Returns a list of list, splitting it using a predicate.
71 This is analoguous to builtins.split sep list,
72 with a predicate as a separator and a list instead of a string.
73
74 Type: splitList :: (a -> bool) -> [a] -> [[a]]
75
76 Example:
77 splitList (x: x == "x") [ "y" "x" "z" "t" ]
78 => [ [ "y" ] "x" [ "z" "t" ] ]
79 */
80 splitList = pred: l: # put in file lists
81 let loop = (vv: v: l: if l == [] then vv ++ [v]
82 else let hd = head l; tl = tail l; in
83 if pred hd then loop (vv ++ [ v hd ]) [] tl else loop vv (v ++ [hd]) tl);
84 in loop [] [] l;
85
86 pred = {
87 /* Predicate intersection, union, and complement */
88 inter = p: q: x: p x && q x;
89 union = p: q: x: p x || q x;
90 compl = p: x: ! p x;
91 true = p: true;
92 false = p: false;
93
94 /* predicate "being equal to y" */
95 equal = y: x: x == y;
96 };
97
98 /* Emulate a "switch - case" construct,
99 instead of relying on `if then else if ...` */
100 /* Usage:
101 ```nix
102 switch-if [
103 if-clause-1
104 ..
105 if-clause-k
106 ] default-out
107 ```
108 where a if-clause has the form `{ cond = b; out = r; }`
109 the first branch such as `b` is true */
110
111 switch-if = c: d: (findFirst (getAttr "cond") {} c).out or d;
112
113 /* Usage:
114 ```nix
115 switch x [
116 simple-clause-1
117 ..
118 simple-clause-k
119 ] default-out
120 ```
121 where a simple-clause has the form `{ case = p; out = r; }`
122 the first branch such as `p x` is true
123 or
124 ```nix
125 switch [ x1 .. xn ] [
126 complex-clause-1
127 ..
128 complex-clause-k
129 ] default-out
130 ```
131 where a complex-clause is either a simple-clause
132 or has the form { cases = [ p1 .. pn ]; out = r; }
133 in which case the first branch such as all `pi x` are true
134
135 if the variables p are not functions,
136 they are converted to a equal p
137 if out is missing the default-out is taken */
138
139 switch = var: clauses: default: with pred; let
140 compare = f: if isFunction f then f else equal f;
141 combine = cl: var:
142 if cl?case then compare cl.case var
143 else all (equal true) (zipListsWith compare cl.cases var); in
144 switch-if (map (cl: { cond = combine cl var; inherit (cl) out; }) clauses) default;
145
146 /* Override arguments to mkCoqDerivation for a Coq library.
147
148 This function allows you to easily override arguments to mkCoqDerivation,
149 even when they are not exposed by the Coq library directly.
150
151 Type: overrideCoqDerivation :: AttrSet -> CoqLibraryDerivation -> CoqLibraryDerivation
152
153 Example:
154
155 ```nix
156 coqPackages.lib.overrideCoqDerivation
157 {
158 defaultVersion = "9999";
159 release."9999".sha256 = "1lq8x86vd3vqqh2yq6hvyagpnhfq5wmk5pg2z0xq7b7dbbbhyfkw";
160 }
161 coqPackages.QuickChick;
162 ```
163
164 This example overrides the `defaultVersion` and `release` arguments that
165 are passed to `mkCoqDerivation` in the QuickChick derivation.
166
167 Note that there is a difference between using `.override` on a Coq
168 library vs this `overrideCoqDerivation` function. `.override` allows you
169 to modify arguments to the derivation itself, for instance by passing
170 different versions of dependencies:
171
172 ```nix
173 coqPackages.QuickChick.override { ssreflect = my-cool-ssreflect; }
174 ```
175
176 whereas `overrideCoqDerivation` allows you to override arguments to the
177 call to `mkCoqDerivation` in the Coq library.
178
179 Note that all Coq libraries in Nixpkgs have a `version` argument for
180 easily using a different version. So if all you want to do is use a
181 different version, and the derivation for the Coq library already has
182 support for the version you want, you likely only need to update the
183 `version` argument on the library derivation. This is done with
184 `.override`:
185
186 ```nix
187 coqPackages.QuickChick.override { version = "1.4.0"; }
188 ```
189 */
190 overrideCoqDerivation = f: drv: (drv.override (args: {
191 mkCoqDerivation = drv_: (args.mkCoqDerivation drv_).override f;
192 }));
193})