Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at netboot-syslinux-multiplatform 193 lines 5.9 kB view raw
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})