| 
									
										
										
										
											2017-07-28 20:05:35 -04:00
										 |  |  |  | { lib }: | 
					
						
							| 
									
										
										
										
											2018-07-26 00:10:53 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-09 16:51:03 +00:00
										 |  |  |  | rec { | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-26 00:03:51 +02:00
										 |  |  |  |   ## Simple (higher order) functions | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-15 18:29:33 +01:00
										 |  |  |  |   /* The identity function
 | 
					
						
							|  |  |  |  |      For when you need a function that does “nothing”. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |      Type: id :: a -> a | 
					
						
							|  |  |  |  |   */ | 
					
						
							| 
									
										
										
										
											2018-10-27 16:40:04 +02:00
										 |  |  |  |   id = | 
					
						
							|  |  |  |  |     # The value to return | 
					
						
							|  |  |  |  |     x: x; | 
					
						
							| 
									
										
										
										
											2009-02-09 16:51:03 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-15 18:29:33 +01:00
										 |  |  |  |   /* The constant function
 | 
					
						
							| 
									
										
										
										
											2018-10-27 16:40:04 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |      Ignores the second argument. If called with only one argument, | 
					
						
							|  |  |  |  |      constructs a function that always returns a static value. | 
					
						
							| 
									
										
										
										
											2017-03-15 18:29:33 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |      Type: const :: a -> b -> a | 
					
						
							|  |  |  |  |      Example: | 
					
						
							|  |  |  |  |        let f = const 5; in f 10 | 
					
						
							|  |  |  |  |        => 5 | 
					
						
							|  |  |  |  |   */ | 
					
						
							| 
									
										
										
										
											2018-10-27 16:40:04 +02:00
										 |  |  |  |   const = | 
					
						
							|  |  |  |  |     # Value to return | 
					
						
							|  |  |  |  |     x: | 
					
						
							|  |  |  |  |     # Value to ignore | 
					
						
							|  |  |  |  |     y: x; | 
					
						
							| 
									
										
										
										
											2009-02-09 16:51:03 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-18 17:57:33 +02:00
										 |  |  |  |   /* Pipes a value through a list of functions, left to right.
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |      Type: pipe :: a -> [<functions>] -> <return type of last function> | 
					
						
							|  |  |  |  |      Example: | 
					
						
							|  |  |  |  |        pipe 2 [ | 
					
						
							|  |  |  |  |          (x: x + 2)  # 2 + 2 = 4 | 
					
						
							|  |  |  |  |          (x: x * 2)  # 4 * 2 = 8 | 
					
						
							|  |  |  |  |        ] | 
					
						
							|  |  |  |  |        => 8 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |        # ideal to do text transformations | 
					
						
							|  |  |  |  |        pipe [ "a/b" "a/c" ] [ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |          # create the cp command | 
					
						
							|  |  |  |  |          (map (file: ''cp "${src}/${file}" $out\n'')) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |          # concatenate all commands into one string | 
					
						
							|  |  |  |  |          lib.concatStrings | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |          # make that string into a nix derivation | 
					
						
							|  |  |  |  |          (pkgs.runCommand "copy-to-out" {}) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |        ] | 
					
						
							|  |  |  |  |        => <drv which copies all files to $out> | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |      The output type of each function has to be the input type | 
					
						
							|  |  |  |  |      of the next function, and the last function returns the | 
					
						
							|  |  |  |  |      final value. | 
					
						
							|  |  |  |  |   */ | 
					
						
							|  |  |  |  |   pipe = val: functions: | 
					
						
							|  |  |  |  |     let reverseApply = x: f: f x; | 
					
						
							|  |  |  |  |     in builtins.foldl' reverseApply val functions; | 
					
						
							|  |  |  |  |   /* note please don’t add a function like `compose = flip pipe`.
 | 
					
						
							|  |  |  |  |      This would confuse users, because the order of the functions | 
					
						
							|  |  |  |  |      in the list is not clear. With pipe, it’s obvious that it | 
					
						
							|  |  |  |  |      goes first-to-last. With `compose`, not so much. | 
					
						
							|  |  |  |  |   */ | 
					
						
							| 
									
										
										
										
											2017-03-15 18:29:33 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   ## Named versions corresponding to some builtin operators. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-27 16:40:04 +02:00
										 |  |  |  |   /* Concatenate two lists
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |      Type: concat :: [a] -> [a] -> [a] | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |      Example: | 
					
						
							|  |  |  |  |        concat [ 1 2 ] [ 3 4 ] | 
					
						
							|  |  |  |  |        => [ 1 2 3 4 ] | 
					
						
							|  |  |  |  |   */ | 
					
						
							| 
									
										
										
										
											2009-02-09 16:51:03 +00:00
										 |  |  |  |   concat = x: y: x ++ y; | 
					
						
							| 
									
										
										
										
											2017-03-15 18:29:33 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   /* boolean “or” */ | 
					
						
							| 
									
										
										
										
											2009-02-09 16:51:03 +00:00
										 |  |  |  |   or = x: y: x || y; | 
					
						
							| 
									
										
										
										
											2017-03-15 18:29:33 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   /* boolean “and” */ | 
					
						
							| 
									
										
										
										
											2009-02-09 16:51:03 +00:00
										 |  |  |  |   and = x: y: x && y; | 
					
						
							| 
									
										
										
										
											2017-03-15 18:29:33 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-10 19:25:48 +00:00
										 |  |  |  |   /* bitwise “and” */ | 
					
						
							| 
									
										
										
										
											2018-07-26 00:10:53 +02:00
										 |  |  |  |   bitAnd = builtins.bitAnd | 
					
						
							| 
									
										
										
										
											2018-09-03 14:10:54 +02:00
										 |  |  |  |     or (import ./zip-int-bits.nix | 
					
						
							|  |  |  |  |         (a: b: if a==1 && b==1 then 1 else 0)); | 
					
						
							| 
									
										
										
										
											2018-06-10 19:25:48 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   /* bitwise “or” */ | 
					
						
							| 
									
										
										
										
											2018-07-26 00:10:53 +02:00
										 |  |  |  |   bitOr = builtins.bitOr | 
					
						
							| 
									
										
										
										
											2018-09-03 14:10:54 +02:00
										 |  |  |  |     or (import ./zip-int-bits.nix | 
					
						
							|  |  |  |  |         (a: b: if a==1 || b==1 then 1 else 0)); | 
					
						
							| 
									
										
										
										
											2018-06-10 19:25:48 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   /* bitwise “xor” */ | 
					
						
							| 
									
										
										
										
											2018-07-26 00:10:53 +02:00
										 |  |  |  |   bitXor = builtins.bitXor | 
					
						
							| 
									
										
										
										
											2018-09-03 14:10:54 +02:00
										 |  |  |  |     or (import ./zip-int-bits.nix | 
					
						
							|  |  |  |  |         (a: b: if a!=b then 1 else 0)); | 
					
						
							| 
									
										
										
										
											2018-06-10 19:25:48 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   /* bitwise “not” */ | 
					
						
							|  |  |  |  |   bitNot = builtins.sub (-1); | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-11 18:08:51 +02:00
										 |  |  |  |   /* Convert a boolean to a string.
 | 
					
						
							| 
									
										
										
										
											2018-10-27 16:40:04 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |      This function uses the strings "true" and "false" to represent | 
					
						
							|  |  |  |  |      boolean values. Calling `toString` on a bool instead returns "1" | 
					
						
							|  |  |  |  |      and "" (sic!). | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |      Type: boolToString :: bool -> string | 
					
						
							| 
									
										
										
										
											2017-04-11 18:08:51 +02:00
										 |  |  |  |   */ | 
					
						
							|  |  |  |  |   boolToString = b: if b then "true" else "false"; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-15 18:29:33 +01:00
										 |  |  |  |   /* Merge two attribute sets shallowly, right side trumps left
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-27 16:40:04 +02:00
										 |  |  |  |      mergeAttrs :: attrs -> attrs -> attrs | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-15 18:29:33 +01:00
										 |  |  |  |      Example: | 
					
						
							| 
									
										
										
										
											2017-04-25 14:36:22 +08:00
										 |  |  |  |        mergeAttrs { a = 1; b = 2; } { b = 3; c = 4; } | 
					
						
							| 
									
										
										
										
											2017-03-15 18:29:33 +01:00
										 |  |  |  |        => { a = 1; b = 3; c = 4; } | 
					
						
							|  |  |  |  |   */ | 
					
						
							| 
									
										
										
										
											2018-10-27 16:40:04 +02:00
										 |  |  |  |   mergeAttrs = | 
					
						
							|  |  |  |  |     # Left attribute set | 
					
						
							|  |  |  |  |     x: | 
					
						
							|  |  |  |  |     # Right attribute set (higher precedence for equal keys) | 
					
						
							|  |  |  |  |     y: x // y; | 
					
						
							| 
									
										
										
										
											2013-11-12 13:48:19 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-26 00:03:51 +02:00
										 |  |  |  |   /* Flip the order of the arguments of a binary function.
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-27 16:40:04 +02:00
										 |  |  |  |      Type: flip :: (a -> b -> c) -> (b -> a -> c) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-26 00:03:51 +02:00
										 |  |  |  |      Example: | 
					
						
							|  |  |  |  |        flip concat [1] [2] | 
					
						
							|  |  |  |  |        => [ 2 1 ] | 
					
						
							|  |  |  |  |   */ | 
					
						
							| 
									
										
										
										
											2009-10-23 07:34:56 +00:00
										 |  |  |  |   flip = f: a: b: f b a; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-27 16:40:04 +02:00
										 |  |  |  |   /* Apply function if the supplied argument is non-null.
 | 
					
						
							| 
									
										
										
										
											2018-07-26 00:03:51 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |      Example: | 
					
						
							|  |  |  |  |        mapNullable (x: x+1) null | 
					
						
							|  |  |  |  |        => null | 
					
						
							|  |  |  |  |        mapNullable (x: x+1) 22 | 
					
						
							|  |  |  |  |        => 23 | 
					
						
							|  |  |  |  |   */ | 
					
						
							| 
									
										
										
										
											2018-10-27 16:40:04 +02:00
										 |  |  |  |   mapNullable = | 
					
						
							|  |  |  |  |     # Function to call | 
					
						
							|  |  |  |  |     f: | 
					
						
							|  |  |  |  |     # Argument to check for null before passing it to `f` | 
					
						
							| 
									
										
										
										
											2019-04-24 05:48:22 +02:00
										 |  |  |  |     a: if a == null then a else f a; | 
					
						
							| 
									
										
										
										
											2017-04-17 16:48:10 -04:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-12 13:48:19 +01:00
										 |  |  |  |   # Pull in some builtins not included elsewhere. | 
					
						
							|  |  |  |  |   inherit (builtins) | 
					
						
							| 
									
										
										
										
											2018-01-31 14:02:19 -05:00
										 |  |  |  |     pathExists readFile isBool | 
					
						
							| 
									
										
										
										
											2018-06-30 21:13:49 +02:00
										 |  |  |  |     isInt isFloat add sub lessThan | 
					
						
							| 
									
										
										
										
											2015-07-23 17:41:35 +02:00
										 |  |  |  |     seq deepSeq genericClosure; | 
					
						
							| 
									
										
										
										
											2013-11-12 13:48:19 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-31 21:59:30 +09:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-26 00:03:51 +02:00
										 |  |  |  |   ## nixpks version strings | 
					
						
							| 
									
										
										
										
											2018-04-24 20:33:35 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-27 16:40:04 +02:00
										 |  |  |  |   /* Returns the current full nixpkgs version number. */ | 
					
						
							| 
									
										
										
										
											2018-04-26 10:31:05 +02:00
										 |  |  |  |   version = release + versionSuffix; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-27 16:40:04 +02:00
										 |  |  |  |   /* Returns the current nixpkgs release number as string. */ | 
					
						
							| 
									
										
										
										
											2018-07-26 00:03:51 +02:00
										 |  |  |  |   release = lib.strings.fileContents ../.version; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-15 21:51:29 +01:00
										 |  |  |  |   /* Returns the current nixpkgs release code name.
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |      On each release the first letter is bumped and a new animal is chosen | 
					
						
							|  |  |  |  |      starting with that new letter. | 
					
						
							|  |  |  |  |   */ | 
					
						
							| 
									
										
										
										
											2020-09-07 14:15:25 -07:00
										 |  |  |  |   codeName = "Okapi"; | 
					
						
							| 
									
										
										
										
											2018-11-15 21:51:29 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-27 16:40:04 +02:00
										 |  |  |  |   /* Returns the current nixpkgs version suffix as string. */ | 
					
						
							| 
									
										
										
										
											2018-07-26 00:03:51 +02:00
										 |  |  |  |   versionSuffix = | 
					
						
							|  |  |  |  |     let suffixFile = ../.version-suffix; | 
					
						
							|  |  |  |  |     in if pathExists suffixFile | 
					
						
							|  |  |  |  |     then lib.strings.fileContents suffixFile | 
					
						
							|  |  |  |  |     else "pre-git"; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-27 16:40:04 +02:00
										 |  |  |  |   /* Attempts to return the the current revision of nixpkgs and
 | 
					
						
							|  |  |  |  |      returns the supplied default value otherwise. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |      Type: revisionWithDefault :: string -> string | 
					
						
							|  |  |  |  |   */ | 
					
						
							|  |  |  |  |   revisionWithDefault = | 
					
						
							|  |  |  |  |     # Default value to return if revision can not be determined | 
					
						
							|  |  |  |  |     default: | 
					
						
							| 
									
										
										
										
											2018-10-05 10:48:42 -04:00
										 |  |  |  |     let | 
					
						
							|  |  |  |  |       revisionFile = "${toString ./..}/.git-revision"; | 
					
						
							|  |  |  |  |       gitRepo      = "${toString ./..}/.git"; | 
					
						
							| 
									
										
										
										
											2020-01-20 00:44:07 +01:00
										 |  |  |  |     in if lib.pathIsGitRepo gitRepo | 
					
						
							| 
									
										
										
										
											2018-10-05 10:48:42 -04:00
										 |  |  |  |        then lib.commitIdFromGitRepo gitRepo | 
					
						
							|  |  |  |  |        else if lib.pathExists revisionFile then lib.fileContents revisionFile | 
					
						
							|  |  |  |  |        else default; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-26 10:31:05 +02:00
										 |  |  |  |   nixpkgsVersion = builtins.trace "`lib.nixpkgsVersion` is deprecated, use `lib.version` instead!" version; | 
					
						
							| 
									
										
										
										
											2014-02-19 18:47:48 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-27 16:40:04 +02:00
										 |  |  |  |   /* Determine whether the function is being called from inside a Nix
 | 
					
						
							|  |  |  |  |      shell. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |      Type: inNixShell :: bool | 
					
						
							|  |  |  |  |   */ | 
					
						
							| 
									
										
										
										
											2016-08-11 16:35:06 +02:00
										 |  |  |  |   inNixShell = builtins.getEnv "IN_NIX_SHELL" != ""; | 
					
						
							| 
									
										
										
										
											2014-02-19 19:00:51 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-26 00:03:51 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   ## Integer operations | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-27 16:40:04 +02:00
										 |  |  |  |   /* Return minimum of two numbers. */ | 
					
						
							| 
									
										
										
										
											2015-02-16 11:57:36 +01:00
										 |  |  |  |   min = x: y: if x < y then x else y; | 
					
						
							| 
									
										
										
										
											2018-10-27 16:40:04 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   /* Return maximum of two numbers. */ | 
					
						
							| 
									
										
										
										
											2015-02-16 11:57:36 +01:00
										 |  |  |  |   max = x: y: if x > y then x else y; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-30 14:32:04 +02:00
										 |  |  |  |   /* Integer modulus
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |      Example: | 
					
						
							|  |  |  |  |        mod 11 10 | 
					
						
							|  |  |  |  |        => 1 | 
					
						
							|  |  |  |  |        mod 1 10 | 
					
						
							|  |  |  |  |        => 1 | 
					
						
							|  |  |  |  |   */ | 
					
						
							|  |  |  |  |   mod = base: int: base - (int * (builtins.div base int)); | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-26 00:03:51 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   ## Comparisons | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-07 21:26:30 +00:00
										 |  |  |  |   /* C-style comparisons
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |      a < b,  compare a b => -1 | 
					
						
							|  |  |  |  |      a == b, compare a b => 0 | 
					
						
							|  |  |  |  |      a > b,  compare a b => 1 | 
					
						
							|  |  |  |  |   */ | 
					
						
							|  |  |  |  |   compare = a: b: | 
					
						
							|  |  |  |  |     if a < b | 
					
						
							|  |  |  |  |     then -1 | 
					
						
							|  |  |  |  |     else if a > b | 
					
						
							|  |  |  |  |          then 1 | 
					
						
							|  |  |  |  |          else 0; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   /* Split type into two subtypes by predicate `p`, take all elements
 | 
					
						
							|  |  |  |  |      of the first subtype to be less than all the elements of the | 
					
						
							|  |  |  |  |      second subtype, compare elements of a single subtype with `yes` | 
					
						
							|  |  |  |  |      and `no` respectively. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-27 16:40:04 +02:00
										 |  |  |  |      Type: (a -> bool) -> (a -> a -> int) -> (a -> a -> int) -> (a -> a -> int) | 
					
						
							| 
									
										
										
										
											2017-12-07 21:26:30 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-27 16:40:04 +02:00
										 |  |  |  |      Example: | 
					
						
							| 
									
										
										
										
											2017-12-07 21:26:30 +00:00
										 |  |  |  |        let cmp = splitByAndCompare (hasPrefix "foo") compare compare; in | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |        cmp "a" "z" => -1 | 
					
						
							|  |  |  |  |        cmp "fooa" "fooz" => -1 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |        cmp "f" "a" => 1 | 
					
						
							|  |  |  |  |        cmp "fooa" "a" => -1 | 
					
						
							|  |  |  |  |        # while | 
					
						
							|  |  |  |  |        compare "fooa" "a" => 1 | 
					
						
							|  |  |  |  |   */ | 
					
						
							| 
									
										
										
										
											2018-10-27 16:40:04 +02:00
										 |  |  |  |   splitByAndCompare = | 
					
						
							|  |  |  |  |     # Predicate | 
					
						
							|  |  |  |  |     p: | 
					
						
							|  |  |  |  |     # Comparison function if predicate holds for both values | 
					
						
							|  |  |  |  |     yes: | 
					
						
							|  |  |  |  |     # Comparison function if predicate holds for neither value | 
					
						
							|  |  |  |  |     no: | 
					
						
							|  |  |  |  |     # First value to compare | 
					
						
							|  |  |  |  |     a: | 
					
						
							|  |  |  |  |     # Second value to compare | 
					
						
							|  |  |  |  |     b: | 
					
						
							| 
									
										
										
										
											2017-12-07 21:26:30 +00:00
										 |  |  |  |     if p a | 
					
						
							|  |  |  |  |     then if p b then yes a b else -1 | 
					
						
							|  |  |  |  |     else if p b then 1 else no a b; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-26 00:03:51 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-27 16:40:04 +02:00
										 |  |  |  |   /* Reads a JSON file.
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |      Type :: path -> any | 
					
						
							|  |  |  |  |   */ | 
					
						
							| 
									
										
										
										
											2016-02-28 16:35:27 +00:00
										 |  |  |  |   importJSON = path: | 
					
						
							|  |  |  |  |     builtins.fromJSON (builtins.readFile path); | 
					
						
							| 
									
										
										
										
											2016-08-15 13:54:23 -04:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-16 15:39:52 +02:00
										 |  |  |  |   /* Reads a TOML file.
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |      Type :: path -> any | 
					
						
							|  |  |  |  |   */ | 
					
						
							|  |  |  |  |   importTOML = path: | 
					
						
							|  |  |  |  |     builtins.fromTOML (builtins.readFile path); | 
					
						
							| 
									
										
										
										
											2018-07-26 00:03:51 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-08 19:26:52 +02:00
										 |  |  |  |   ## Warnings | 
					
						
							| 
									
										
										
										
											2018-07-26 00:03:51 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-27 16:40:04 +02:00
										 |  |  |  |   # See https://github.com/NixOS/nix/issues/749. Eventually we'd like these | 
					
						
							|  |  |  |  |   # to expand to Nix builtins that carry metadata so that Nix can filter out | 
					
						
							|  |  |  |  |   # the INFO messages without parsing the message string. | 
					
						
							|  |  |  |  |   # | 
					
						
							|  |  |  |  |   # Usage: | 
					
						
							|  |  |  |  |   # { | 
					
						
							|  |  |  |  |   #   foo = lib.warn "foo is deprecated" oldFoo; | 
					
						
							|  |  |  |  |   # } | 
					
						
							|  |  |  |  |   # | 
					
						
							|  |  |  |  |   # TODO: figure out a clever way to integrate location information from | 
					
						
							|  |  |  |  |   # something like __unsafeGetAttrPos. | 
					
						
							| 
									
										
										
										
											2016-08-15 13:54:23 -04:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-23 18:06:51 +00:00
										 |  |  |  |   warn = msg: builtins.trace "[1;31mwarning: ${msg}[0m"; | 
					
						
							| 
									
										
										
										
											2016-08-15 13:54:23 -04:00
										 |  |  |  |   info = msg: builtins.trace "INFO: ${msg}"; | 
					
						
							| 
									
										
										
										
											2018-01-31 14:02:19 -05:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-23 18:06:51 +00:00
										 |  |  |  |   showWarnings = warnings: res: lib.fold (w: x: warn w x) res warnings; | 
					
						
							| 
									
										
										
										
											2018-07-26 00:03:51 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   ## Function annotations | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   /* Add metadata about expected function arguments to a function.
 | 
					
						
							|  |  |  |  |      The metadata should match the format given by | 
					
						
							|  |  |  |  |      builtins.functionArgs, i.e. a set from expected argument to a bool | 
					
						
							|  |  |  |  |      representing whether that argument has a default or not. | 
					
						
							|  |  |  |  |      setFunctionArgs : (a → b) → Map String Bool → (a → b) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |      This function is necessary because you can't dynamically create a | 
					
						
							|  |  |  |  |      function of the { a, b ? foo, ... }: format, but some facilities | 
					
						
							|  |  |  |  |      like callPackage expect to be able to query expected arguments. | 
					
						
							|  |  |  |  |   */ | 
					
						
							| 
									
										
										
										
											2018-01-31 14:02:19 -05:00
										 |  |  |  |   setFunctionArgs = f: args: | 
					
						
							|  |  |  |  |     { # TODO: Should we add call-time "type" checking like built in? | 
					
						
							|  |  |  |  |       __functor = self: f; | 
					
						
							|  |  |  |  |       __functionArgs = args; | 
					
						
							|  |  |  |  |     }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-26 00:03:51 +02:00
										 |  |  |  |   /* Extract the expected function arguments from a function.
 | 
					
						
							|  |  |  |  |      This works both with nix-native { a, b ? foo, ... }: style | 
					
						
							|  |  |  |  |      functions and functions with args set with 'setFunctionArgs'. It | 
					
						
							|  |  |  |  |      has the same return type and semantics as builtins.functionArgs. | 
					
						
							|  |  |  |  |      setFunctionArgs : (a → b) → Map String Bool. | 
					
						
							|  |  |  |  |   */ | 
					
						
							| 
									
										
										
										
											2018-01-31 14:02:19 -05:00
										 |  |  |  |   functionArgs = f: f.__functionArgs or (builtins.functionArgs f); | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-26 00:03:51 +02:00
										 |  |  |  |   /* Check whether something is a function or something
 | 
					
						
							|  |  |  |  |      annotated with function args. | 
					
						
							|  |  |  |  |   */ | 
					
						
							| 
									
										
										
										
											2018-01-31 14:02:19 -05:00
										 |  |  |  |   isFunction = f: builtins.isFunction f || | 
					
						
							|  |  |  |  |     (f ? __functor && isFunction (f.__functor f)); | 
					
						
							| 
									
										
										
										
											2020-04-20 12:00:23 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   /* Convert the given positive integer to a string of its hexadecimal
 | 
					
						
							|  |  |  |  |      representation. For example: | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 13:14:19 +02:00
										 |  |  |  |      toHexString 0 => "0" | 
					
						
							| 
									
										
										
										
											2020-04-20 12:00:23 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 13:14:19 +02:00
										 |  |  |  |      toHexString 16 => "10" | 
					
						
							| 
									
										
										
										
											2020-04-20 12:00:23 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 13:14:19 +02:00
										 |  |  |  |      toHexString 250 => "FA" | 
					
						
							| 
									
										
										
										
											2020-04-20 12:00:23 +02:00
										 |  |  |  |   */ | 
					
						
							| 
									
										
										
										
											2020-07-20 13:14:19 +02:00
										 |  |  |  |   toHexString = i: | 
					
						
							| 
									
										
										
										
											2020-04-20 12:00:23 +02:00
										 |  |  |  |     let | 
					
						
							|  |  |  |  |       toHexDigit = d: | 
					
						
							|  |  |  |  |         if d < 10 | 
					
						
							|  |  |  |  |         then toString d | 
					
						
							|  |  |  |  |         else | 
					
						
							|  |  |  |  |           { | 
					
						
							|  |  |  |  |             "10" = "A"; | 
					
						
							|  |  |  |  |             "11" = "B"; | 
					
						
							|  |  |  |  |             "12" = "C"; | 
					
						
							|  |  |  |  |             "13" = "D"; | 
					
						
							|  |  |  |  |             "14" = "E"; | 
					
						
							|  |  |  |  |             "15" = "F"; | 
					
						
							|  |  |  |  |           }.${toString d}; | 
					
						
							|  |  |  |  |     in | 
					
						
							| 
									
										
										
										
											2020-07-20 13:14:19 +02:00
										 |  |  |  |       lib.concatMapStrings toHexDigit (toBaseDigits 16 i); | 
					
						
							| 
									
										
										
										
											2020-04-20 12:00:23 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 13:14:19 +02:00
										 |  |  |  |   /* `toBaseDigits base i` converts the positive integer i to a list of its
 | 
					
						
							| 
									
										
										
										
											2020-04-20 12:00:23 +02:00
										 |  |  |  |      digits in the given base. For example: | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 13:14:19 +02:00
										 |  |  |  |      toBaseDigits 10 123 => [ 1 2 3 ] | 
					
						
							| 
									
										
										
										
											2020-04-20 12:00:23 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 13:14:19 +02:00
										 |  |  |  |      toBaseDigits 2 6 => [ 1 1 0 ] | 
					
						
							| 
									
										
										
										
											2020-04-20 12:00:23 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-20 13:14:19 +02:00
										 |  |  |  |      toBaseDigits 16 250 => [ 15 10 ] | 
					
						
							| 
									
										
										
										
											2020-04-20 12:00:23 +02:00
										 |  |  |  |   */ | 
					
						
							| 
									
										
										
										
											2020-07-20 13:14:19 +02:00
										 |  |  |  |   toBaseDigits = base: i: | 
					
						
							| 
									
										
										
										
											2020-04-20 12:00:23 +02:00
										 |  |  |  |     let | 
					
						
							|  |  |  |  |       go = i: | 
					
						
							|  |  |  |  |         if i < base | 
					
						
							|  |  |  |  |         then [i] | 
					
						
							|  |  |  |  |         else | 
					
						
							|  |  |  |  |           let | 
					
						
							|  |  |  |  |             r = i - ((i / base) * base); | 
					
						
							|  |  |  |  |             q = (i - r) / base; | 
					
						
							|  |  |  |  |           in | 
					
						
							|  |  |  |  |             [r] ++ go q; | 
					
						
							|  |  |  |  |     in | 
					
						
							|  |  |  |  |       assert (base >= 2); | 
					
						
							|  |  |  |  |       assert (i >= 0); | 
					
						
							|  |  |  |  |       lib.reverseList (go i); | 
					
						
							| 
									
										
										
										
											2009-02-09 16:51:03 +00:00
										 |  |  |  | } |