1{ lib }:
2
3let
4 inherit (lib.trivial)
5 isFunction
6 isInt
7 functionArgs
8 pathExists
9 release
10 setFunctionArgs
11 toBaseDigits
12 version
13 versionSuffix
14 warn;
15in {
16
17 ## Simple (higher order) functions
18
19 /**
20 The identity function
21 For when you need a function that does “nothing”.
22
23
24 # Inputs
25
26 `x`
27
28 : The value to return
29
30 # Type
31
32 ```
33 id :: a -> a
34 ```
35 */
36 id = x: x;
37
38 /**
39 The constant function
40
41 Ignores the second argument. If called with only one argument,
42 constructs a function that always returns a static value.
43
44
45 # Inputs
46
47 `x`
48
49 : Value to return
50
51 `y`
52
53 : Value to ignore
54
55 # Type
56
57 ```
58 const :: a -> b -> a
59 ```
60
61 # Examples
62 :::{.example}
63 ## `lib.trivial.const` usage example
64
65 ```nix
66 let f = const 5; in f 10
67 => 5
68 ```
69
70 :::
71 */
72 const =
73 x:
74 y: x;
75
76 /**
77 Pipes a value through a list of functions, left to right.
78
79 # Inputs
80
81 `value`
82
83 : Value to start piping.
84
85 `fns`
86
87 : List of functions to apply sequentially.
88
89 # Type
90
91 ```
92 pipe :: a -> [<functions>] -> <return type of last function>
93 ```
94
95 # Examples
96 :::{.example}
97 ## `lib.trivial.pipe` usage example
98
99 ```nix
100 pipe 2 [
101 (x: x + 2) # 2 + 2 = 4
102 (x: x * 2) # 4 * 2 = 8
103 ]
104 => 8
105
106 # ideal to do text transformations
107 pipe [ "a/b" "a/c" ] [
108
109 # create the cp command
110 (map (file: ''cp "${src}/${file}" $out\n''))
111
112 # concatenate all commands into one string
113 lib.concatStrings
114
115 # make that string into a nix derivation
116 (pkgs.runCommand "copy-to-out" {})
117
118 ]
119 => <drv which copies all files to $out>
120
121 The output type of each function has to be the input type
122 of the next function, and the last function returns the
123 final value.
124 ```
125
126 :::
127 */
128 pipe = builtins.foldl' (x: f: f x);
129
130 # note please don’t add a function like `compose = flip pipe`.
131 # This would confuse users, because the order of the functions
132 # in the list is not clear. With pipe, it’s obvious that it
133 # goes first-to-last. With `compose`, not so much.
134
135 ## Named versions corresponding to some builtin operators.
136
137 /**
138 Concatenate two lists
139
140
141 # Inputs
142
143 `x`
144
145 : 1\. Function argument
146
147 `y`
148
149 : 2\. Function argument
150
151 # Type
152
153 ```
154 concat :: [a] -> [a] -> [a]
155 ```
156
157 # Examples
158 :::{.example}
159 ## `lib.trivial.concat` usage example
160
161 ```nix
162 concat [ 1 2 ] [ 3 4 ]
163 => [ 1 2 3 4 ]
164 ```
165
166 :::
167 */
168 concat = x: y: x ++ y;
169
170 /**
171 boolean “or”
172
173
174 # Inputs
175
176 `x`
177
178 : 1\. Function argument
179
180 `y`
181
182 : 2\. Function argument
183 */
184 or = x: y: x || y;
185
186 /**
187 boolean “and”
188
189
190 # Inputs
191
192 `x`
193
194 : 1\. Function argument
195
196 `y`
197
198 : 2\. Function argument
199 */
200 and = x: y: x && y;
201
202 /**
203 boolean “exclusive or”
204
205
206 # Inputs
207
208 `x`
209
210 : 1\. Function argument
211
212 `y`
213
214 : 2\. Function argument
215 */
216 # We explicitly invert the arguments purely as a type assertion.
217 # This is invariant under XOR, so it does not affect the result.
218 xor = x: y: (!x) != (!y);
219
220 /**
221 bitwise “not”
222 */
223 bitNot = builtins.sub (-1);
224
225 /**
226 Convert a boolean to a string.
227
228 This function uses the strings "true" and "false" to represent
229 boolean values. Calling `toString` on a bool instead returns "1"
230 and "" (sic!).
231
232
233 # Inputs
234
235 `b`
236
237 : 1\. Function argument
238
239 # Type
240
241 ```
242 boolToString :: bool -> string
243 ```
244 */
245 boolToString = b: if b then "true" else "false";
246
247 /**
248 Merge two attribute sets shallowly, right side trumps left
249
250 mergeAttrs :: attrs -> attrs -> attrs
251
252
253 # Inputs
254
255 `x`
256
257 : Left attribute set
258
259 `y`
260
261 : Right attribute set (higher precedence for equal keys)
262
263
264 # Examples
265 :::{.example}
266 ## `lib.trivial.mergeAttrs` usage example
267
268 ```nix
269 mergeAttrs { a = 1; b = 2; } { b = 3; c = 4; }
270 => { a = 1; b = 3; c = 4; }
271 ```
272
273 :::
274 */
275 mergeAttrs =
276 x:
277 y: x // y;
278
279 /**
280 Flip the order of the arguments of a binary function.
281
282
283 # Inputs
284
285 `f`
286
287 : 1\. Function argument
288
289 `a`
290
291 : 2\. Function argument
292
293 `b`
294
295 : 3\. Function argument
296
297 # Type
298
299 ```
300 flip :: (a -> b -> c) -> (b -> a -> c)
301 ```
302
303 # Examples
304 :::{.example}
305 ## `lib.trivial.flip` usage example
306
307 ```nix
308 flip concat [1] [2]
309 => [ 2 1 ]
310 ```
311
312 :::
313 */
314 flip = f: a: b: f b a;
315
316 /**
317 Apply function if the supplied argument is non-null.
318
319
320 # Inputs
321
322 `f`
323
324 : Function to call
325
326 `a`
327
328 : Argument to check for null before passing it to `f`
329
330
331 # Examples
332 :::{.example}
333 ## `lib.trivial.mapNullable` usage example
334
335 ```nix
336 mapNullable (x: x+1) null
337 => null
338 mapNullable (x: x+1) 22
339 => 23
340 ```
341
342 :::
343 */
344 mapNullable =
345 f:
346 a: if a == null then a else f a;
347
348 # Pull in some builtins not included elsewhere.
349 inherit (builtins)
350 pathExists readFile isBool
351 isInt isFloat add sub lessThan
352 seq deepSeq genericClosure
353 bitAnd bitOr bitXor;
354
355 ## nixpkgs version strings
356
357 /**
358 Returns the current full nixpkgs version number.
359 */
360 version = release + versionSuffix;
361
362 /**
363 Returns the current nixpkgs release number as string.
364 */
365 release = lib.strings.fileContents ./.version;
366
367 /**
368 The latest release that is supported, at the time of release branch-off,
369 if applicable.
370
371 Ideally, out-of-tree modules should be able to evaluate cleanly with all
372 supported Nixpkgs versions (master, release and old release until EOL).
373 So if possible, deprecation warnings should take effect only when all
374 out-of-tree expressions/libs/modules can upgrade to the new way without
375 losing support for supported Nixpkgs versions.
376
377 This release number allows deprecation warnings to be implemented such that
378 they take effect as soon as the oldest release reaches end of life.
379 */
380 oldestSupportedRelease =
381 # Update on master only. Do not backport.
382 2311;
383
384 /**
385 Whether a feature is supported in all supported releases (at the time of
386 release branch-off, if applicable). See `oldestSupportedRelease`.
387
388
389 # Inputs
390
391 `release`
392
393 : Release number of feature introduction as an integer, e.g. 2111 for 21.11.
394 Set it to the upcoming release, matching the nixpkgs/.version file.
395 */
396 isInOldestRelease =
397 release:
398 release <= lib.trivial.oldestSupportedRelease;
399
400 /**
401 Returns the current nixpkgs release code name.
402
403 On each release the first letter is bumped and a new animal is chosen
404 starting with that new letter.
405 */
406 codeName = "Vicuña";
407
408 /**
409 Returns the current nixpkgs version suffix as string.
410 */
411 versionSuffix =
412 let suffixFile = ../.version-suffix;
413 in if pathExists suffixFile
414 then lib.strings.fileContents suffixFile
415 else "pre-git";
416
417 /**
418 Attempts to return the the current revision of nixpkgs and
419 returns the supplied default value otherwise.
420
421
422 # Inputs
423
424 `default`
425
426 : Default value to return if revision can not be determined
427
428 # Type
429
430 ```
431 revisionWithDefault :: string -> string
432 ```
433 */
434 revisionWithDefault =
435 default:
436 let
437 revisionFile = "${toString ./..}/.git-revision";
438 gitRepo = "${toString ./..}/.git";
439 in if lib.pathIsGitRepo gitRepo
440 then lib.commitIdFromGitRepo gitRepo
441 else if lib.pathExists revisionFile then lib.fileContents revisionFile
442 else default;
443
444 nixpkgsVersion = warn "lib.nixpkgsVersion is a deprecated alias of lib.version." version;
445
446 /**
447 Determine whether the function is being called from inside a Nix
448 shell.
449
450 # Type
451
452 ```
453 inNixShell :: bool
454 ```
455 */
456 inNixShell = builtins.getEnv "IN_NIX_SHELL" != "";
457
458 /**
459 Determine whether the function is being called from inside pure-eval mode
460 by seeing whether `builtins` contains `currentSystem`. If not, we must be in
461 pure-eval mode.
462
463 # Type
464
465 ```
466 inPureEvalMode :: bool
467 ```
468 */
469 inPureEvalMode = ! builtins ? currentSystem;
470
471 ## Integer operations
472
473 /**
474 Return minimum of two numbers.
475
476
477 # Inputs
478
479 `x`
480
481 : 1\. Function argument
482
483 `y`
484
485 : 2\. Function argument
486 */
487 min = x: y: if x < y then x else y;
488
489 /**
490 Return maximum of two numbers.
491
492
493 # Inputs
494
495 `x`
496
497 : 1\. Function argument
498
499 `y`
500
501 : 2\. Function argument
502 */
503 max = x: y: if x > y then x else y;
504
505 /**
506 Integer modulus
507
508
509 # Inputs
510
511 `base`
512
513 : 1\. Function argument
514
515 `int`
516
517 : 2\. Function argument
518
519
520 # Examples
521 :::{.example}
522 ## `lib.trivial.mod` usage example
523
524 ```nix
525 mod 11 10
526 => 1
527 mod 1 10
528 => 1
529 ```
530
531 :::
532 */
533 mod = base: int: base - (int * (builtins.div base int));
534
535
536 ## Comparisons
537
538 /**
539 C-style comparisons
540
541 a < b, compare a b => -1
542 a == b, compare a b => 0
543 a > b, compare a b => 1
544
545
546 # Inputs
547
548 `a`
549
550 : 1\. Function argument
551
552 `b`
553
554 : 2\. Function argument
555 */
556 compare = a: b:
557 if a < b
558 then -1
559 else if a > b
560 then 1
561 else 0;
562
563 /**
564 Split type into two subtypes by predicate `p`, take all elements
565 of the first subtype to be less than all the elements of the
566 second subtype, compare elements of a single subtype with `yes`
567 and `no` respectively.
568
569
570 # Inputs
571
572 `p`
573
574 : Predicate
575
576 `yes`
577
578 : Comparison function if predicate holds for both values
579
580 `no`
581
582 : Comparison function if predicate holds for neither value
583
584 `a`
585
586 : First value to compare
587
588 `b`
589
590 : Second value to compare
591
592 # Type
593
594 ```
595 (a -> bool) -> (a -> a -> int) -> (a -> a -> int) -> (a -> a -> int)
596 ```
597
598 # Examples
599 :::{.example}
600 ## `lib.trivial.splitByAndCompare` usage example
601
602 ```nix
603 let cmp = splitByAndCompare (hasPrefix "foo") compare compare; in
604
605 cmp "a" "z" => -1
606 cmp "fooa" "fooz" => -1
607
608 cmp "f" "a" => 1
609 cmp "fooa" "a" => -1
610 # while
611 compare "fooa" "a" => 1
612 ```
613
614 :::
615 */
616 splitByAndCompare =
617 p: yes: no: a: b:
618 if p a
619 then if p b then yes a b else -1
620 else if p b then 1 else no a b;
621
622
623 /**
624 Reads a JSON file.
625
626
627 # Inputs
628
629 `path`
630
631 : 1\. Function argument
632
633 # Type
634
635 ```
636 importJSON :: path -> any
637 ```
638 */
639 importJSON = path:
640 builtins.fromJSON (builtins.readFile path);
641
642 /**
643 Reads a TOML file.
644
645
646 # Inputs
647
648 `path`
649
650 : 1\. Function argument
651
652 # Type
653
654 ```
655 importTOML :: path -> any
656 ```
657 */
658 importTOML = path:
659 builtins.fromTOML (builtins.readFile path);
660
661 ## Warnings
662
663 # See https://github.com/NixOS/nix/issues/749. Eventually we'd like these
664 # to expand to Nix builtins that carry metadata so that Nix can filter out
665 # the INFO messages without parsing the message string.
666 #
667 # Usage:
668 # {
669 # foo = lib.warn "foo is deprecated" oldFoo;
670 # bar = lib.warnIf (bar == "") "Empty bar is deprecated" bar;
671 # }
672 #
673 # TODO: figure out a clever way to integrate location information from
674 # something like __unsafeGetAttrPos.
675
676 /**
677 Print a warning before returning the second argument. This function behaves
678 like `builtins.trace`, but requires a string message and formats it as a
679 warning, including the `warning: ` prefix.
680
681 To get a call stack trace and abort evaluation, set the environment variable
682 `NIX_ABORT_ON_WARN=true` and set the Nix options `--option pure-eval false --show-trace`
683
684 # Inputs
685
686 `msg`
687
688 : Warning message to print.
689
690 `val`
691
692 : Value to return as-is.
693
694 # Type
695
696 ```
697 string -> a -> a
698 ```
699 */
700 warn =
701 if lib.elem (builtins.getEnv "NIX_ABORT_ON_WARN") ["1" "true" "yes"]
702 then msg: builtins.trace "[1;31mwarning: ${msg}[0m" (abort "NIX_ABORT_ON_WARN=true; warnings are treated as unrecoverable errors.")
703 else msg: builtins.trace "[1;31mwarning: ${msg}[0m";
704
705 /**
706 Like warn, but only warn when the first argument is `true`.
707
708
709 # Inputs
710
711 `cond`
712
713 : 1\. Function argument
714
715 `msg`
716
717 : 2\. Function argument
718
719 `val`
720
721 : Value to return as-is.
722
723 # Type
724
725 ```
726 bool -> string -> a -> a
727 ```
728 */
729 warnIf = cond: msg: if cond then warn msg else x: x;
730
731 /**
732 Like warnIf, but negated (warn if the first argument is `false`).
733
734
735 # Inputs
736
737 `cond`
738
739 : 1\. Function argument
740
741 `msg`
742
743 : 2\. Function argument
744
745 `val`
746
747 : Value to return as-is.
748
749 # Type
750
751 ```
752 bool -> string -> a -> a
753 ```
754 */
755 warnIfNot = cond: msg: if cond then x: x else warn msg;
756
757 /**
758 Like the `assert b; e` expression, but with a custom error message and
759 without the semicolon.
760
761 If true, return the identity function, `r: r`.
762
763 If false, throw the error message.
764
765 Calls can be juxtaposed using function application, as `(r: r) a = a`, so
766 `(r: r) (r: r) a = a`, and so forth.
767
768
769 # Inputs
770
771 `cond`
772
773 : 1\. Function argument
774
775 `msg`
776
777 : 2\. Function argument
778
779 # Type
780
781 ```
782 bool -> string -> a -> a
783 ```
784
785 # Examples
786 :::{.example}
787 ## `lib.trivial.throwIfNot` usage example
788
789 ```nix
790 throwIfNot (lib.isList overlays) "The overlays argument to nixpkgs must be a list."
791 lib.foldr (x: throwIfNot (lib.isFunction x) "All overlays passed to nixpkgs must be functions.") (r: r) overlays
792 pkgs
793 ```
794
795 :::
796 */
797 throwIfNot = cond: msg: if cond then x: x else throw msg;
798
799 /**
800 Like throwIfNot, but negated (throw if the first argument is `true`).
801
802
803 # Inputs
804
805 `cond`
806
807 : 1\. Function argument
808
809 `msg`
810
811 : 2\. Function argument
812
813 # Type
814
815 ```
816 bool -> string -> a -> a
817 ```
818 */
819 throwIf = cond: msg: if cond then throw msg else x: x;
820
821 /**
822 Check if the elements in a list are valid values from a enum, returning the identity function, or throwing an error message otherwise.
823
824
825 # Inputs
826
827 `msg`
828
829 : 1\. Function argument
830
831 `valid`
832
833 : 2\. Function argument
834
835 `given`
836
837 : 3\. Function argument
838
839 # Type
840
841 ```
842 String -> List ComparableVal -> List ComparableVal -> a -> a
843 ```
844
845 # Examples
846 :::{.example}
847 ## `lib.trivial.checkListOfEnum` usage example
848
849 ```nix
850 let colorVariants = ["bright" "dark" "black"]
851 in checkListOfEnum "color variants" [ "standard" "light" "dark" ] colorVariants;
852 =>
853 error: color variants: bright, black unexpected; valid ones: standard, light, dark
854 ```
855
856 :::
857 */
858 checkListOfEnum = msg: valid: given:
859 let
860 unexpected = lib.subtractLists valid given;
861 in
862 lib.throwIfNot (unexpected == [])
863 "${msg}: ${builtins.concatStringsSep ", " (builtins.map builtins.toString unexpected)} unexpected; valid ones: ${builtins.concatStringsSep ", " (builtins.map builtins.toString valid)}";
864
865 info = msg: builtins.trace "INFO: ${msg}";
866
867 showWarnings = warnings: res: lib.foldr (w: x: warn w x) res warnings;
868
869 ## Function annotations
870
871 /**
872 Add metadata about expected function arguments to a function.
873 The metadata should match the format given by
874 builtins.functionArgs, i.e. a set from expected argument to a bool
875 representing whether that argument has a default or not.
876 setFunctionArgs : (a → b) → Map String Bool → (a → b)
877
878 This function is necessary because you can't dynamically create a
879 function of the { a, b ? foo, ... }: format, but some facilities
880 like callPackage expect to be able to query expected arguments.
881
882
883 # Inputs
884
885 `f`
886
887 : 1\. Function argument
888
889 `args`
890
891 : 2\. Function argument
892 */
893 setFunctionArgs = f: args:
894 { # TODO: Should we add call-time "type" checking like built in?
895 __functor = self: f;
896 __functionArgs = args;
897 };
898
899 /**
900 Extract the expected function arguments from a function.
901 This works both with nix-native { a, b ? foo, ... }: style
902 functions and functions with args set with 'setFunctionArgs'. It
903 has the same return type and semantics as builtins.functionArgs.
904 setFunctionArgs : (a → b) → Map String Bool.
905
906
907 # Inputs
908
909 `f`
910
911 : 1\. Function argument
912 */
913 functionArgs = f:
914 if f ? __functor
915 then f.__functionArgs or (functionArgs (f.__functor f))
916 else builtins.functionArgs f;
917
918 /**
919 Check whether something is a function or something
920 annotated with function args.
921
922
923 # Inputs
924
925 `f`
926
927 : 1\. Function argument
928 */
929 isFunction = f: builtins.isFunction f ||
930 (f ? __functor && isFunction (f.__functor f));
931
932 /**
933 `mirrorFunctionArgs f g` creates a new function `g'` with the same behavior as `g` (`g' x == g x`)
934 but its function arguments mirroring `f` (`lib.functionArgs g' == lib.functionArgs f`).
935
936
937 # Inputs
938
939 `f`
940
941 : Function to provide the argument metadata
942
943 `g`
944
945 : Function to set the argument metadata to
946
947 # Type
948
949 ```
950 mirrorFunctionArgs :: (a -> b) -> (a -> c) -> (a -> c)
951 ```
952
953 # Examples
954 :::{.example}
955 ## `lib.trivial.mirrorFunctionArgs` usage example
956
957 ```nix
958 addab = {a, b}: a + b
959 addab { a = 2; b = 4; }
960 => 6
961 lib.functionArgs addab
962 => { a = false; b = false; }
963 addab1 = attrs: addab attrs + 1
964 addab1 { a = 2; b = 4; }
965 => 7
966 lib.functionArgs addab1
967 => { }
968 addab1' = lib.mirrorFunctionArgs addab addab1
969 addab1' { a = 2; b = 4; }
970 => 7
971 lib.functionArgs addab1'
972 => { a = false; b = false; }
973 ```
974
975 :::
976 */
977 mirrorFunctionArgs =
978 f:
979 let
980 fArgs = functionArgs f;
981 in
982 g:
983 setFunctionArgs g fArgs;
984
985 /**
986 Turns any non-callable values into constant functions.
987 Returns callable values as is.
988
989
990 # Inputs
991
992 `v`
993
994 : Any value
995
996
997 # Examples
998 :::{.example}
999 ## `lib.trivial.toFunction` usage example
1000
1001 ```nix
1002 nix-repl> lib.toFunction 1 2
1003 1
1004
1005 nix-repl> lib.toFunction (x: x + 1) 2
1006 3
1007 ```
1008
1009 :::
1010 */
1011 toFunction =
1012 v:
1013 if isFunction v
1014 then v
1015 else k: v;
1016
1017 /**
1018 Convert the given positive integer to a string of its hexadecimal
1019 representation. For example:
1020
1021 toHexString 0 => "0"
1022
1023 toHexString 16 => "10"
1024
1025 toHexString 250 => "FA"
1026 */
1027 toHexString = let
1028 hexDigits = {
1029 "10" = "A";
1030 "11" = "B";
1031 "12" = "C";
1032 "13" = "D";
1033 "14" = "E";
1034 "15" = "F";
1035 };
1036 toHexDigit = d:
1037 if d < 10
1038 then toString d
1039 else hexDigits.${toString d};
1040 in i: lib.concatMapStrings toHexDigit (toBaseDigits 16 i);
1041
1042 /**
1043 `toBaseDigits base i` converts the positive integer i to a list of its
1044 digits in the given base. For example:
1045
1046 toBaseDigits 10 123 => [ 1 2 3 ]
1047
1048 toBaseDigits 2 6 => [ 1 1 0 ]
1049
1050 toBaseDigits 16 250 => [ 15 10 ]
1051
1052
1053 # Inputs
1054
1055 `base`
1056
1057 : 1\. Function argument
1058
1059 `i`
1060
1061 : 2\. Function argument
1062 */
1063 toBaseDigits = base: i:
1064 let
1065 go = i:
1066 if i < base
1067 then [i]
1068 else
1069 let
1070 r = i - ((i / base) * base);
1071 q = (i - r) / base;
1072 in
1073 [r] ++ go q;
1074 in
1075 assert (isInt base);
1076 assert (isInt i);
1077 assert (base >= 2);
1078 assert (i >= 0);
1079 lib.reverseList (go i);
1080}