···11-/* Operations on attribute sets. */
11+/**
22+ Operations on attribute sets.
33+*/
24{ lib }:
3546let
···1214 inherit (builtins) attrNames listToAttrs hasAttr isAttrs getAttr removeAttrs;
131514161515- /* Return an attribute from nested attribute sets.
1717+ /**
1818+ Return an attribute from nested attribute sets.
1919+2020+ Nix has an [attribute selection operator `. or`](https://nixos.org/manual/nix/stable/language/operators#attribute-selection) which is sufficient for such queries, as long as the number of attributes is static. For example:
2121+2222+ ```nix
2323+ (x.a.b or 6) == attrByPath ["a" "b"] 6 x
2424+ # and
2525+ (x.${f p}."example.com" or 6) == attrByPath [ (f p) "example.com" ] 6 x
2626+ ```
2727+2828+2929+ # Inputs
3030+3131+ `attrPath`
3232+3333+ : A list of strings representing the attribute path to return from `set`
16341717- Nix has an [attribute selection operator `. or`](https://nixos.org/manual/nix/stable/language/operators#attribute-selection) which is sufficient for such queries, as long as the number of attributes is static. For example:
3535+ `default`
3636+3737+ : Default value if `attrPath` does not resolve to an existing value
3838+3939+ `set`
4040+4141+ : The nested attribute set to select values from
18421919- ```nix
2020- (x.a.b or 6) == attrByPath ["a" "b"] 6 x
2121- # and
2222- (x.${f p}."example.com" or 6) == attrByPath [ (f p) "example.com" ] 6 x
2323- ```
4343+ # Type
24442525- Example:
2626- x = { a = { b = 3; }; }
2727- # ["a" "b"] is equivalent to x.a.b
2828- # 6 is a default value to return if the path does not exist in attrset
2929- attrByPath ["a" "b"] 6 x
3030- => 3
3131- attrByPath ["z" "z"] 6 x
3232- => 6
4545+ ```
4646+ attrByPath :: [String] -> Any -> AttrSet -> Any
4747+ ```
33483434- Type:
3535- attrByPath :: [String] -> Any -> AttrSet -> Any
4949+ # Examples
5050+ :::{.example}
5151+ ## `lib.attrsets.attrByPath` usage example
36525353+ ```nix
5454+ x = { a = { b = 3; }; }
5555+ # ["a" "b"] is equivalent to x.a.b
5656+ # 6 is a default value to return if the path does not exist in attrset
5757+ attrByPath ["a" "b"] 6 x
5858+ => 3
5959+ attrByPath ["z" "z"] 6 x
6060+ => 6
6161+ ```
6262+6363+ :::
3764 */
3865 attrByPath =
3939- # A list of strings representing the attribute path to return from `set`
4066 attrPath:
4141- # Default value if `attrPath` does not resolve to an existing value
4267 default:
4343- # The nested attribute set to select values from
4468 set:
4569 let
4670 lenAttrPath = length attrPath;
···5781 in
5882 attrByPath' 0 set;
59836060- /* Return if an attribute from nested attribute set exists.
8484+ /**
8585+ Return if an attribute from nested attribute set exists.
8686+8787+ Nix has a [has attribute operator `?`](https://nixos.org/manual/nix/stable/language/operators#has-attribute), which is sufficient for such queries, as long as the number of attributes is static. For example:
8888+8989+ ```nix
9090+ (x?a.b) == hasAttryByPath ["a" "b"] x
9191+ # and
9292+ (x?${f p}."example.com") == hasAttryByPath [ (f p) "example.com" ] x
9393+ ```
9494+9595+ **Laws**:
9696+ 1. ```nix
9797+ hasAttrByPath [] x == true
9898+ ```
9999+100100+101101+ # Inputs
102102+103103+ `attrPath`
611046262- Nix has a [has attribute operator `?`](https://nixos.org/manual/nix/stable/language/operators#has-attribute), which is sufficient for such queries, as long as the number of attributes is static. For example:
105105+ : A list of strings representing the attribute path to check from `set`
631066464- ```nix
6565- (x?a.b) == hasAttryByPath ["a" "b"] x
6666- # and
6767- (x?${f p}."example.com") == hasAttryByPath [ (f p) "example.com" ] x
6868- ```
107107+ `e`
691087070- **Laws**:
7171- 1. ```nix
7272- hasAttrByPath [] x == true
7373- ```
109109+ : The nested attribute set to check
741107575- Example:
7676- x = { a = { b = 3; }; }
7777- hasAttrByPath ["a" "b"] x
7878- => true
7979- hasAttrByPath ["z" "z"] x
8080- => false
8181- hasAttrByPath [] (throw "no need")
8282- => true
111111+ # Type
831128484- Type:
8585- hasAttrByPath :: [String] -> AttrSet -> Bool
113113+ ```
114114+ hasAttrByPath :: [String] -> AttrSet -> Bool
115115+ ```
116116+117117+ # Examples
118118+ :::{.example}
119119+ ## `lib.attrsets.hasAttrByPath` usage example
120120+121121+ ```nix
122122+ x = { a = { b = 3; }; }
123123+ hasAttrByPath ["a" "b"] x
124124+ => true
125125+ hasAttrByPath ["z" "z"] x
126126+ => false
127127+ hasAttrByPath [] (throw "no need")
128128+ => true
129129+ ```
130130+131131+ :::
86132 */
87133 hasAttrByPath =
8888- # A list of strings representing the attribute path to check from `set`
89134 attrPath:
9090- # The nested attribute set to check
91135 e:
92136 let
93137 lenAttrPath = length attrPath;
···103147 in
104148 hasAttrByPath' 0 e;
105149106106- /*
150150+ /**
107151 Return the longest prefix of an attribute path that refers to an existing attribute in a nesting of attribute sets.
108152109153 Can be used after [`mapAttrsRecursiveCond`](#function-library-lib.attrsets.mapAttrsRecursiveCond) to apply a condition,
···120164 hasAttrByPath (attrsets.longestValidPathPrefix p x) x == true
121165 ```
122166123123- Example:
124124- x = { a = { b = 3; }; }
125125- attrsets.longestValidPathPrefix ["a" "b" "c"] x
126126- => ["a" "b"]
127127- attrsets.longestValidPathPrefix ["a"] x
128128- => ["a"]
129129- attrsets.longestValidPathPrefix ["z" "z"] x
130130- => []
131131- attrsets.longestValidPathPrefix ["z" "z"] (throw "no need")
132132- => []
167167+168168+ # Inputs
169169+170170+ `attrPath`
171171+172172+ : A list of strings representing the longest possible path that may be returned.
173173+174174+ `v`
175175+176176+ : The nested attribute set to check.
133177134134- Type:
135135- attrsets.longestValidPathPrefix :: [String] -> Value -> [String]
178178+ # Type
179179+180180+ ```
181181+ attrsets.longestValidPathPrefix :: [String] -> Value -> [String]
182182+ ```
183183+184184+ # Examples
185185+ :::{.example}
186186+ ## `lib.attrsets.longestValidPathPrefix` usage example
187187+188188+ ```nix
189189+ x = { a = { b = 3; }; }
190190+ attrsets.longestValidPathPrefix ["a" "b" "c"] x
191191+ => ["a" "b"]
192192+ attrsets.longestValidPathPrefix ["a"] x
193193+ => ["a"]
194194+ attrsets.longestValidPathPrefix ["z" "z"] x
195195+ => []
196196+ attrsets.longestValidPathPrefix ["z" "z"] (throw "no need")
197197+ => []
198198+ ```
199199+200200+ :::
136201 */
137202 longestValidPathPrefix =
138138- # A list of strings representing the longest possible path that may be returned.
139203 attrPath:
140140- # The nested attribute set to check.
141204 v:
142205 let
143206 lenAttrPath = length attrPath;
···168231 in
169232 getPrefixForSetAtIndex v 0;
170233171171- /* Create a new attribute set with `value` set at the nested attribute location specified in `attrPath`.
234234+ /**
235235+ Create a new attribute set with `value` set at the nested attribute location specified in `attrPath`.
236236+237237+238238+ # Inputs
239239+240240+ `attrPath`
241241+242242+ : A list of strings representing the attribute path to set
243243+244244+ `value`
245245+246246+ : The value to set at the location described by `attrPath`
247247+248248+ # Type
249249+250250+ ```
251251+ setAttrByPath :: [String] -> Any -> AttrSet
252252+ ```
172253173173- Example:
174174- setAttrByPath ["a" "b"] 3
175175- => { a = { b = 3; }; }
254254+ # Examples
255255+ :::{.example}
256256+ ## `lib.attrsets.setAttrByPath` usage example
176257177177- Type:
178178- setAttrByPath :: [String] -> Any -> AttrSet
258258+ ```nix
259259+ setAttrByPath ["a" "b"] 3
260260+ => { a = { b = 3; }; }
261261+ ```
262262+263263+ :::
179264 */
180265 setAttrByPath =
181181- # A list of strings representing the attribute path to set
182266 attrPath:
183183- # The value to set at the location described by `attrPath`
184267 value:
185268 let
186269 len = length attrPath;
···190273 else { ${elemAt attrPath n} = atDepth (n + 1); };
191274 in atDepth 0;
192275193193- /* Like `attrByPath`, but without a default value. If it doesn't find the
194194- path it will throw an error.
276276+ /**
277277+ Like `attrByPath`, but without a default value. If it doesn't find the
278278+ path it will throw an error.
195279196196- Nix has an [attribute selection operator](https://nixos.org/manual/nix/stable/language/operators#attribute-selection) which is sufficient for such queries, as long as the number of attributes is static. For example:
280280+ Nix has an [attribute selection operator](https://nixos.org/manual/nix/stable/language/operators#attribute-selection) which is sufficient for such queries, as long as the number of attributes is static. For example:
197281198282 ```nix
199199- x.a.b == getAttrByPath ["a" "b"] x
200200- # and
201201- x.${f p}."example.com" == getAttrByPath [ (f p) "example.com" ] x
202202- ```
283283+ x.a.b == getAttrByPath ["a" "b"] x
284284+ # and
285285+ x.${f p}."example.com" == getAttrByPath [ (f p) "example.com" ] x
286286+ ```
203287204204- Example:
205205- x = { a = { b = 3; }; }
206206- getAttrFromPath ["a" "b"] x
207207- => 3
208208- getAttrFromPath ["z" "z"] x
209209- => error: cannot find attribute `z.z'
288288+289289+ # Inputs
290290+291291+ `attrPath`
292292+293293+ : A list of strings representing the attribute path to get from `set`
294294+295295+ `set`
296296+297297+ : The nested attribute set to find the value in.
298298+299299+ # Type
300300+301301+ ```
302302+ getAttrFromPath :: [String] -> AttrSet -> Any
303303+ ```
304304+305305+ # Examples
306306+ :::{.example}
307307+ ## `lib.attrsets.getAttrFromPath` usage example
308308+309309+ ```nix
310310+ x = { a = { b = 3; }; }
311311+ getAttrFromPath ["a" "b"] x
312312+ => 3
313313+ getAttrFromPath ["z" "z"] x
314314+ => error: cannot find attribute `z.z'
315315+ ```
210316211211- Type:
212212- getAttrFromPath :: [String] -> AttrSet -> Any
317317+ :::
213318 */
214319 getAttrFromPath =
215215- # A list of strings representing the attribute path to get from `set`
216320 attrPath:
217217- # The nested attribute set to find the value in.
218321 set:
219322 attrByPath attrPath (abort ("cannot find attribute `" + concatStringsSep "." attrPath + "'")) set;
220323221221- /* Map each attribute in the given set and merge them into a new attribute set.
324324+ /**
325325+ Map each attribute in the given set and merge them into a new attribute set.
222326223223- Type:
224224- concatMapAttrs :: (String -> a -> AttrSet) -> AttrSet -> AttrSet
225327226226- Example:
227227- concatMapAttrs
228228- (name: value: {
229229- ${name} = value;
230230- ${name + value} = value;
231231- })
232232- { x = "a"; y = "b"; }
233233- => { x = "a"; xa = "a"; y = "b"; yb = "b"; }
328328+ # Inputs
329329+330330+ `f`
331331+332332+ : 1\. Function argument
333333+334334+ `v`
335335+336336+ : 2\. Function argument
337337+338338+ # Type
339339+340340+ ```
341341+ concatMapAttrs :: (String -> a -> AttrSet) -> AttrSet -> AttrSet
342342+ ```
343343+344344+ # Examples
345345+ :::{.example}
346346+ ## `lib.attrsets.concatMapAttrs` usage example
347347+348348+ ```nix
349349+ concatMapAttrs
350350+ (name: value: {
351351+ ${name} = value;
352352+ ${name + value} = value;
353353+ })
354354+ { x = "a"; y = "b"; }
355355+ => { x = "a"; xa = "a"; y = "b"; yb = "b"; }
356356+ ```
357357+358358+ :::
234359 */
235360 concatMapAttrs = f: v:
236361 foldl' mergeAttrs { }
···239364 );
240365241366242242- /* Update or set specific paths of an attribute set.
367367+ /**
368368+ Update or set specific paths of an attribute set.
243369244244- Takes a list of updates to apply and an attribute set to apply them to,
245245- and returns the attribute set with the updates applied. Updates are
246246- represented as `{ path = ...; update = ...; }` values, where `path` is a
247247- list of strings representing the attribute path that should be updated,
248248- and `update` is a function that takes the old value at that attribute path
249249- as an argument and returns the new
250250- value it should be.
370370+ Takes a list of updates to apply and an attribute set to apply them to,
371371+ and returns the attribute set with the updates applied. Updates are
372372+ represented as `{ path = ...; update = ...; }` values, where `path` is a
373373+ list of strings representing the attribute path that should be updated,
374374+ and `update` is a function that takes the old value at that attribute path
375375+ as an argument and returns the new
376376+ value it should be.
251377252252- Properties:
378378+ Properties:
253379254254- - Updates to deeper attribute paths are applied before updates to more
255255- shallow attribute paths
380380+ - Updates to deeper attribute paths are applied before updates to more
381381+ shallow attribute paths
256382257257- - Multiple updates to the same attribute path are applied in the order
258258- they appear in the update list
383383+ - Multiple updates to the same attribute path are applied in the order
384384+ they appear in the update list
259385260260- - If any but the last `path` element leads into a value that is not an
261261- attribute set, an error is thrown
386386+ - If any but the last `path` element leads into a value that is not an
387387+ attribute set, an error is thrown
262388263263- - If there is an update for an attribute path that doesn't exist,
264264- accessing the argument in the update function causes an error, but
265265- intermediate attribute sets are implicitly created as needed
389389+ - If there is an update for an attribute path that doesn't exist,
390390+ accessing the argument in the update function causes an error, but
391391+ intermediate attribute sets are implicitly created as needed
266392267267- Example:
268268- updateManyAttrsByPath [
269269- {
270270- path = [ "a" "b" ];
271271- update = old: { d = old.c; };
272272- }
273273- {
274274- path = [ "a" "b" "c" ];
275275- update = old: old + 1;
276276- }
277277- {
278278- path = [ "x" "y" ];
279279- update = old: "xy";
280280- }
281281- ] { a.b.c = 0; }
282282- => { a = { b = { d = 1; }; }; x = { y = "xy"; }; }
393393+ # Type
394394+395395+ ```
396396+ updateManyAttrsByPath :: [{ path :: [String]; update :: (Any -> Any); }] -> AttrSet -> AttrSet
397397+ ```
398398+399399+ # Examples
400400+ :::{.example}
401401+ ## `lib.attrsets.updateManyAttrsByPath` usage example
402402+403403+ ```nix
404404+ updateManyAttrsByPath [
405405+ {
406406+ path = [ "a" "b" ];
407407+ update = old: { d = old.c; };
408408+ }
409409+ {
410410+ path = [ "a" "b" "c" ];
411411+ update = old: old + 1;
412412+ }
413413+ {
414414+ path = [ "x" "y" ];
415415+ update = old: "xy";
416416+ }
417417+ ] { a.b.c = 0; }
418418+ => { a = { b = { d = 1; }; }; x = { y = "xy"; }; }
419419+ ```
283420284284- Type: updateManyAttrsByPath :: [{ path :: [String]; update :: (Any -> Any); }] -> AttrSet -> AttrSet
421421+ :::
285422 */
286423 updateManyAttrsByPath = let
287424 # When recursing into attributes, instead of updating the `path` of each
···342479343480 in updates: value: go 0 true value updates;
344481345345- /* Return the specified attributes from a set.
482482+ /**
483483+ Return the specified attributes from a set.
346484347347- Example:
348348- attrVals ["a" "b" "c"] as
349349- => [as.a as.b as.c]
485485+486486+ # Inputs
487487+488488+ `nameList`
489489+490490+ : The list of attributes to fetch from `set`. Each attribute name must exist on the attrbitue set
491491+492492+ `set`
493493+494494+ : The set to get attribute values from
495495+496496+ # Type
497497+498498+ ```
499499+ attrVals :: [String] -> AttrSet -> [Any]
500500+ ```
501501+502502+ # Examples
503503+ :::{.example}
504504+ ## `lib.attrsets.attrVals` usage example
505505+506506+ ```nix
507507+ attrVals ["a" "b" "c"] as
508508+ => [as.a as.b as.c]
509509+ ```
350510351351- Type:
352352- attrVals :: [String] -> AttrSet -> [Any]
511511+ :::
353512 */
354513 attrVals =
355355- # The list of attributes to fetch from `set`. Each attribute name must exist on the attrbitue set
356514 nameList:
357357- # The set to get attribute values from
358515 set: map (x: set.${x}) nameList;
359516360517361361- /* Return the values of all attributes in the given set, sorted by
362362- attribute name.
518518+ /**
519519+ Return the values of all attributes in the given set, sorted by
520520+ attribute name.
363521364364- Example:
365365- attrValues {c = 3; a = 1; b = 2;}
366366- => [1 2 3]
522522+ # Type
367523368368- Type:
369369- attrValues :: AttrSet -> [Any]
524524+ ```
525525+ attrValues :: AttrSet -> [Any]
526526+ ```
527527+528528+ # Examples
529529+ :::{.example}
530530+ ## `lib.attrsets.attrValues` usage example
531531+532532+ ```nix
533533+ attrValues {c = 3; a = 1; b = 2;}
534534+ => [1 2 3]
535535+ ```
536536+537537+ :::
370538 */
371539 attrValues = builtins.attrValues;
372540373541374374- /* Given a set of attribute names, return the set of the corresponding
375375- attributes from the given set.
542542+ /**
543543+ Given a set of attribute names, return the set of the corresponding
544544+ attributes from the given set.
545545+546546+547547+ # Inputs
548548+549549+ `names`
550550+551551+ : A list of attribute names to get out of `set`
552552+553553+ `attrs`
554554+555555+ : The set to get the named attributes from
556556+557557+ # Type
376558377377- Example:
378378- getAttrs [ "a" "b" ] { a = 1; b = 2; c = 3; }
379379- => { a = 1; b = 2; }
559559+ ```
560560+ getAttrs :: [String] -> AttrSet -> AttrSet
561561+ ```
562562+563563+ # Examples
564564+ :::{.example}
565565+ ## `lib.attrsets.getAttrs` usage example
566566+567567+ ```nix
568568+ getAttrs [ "a" "b" ] { a = 1; b = 2; c = 3; }
569569+ => { a = 1; b = 2; }
570570+ ```
380571381381- Type:
382382- getAttrs :: [String] -> AttrSet -> AttrSet
572572+ :::
383573 */
384574 getAttrs =
385385- # A list of attribute names to get out of `set`
386575 names:
387387- # The set to get the named attributes from
388576 attrs: genAttrs names (name: attrs.${name});
389577390390- /* Collect each attribute named `attr` from a list of attribute
391391- sets. Sets that don't contain the named attribute are ignored.
578578+ /**
579579+ Collect each attribute named `attr` from a list of attribute
580580+ sets. Sets that don't contain the named attribute are ignored.
392581393393- Example:
394394- catAttrs "a" [{a = 1;} {b = 0;} {a = 2;}]
395395- => [1 2]
582582+ # Inputs
396583397397- Type:
398398- catAttrs :: String -> [AttrSet] -> [Any]
584584+ `attr`
585585+586586+ : The attribute name to get out of the sets.
587587+588588+ `list`
589589+590590+ : The list of attribute sets to go through
591591+592592+ # Type
593593+594594+ ```
595595+ catAttrs :: String -> [AttrSet] -> [Any]
596596+ ```
597597+598598+ # Examples
599599+ :::{.example}
600600+ ## `lib.attrsets.catAttrs` usage example
601601+602602+ ```nix
603603+ catAttrs "a" [{a = 1;} {b = 0;} {a = 2;}]
604604+ => [1 2]
605605+ ```
606606+607607+ :::
399608 */
400609 catAttrs = builtins.catAttrs;
401610402611403403- /* Filter an attribute set by removing all attributes for which the
404404- given predicate return false.
612612+ /**
613613+ Filter an attribute set by removing all attributes for which the
614614+ given predicate return false.
615615+616616+617617+ # Inputs
618618+619619+ `pred`
620620+621621+ : Predicate taking an attribute name and an attribute value, which returns `true` to include the attribute, or `false` to exclude the attribute.
622622+623623+ `set`
405624406406- Example:
407407- filterAttrs (n: v: n == "foo") { foo = 1; bar = 2; }
408408- => { foo = 1; }
625625+ : The attribute set to filter
409626410410- Type:
411411- filterAttrs :: (String -> Any -> Bool) -> AttrSet -> AttrSet
627627+ # Type
628628+629629+ ```
630630+ filterAttrs :: (String -> Any -> Bool) -> AttrSet -> AttrSet
631631+ ```
632632+633633+ # Examples
634634+ :::{.example}
635635+ ## `lib.attrsets.filterAttrs` usage example
636636+637637+ ```nix
638638+ filterAttrs (n: v: n == "foo") { foo = 1; bar = 2; }
639639+ => { foo = 1; }
640640+ ```
641641+642642+ :::
412643 */
413644 filterAttrs =
414414- # Predicate taking an attribute name and an attribute value, which returns `true` to include the attribute, or `false` to exclude the attribute.
415645 pred:
416416- # The attribute set to filter
417646 set:
418647 listToAttrs (concatMap (name: let v = set.${name}; in if pred name v then [(nameValuePair name v)] else []) (attrNames set));
419648420649421421- /* Filter an attribute set recursively by removing all attributes for
422422- which the given predicate return false.
650650+ /**
651651+ Filter an attribute set recursively by removing all attributes for
652652+ which the given predicate return false.
653653+654654+655655+ # Inputs
656656+657657+ `pred`
658658+659659+ : Predicate taking an attribute name and an attribute value, which returns `true` to include the attribute, or `false` to exclude the attribute.
660660+661661+ `set`
662662+663663+ : The attribute set to filter
664664+665665+ # Type
666666+667667+ ```
668668+ filterAttrsRecursive :: (String -> Any -> Bool) -> AttrSet -> AttrSet
669669+ ```
423670424424- Example:
425425- filterAttrsRecursive (n: v: v != null) { foo = { bar = null; }; }
426426- => { foo = {}; }
671671+ # Examples
672672+ :::{.example}
673673+ ## `lib.attrsets.filterAttrsRecursive` usage example
674674+675675+ ```nix
676676+ filterAttrsRecursive (n: v: v != null) { foo = { bar = null; }; }
677677+ => { foo = {}; }
678678+ ```
427679428428- Type:
429429- filterAttrsRecursive :: (String -> Any -> Bool) -> AttrSet -> AttrSet
680680+ :::
430681 */
431682 filterAttrsRecursive =
432432- # Predicate taking an attribute name and an attribute value, which returns `true` to include the attribute, or `false` to exclude the attribute.
433683 pred:
434434- # The attribute set to filter
435684 set:
436685 listToAttrs (
437686 concatMap (name:
···445694 ) (attrNames set)
446695 );
447696448448- /*
697697+ /**
449698 Like [`lib.lists.foldl'`](#function-library-lib.lists.foldl-prime) but for attribute sets.
450699 Iterates over every name-value pair in the given attribute set.
451700 The result of the callback function is often called `acc` for accumulator. It is passed between callbacks from left to right and the final `acc` is the return value of `foldlAttrs`.
452701453702 Attention:
454454- There is a completely different function
455455- `lib.foldAttrs`
456456- which has nothing to do with this function, despite the similar name.
457703458458- Example:
459459- foldlAttrs
460460- (acc: name: value: {
461461- sum = acc.sum + value;
462462- names = acc.names ++ [name];
463463- })
464464- { sum = 0; names = []; }
465465- {
466466- foo = 1;
467467- bar = 10;
468468- }
469469- ->
470470- {
471471- sum = 11;
472472- names = ["bar" "foo"];
473473- }
704704+ There is a completely different function `lib.foldAttrs`
705705+ which has nothing to do with this function, despite the similar name.
706706+707707+708708+ # Inputs
709709+710710+ `f`
711711+712712+ : 1\. Function argument
713713+714714+ `init`
715715+716716+ : 2\. Function argument
717717+718718+ `set`
474719475475- foldlAttrs
476476- (throw "function not needed")
477477- 123
478478- {};
479479- ->
480480- 123
720720+ : 3\. Function argument
481721482482- foldlAttrs
483483- (acc: _: _: acc)
484484- 3
485485- { z = throw "value not needed"; a = throw "value not needed"; };
486486- ->
487487- 3
722722+ # Type
488723489489- The accumulator doesn't have to be an attrset.
490490- It can be as simple as a number or string.
724724+ ```
725725+ foldlAttrs :: ( a -> String -> b -> a ) -> a -> { ... :: b } -> a
726726+ ```
491727492492- foldlAttrs
493493- (acc: _: v: acc * 10 + v)
494494- 1
495495- { z = 1; a = 2; };
496496- ->
497497- 121
728728+ # Examples
729729+ :::{.example}
730730+ ## `lib.attrsets.foldlAttrs` usage example
498731499499- Type:
500500- foldlAttrs :: ( a -> String -> b -> a ) -> a -> { ... :: b } -> a
732732+ ```nix
733733+ foldlAttrs
734734+ (acc: name: value: {
735735+ sum = acc.sum + value;
736736+ names = acc.names ++ [name];
737737+ })
738738+ { sum = 0; names = []; }
739739+ {
740740+ foo = 1;
741741+ bar = 10;
742742+ }
743743+ ->
744744+ {
745745+ sum = 11;
746746+ names = ["bar" "foo"];
747747+ }
748748+749749+ foldlAttrs
750750+ (throw "function not needed")
751751+ 123
752752+ {};
753753+ ->
754754+ 123
755755+756756+ foldlAttrs
757757+ (acc: _: _: acc)
758758+ 3
759759+ { z = throw "value not needed"; a = throw "value not needed"; };
760760+ ->
761761+ 3
762762+763763+ The accumulator doesn't have to be an attrset.
764764+ It can be as simple as a number or string.
765765+766766+ foldlAttrs
767767+ (acc: _: v: acc * 10 + v)
768768+ 1
769769+ { z = 1; a = 2; };
770770+ ->
771771+ 121
772772+ ```
773773+774774+ :::
501775 */
502776 foldlAttrs = f: init: set:
503777 foldl'
···505779 init
506780 (attrNames set);
507781508508- /* Apply fold functions to values grouped by key.
782782+ /**
783783+ Apply fold functions to values grouped by key.
509784510510- Example:
511511- foldAttrs (item: acc: [item] ++ acc) [] [{ a = 2; } { a = 3; }]
512512- => { a = [ 2 3 ]; }
785785+786786+ # Inputs
513787514514- Type:
515515- foldAttrs :: (Any -> Any -> Any) -> Any -> [AttrSets] -> Any
788788+ `op`
516789790790+ : A function, given a value and a collector combines the two.
791791+792792+ `nul`
793793+794794+ : The starting value.
795795+796796+ `list_of_attrs`
797797+798798+ : A list of attribute sets to fold together by key.
799799+800800+ # Type
801801+802802+ ```
803803+ foldAttrs :: (Any -> Any -> Any) -> Any -> [AttrSets] -> Any
804804+ ```
805805+806806+ # Examples
807807+ :::{.example}
808808+ ## `lib.attrsets.foldAttrs` usage example
809809+810810+ ```nix
811811+ foldAttrs (item: acc: [item] ++ acc) [] [{ a = 2; } { a = 3; }]
812812+ => { a = [ 2 3 ]; }
813813+ ```
814814+815815+ :::
517816 */
518817 foldAttrs =
519519- # A function, given a value and a collector combines the two.
520818 op:
521521- # The starting value.
522819 nul:
523523- # A list of attribute sets to fold together by key.
524820 list_of_attrs:
525821 foldr (n: a:
526822 foldr (name: o:
···529825 ) {} list_of_attrs;
530826531827532532- /* Recursively collect sets that verify a given predicate named `pred`
533533- from the set `attrs`. The recursion is stopped when the predicate is
534534- verified.
828828+ /**
829829+ Recursively collect sets that verify a given predicate named `pred`
830830+ from the set `attrs`. The recursion is stopped when the predicate is
831831+ verified.
832832+833833+834834+ # Inputs
835835+836836+ `pred`
837837+838838+ : Given an attribute's value, determine if recursion should stop.
839839+840840+ `attrs`
841841+842842+ : The attribute set to recursively collect.
535843536536- Example:
537537- collect isList { a = { b = ["b"]; }; c = [1]; }
538538- => [["b"] [1]]
844844+ # Type
539845540540- collect (x: x ? outPath)
541541- { a = { outPath = "a/"; }; b = { outPath = "b/"; }; }
542542- => [{ outPath = "a/"; } { outPath = "b/"; }]
846846+ ```
847847+ collect :: (AttrSet -> Bool) -> AttrSet -> [x]
848848+ ```
543849544544- Type:
545545- collect :: (AttrSet -> Bool) -> AttrSet -> [x]
850850+ # Examples
851851+ :::{.example}
852852+ ## `lib.attrsets.collect` usage example
853853+854854+ ```nix
855855+ collect isList { a = { b = ["b"]; }; c = [1]; }
856856+ => [["b"] [1]]
857857+858858+ collect (x: x ? outPath)
859859+ { a = { outPath = "a/"; }; b = { outPath = "b/"; }; }
860860+ => [{ outPath = "a/"; } { outPath = "b/"; }]
861861+ ```
862862+863863+ :::
546864 */
547865 collect =
548548- # Given an attribute's value, determine if recursion should stop.
549549- pred:
550550- # The attribute set to recursively collect.
551551- attrs:
866866+ pred:
867867+ attrs:
552868 if pred attrs then
553869 [ attrs ]
554870 else if isAttrs attrs then
···556872 else
557873 [];
558874559559- /* Return the cartesian product of attribute set value combinations.
875875+ /**
876876+ Return the cartesian product of attribute set value combinations.
877877+878878+879879+ # Inputs
880880+881881+ `attrsOfLists`
882882+883883+ : Attribute set with attributes that are lists of values
884884+885885+ # Type
886886+887887+ ```
888888+ cartesianProductOfSets :: AttrSet -> [AttrSet]
889889+ ```
890890+891891+ # Examples
892892+ :::{.example}
893893+ ## `lib.attrsets.cartesianProductOfSets` usage example
894894+895895+ ```nix
896896+ cartesianProductOfSets { a = [ 1 2 ]; b = [ 10 20 ]; }
897897+ => [
898898+ { a = 1; b = 10; }
899899+ { a = 1; b = 20; }
900900+ { a = 2; b = 10; }
901901+ { a = 2; b = 20; }
902902+ ]
903903+ ```
560904561561- Example:
562562- cartesianProductOfSets { a = [ 1 2 ]; b = [ 10 20 ]; }
563563- => [
564564- { a = 1; b = 10; }
565565- { a = 1; b = 20; }
566566- { a = 2; b = 10; }
567567- { a = 2; b = 20; }
568568- ]
569569- Type:
570570- cartesianProductOfSets :: AttrSet -> [AttrSet]
905905+ :::
571906 */
572907 cartesianProductOfSets =
573573- # Attribute set with attributes that are lists of values
574908 attrsOfLists:
575909 foldl' (listOfAttrs: attrName:
576910 concatMap (attrs:
···579913 ) [{}] (attrNames attrsOfLists);
580914581915582582- /* Utility function that creates a `{name, value}` pair as expected by `builtins.listToAttrs`.
916916+ /**
917917+ Utility function that creates a `{name, value}` pair as expected by `builtins.listToAttrs`.
583918584584- Example:
585585- nameValuePair "some" 6
586586- => { name = "some"; value = 6; }
587919588588- Type:
589589- nameValuePair :: String -> Any -> { name :: String; value :: Any; }
920920+ # Inputs
921921+922922+ `name`
923923+924924+ : Attribute name
925925+926926+ `value`
927927+928928+ : Attribute value
929929+930930+ # Type
931931+932932+ ```
933933+ nameValuePair :: String -> Any -> { name :: String; value :: Any; }
934934+ ```
935935+936936+ # Examples
937937+ :::{.example}
938938+ ## `lib.attrsets.nameValuePair` usage example
939939+940940+ ```nix
941941+ nameValuePair "some" 6
942942+ => { name = "some"; value = 6; }
943943+ ```
944944+945945+ :::
590946 */
591947 nameValuePair =
592592- # Attribute name
593948 name:
594594- # Attribute value
595949 value:
596950 { inherit name value; };
597951598952599599- /* Apply a function to each element in an attribute set, creating a new attribute set.
953953+ /**
954954+ Apply a function to each element in an attribute set, creating a new attribute set.
600955601601- Example:
602602- mapAttrs (name: value: name + "-" + value)
603603- { x = "foo"; y = "bar"; }
604604- => { x = "x-foo"; y = "y-bar"; }
956956+ # Inputs
605957606606- Type:
607607- mapAttrs :: (String -> Any -> Any) -> AttrSet -> AttrSet
958958+ `f`
959959+960960+ : A function that takes an attribute name and its value, and returns the new value for the attribute.
961961+962962+ `attrset`
963963+964964+ : The attribute set to iterate through.
965965+966966+ # Type
967967+968968+ ```
969969+ mapAttrs :: (String -> Any -> Any) -> AttrSet -> AttrSet
970970+ ```
971971+972972+ # Examples
973973+ :::{.example}
974974+ ## `lib.attrsets.mapAttrs` usage example
975975+976976+ ```nix
977977+ mapAttrs (name: value: name + "-" + value)
978978+ { x = "foo"; y = "bar"; }
979979+ => { x = "x-foo"; y = "y-bar"; }
980980+ ```
981981+982982+ :::
608983 */
609984 mapAttrs = builtins.mapAttrs;
610985611986612612- /* Like `mapAttrs`, but allows the name of each attribute to be
613613- changed in addition to the value. The applied function should
614614- return both the new name and value as a `nameValuePair`.
987987+ /**
988988+ Like `mapAttrs`, but allows the name of each attribute to be
989989+ changed in addition to the value. The applied function should
990990+ return both the new name and value as a `nameValuePair`.
991991+992992+993993+ # Inputs
994994+995995+ `f`
996996+997997+ : A function, given an attribute's name and value, returns a new `nameValuePair`.
998998+999999+ `set`
10001000+10011001+ : Attribute set to map over.
10021002+10031003+ # Type
10041004+10051005+ ```
10061006+ mapAttrs' :: (String -> Any -> { name :: String; value :: Any; }) -> AttrSet -> AttrSet
10071007+ ```
10081008+10091009+ # Examples
10101010+ :::{.example}
10111011+ ## `lib.attrsets.mapAttrs'` usage example
6151012616616- Example:
617617- mapAttrs' (name: value: nameValuePair ("foo_" + name) ("bar-" + value))
618618- { x = "a"; y = "b"; }
619619- => { foo_x = "bar-a"; foo_y = "bar-b"; }
10131013+ ```nix
10141014+ mapAttrs' (name: value: nameValuePair ("foo_" + name) ("bar-" + value))
10151015+ { x = "a"; y = "b"; }
10161016+ => { foo_x = "bar-a"; foo_y = "bar-b"; }
10171017+ ```
6201018621621- Type:
622622- mapAttrs' :: (String -> Any -> { name :: String; value :: Any; }) -> AttrSet -> AttrSet
10191019+ :::
6231020 */
6241021 mapAttrs' =
625625- # A function, given an attribute's name and value, returns a new `nameValuePair`.
6261022 f:
627627- # Attribute set to map over.
6281023 set:
6291024 listToAttrs (map (attr: f attr set.${attr}) (attrNames set));
63010256311026632632- /* Call a function for each attribute in the given set and return
633633- the result in a list.
10271027+ /**
10281028+ Call a function for each attribute in the given set and return
10291029+ the result in a list.
6341030635635- Example:
636636- mapAttrsToList (name: value: name + value)
637637- { x = "a"; y = "b"; }
638638- => [ "xa" "yb" ]
10311031+ # Inputs
10321032+10331033+ `f`
10341034+10351035+ : A function, given an attribute's name and value, returns a new value.
10361036+10371037+ `attrs`
10381038+10391039+ : Attribute set to map over.
10401040+10411041+ # Type
10421042+10431043+ ```
10441044+ mapAttrsToList :: (String -> a -> b) -> AttrSet -> [b]
10451045+ ```
6391046640640- Type:
641641- mapAttrsToList :: (String -> a -> b) -> AttrSet -> [b]
10471047+ # Examples
10481048+ :::{.example}
10491049+ ## `lib.attrsets.mapAttrsToList` usage example
642105010511051+ ```nix
10521052+ mapAttrsToList (name: value: name + value)
10531053+ { x = "a"; y = "b"; }
10541054+ => [ "xa" "yb" ]
10551055+ ```
10561056+10571057+ :::
6431058 */
6441059 mapAttrsToList =
645645- # A function, given an attribute's name and value, returns a new value.
6461060 f:
647647- # Attribute set to map over.
6481061 attrs:
6491062 map (name: f name attrs.${name}) (attrNames attrs);
6501063651651- /*
10641064+ /**
6521065 Deconstruct an attrset to a list of name-value pairs as expected by [`builtins.listToAttrs`](https://nixos.org/manual/nix/stable/language/builtins.html#builtins-listToAttrs).
6531066 Each element of the resulting list is an attribute set with these attributes:
6541067 - `name` (string): The name of the attribute
···6681081 This is because the `listToAttrs` removes duplicate names and doesn't preserve the order of the list.
6691082 :::
6701083671671- Example:
672672- attrsToList { foo = 1; bar = "asdf"; }
673673- => [ { name = "bar"; value = "asdf"; } { name = "foo"; value = 1; } ]
10841084+ # Inputs
10851085+10861086+ `set`
10871087+10881088+ : The attribute set to deconstruct.
6741089675675- Type:
676676- attrsToList :: AttrSet -> [ { name :: String; value :: Any; } ]
10901090+ # Type
677109110921092+ ```
10931093+ attrsToList :: AttrSet -> [ { name :: String; value :: Any; } ]
10941094+ ```
10951095+10961096+ # Examples
10971097+ :::{.example}
10981098+ ## `lib.attrsets.attrsToList` usage example
10991099+11001100+ ```nix
11011101+ attrsToList { foo = 1; bar = "asdf"; }
11021102+ => [ { name = "bar"; value = "asdf"; } { name = "foo"; value = 1; } ]
11031103+ ```
11041104+11051105+ :::
6781106 */
6791107 attrsToList = mapAttrsToList nameValuePair;
6801108···7051133 ```
7061134 */
7071135 mapAttrsRecursive =
708708- # A function that, given an attribute path as a list of strings and the corresponding attribute value, returns a new value.
7091136 f:
710710- # Attribute set to recursively map over.
7111137 set:
7121138 mapAttrsRecursiveCond (as: true) f set;
7131139···7361162 ```
7371163 */
7381164 mapAttrsRecursiveCond =
739739- # A function that, given the attribute set the recursion is currently at, determines if to recurse deeper into that attribute set.
7401165 cond:
741741- # A function that, given an attribute path as a list of strings and the corresponding attribute value, returns a new value.
742742- # The attribute value is either an attribute set for which `cond` returns false, or something other than an attribute set.
7431166 f:
744744- # Attribute set to recursively map over.
7451167 set:
7461168 let
7471169 recurse = path:
···7541176 recurse [ ] set;
75511777561178757757- /* Generate an attribute set by mapping a function over a list of
758758- attribute names.
11791179+ /**
11801180+ Generate an attribute set by mapping a function over a list of
11811181+ attribute names.
11821182+11831183+11841184+ # Inputs
11851185+11861186+ `names`
11871187+11881188+ : Names of values in the resulting attribute set.
11891189+11901190+ `f`
11911191+11921192+ : A function, given the name of the attribute, returns the attribute's value.
11931193+11941194+ # Type
11951195+11961196+ ```
11971197+ genAttrs :: [ String ] -> (String -> Any) -> AttrSet
11981198+ ```
11991199+12001200+ # Examples
12011201+ :::{.example}
12021202+ ## `lib.attrsets.genAttrs` usage example
7591203760760- Example:
761761- genAttrs [ "foo" "bar" ] (name: "x_" + name)
762762- => { foo = "x_foo"; bar = "x_bar"; }
12041204+ ```nix
12051205+ genAttrs [ "foo" "bar" ] (name: "x_" + name)
12061206+ => { foo = "x_foo"; bar = "x_bar"; }
12071207+ ```
7631208764764- Type:
765765- genAttrs :: [ String ] -> (String -> Any) -> AttrSet
12091209+ :::
7661210 */
7671211 genAttrs =
768768- # Names of values in the resulting attribute set.
7691212 names:
770770- # A function, given the name of the attribute, returns the attribute's value.
7711213 f:
7721214 listToAttrs (map (n: nameValuePair n (f n)) names);
77312157741216775775- /* Check whether the argument is a derivation. Any set with
776776- `{ type = "derivation"; }` counts as a derivation.
12171217+ /**
12181218+ Check whether the argument is a derivation. Any set with
12191219+ `{ type = "derivation"; }` counts as a derivation.
7771220778778- Example:
779779- nixpkgs = import <nixpkgs> {}
780780- isDerivation nixpkgs.ruby
781781- => true
782782- isDerivation "foobar"
783783- => false
7841221785785- Type:
786786- isDerivation :: Any -> Bool
12221222+ # Inputs
12231223+12241224+ `value`
12251225+12261226+ : Value to check.
12271227+12281228+ # Type
12291229+12301230+ ```
12311231+ isDerivation :: Any -> Bool
12321232+ ```
12331233+12341234+ # Examples
12351235+ :::{.example}
12361236+ ## `lib.attrsets.isDerivation` usage example
12371237+12381238+ ```nix
12391239+ nixpkgs = import <nixpkgs> {}
12401240+ isDerivation nixpkgs.ruby
12411241+ => true
12421242+ isDerivation "foobar"
12431243+ => false
12441244+ ```
12451245+12461246+ :::
7871247 */
7881248 isDerivation =
789789- # Value to check.
7901249 value: value.type or null == "derivation";
7911250792792- /* Converts a store path to a fake derivation.
12511251+ /**
12521252+ Converts a store path to a fake derivation.
12531253+7931254794794- Type:
795795- toDerivation :: Path -> Derivation
796796- */
12551255+ # Inputs
12561256+12571257+ `path`
12581258+12591259+ : A store path to convert to a derivation.
12601260+12611261+ # Type
12621262+12631263+ ```
12641264+ toDerivation :: Path -> Derivation
12651265+ ```
12661266+ */
7971267 toDerivation =
798798- # A store path to convert to a derivation.
7991268 path:
8001269 let
8011270 path' = builtins.storePath path;
···8101279 in res;
81112808121281813813- /* If `cond` is true, return the attribute set `as`,
814814- otherwise an empty attribute set.
12821282+ /**
12831283+ If `cond` is true, return the attribute set `as`,
12841284+ otherwise an empty attribute set.
8151285816816- Example:
817817- optionalAttrs (true) { my = "set"; }
818818- => { my = "set"; }
819819- optionalAttrs (false) { my = "set"; }
820820- => { }
8211286822822- Type:
823823- optionalAttrs :: Bool -> AttrSet -> AttrSet
12871287+ # Inputs
12881288+12891289+ `cond`
12901290+12911291+ : Condition under which the `as` attribute set is returned.
12921292+12931293+ `as`
12941294+12951295+ : The attribute set to return if `cond` is `true`.
12961296+12971297+ # Type
12981298+12991299+ ```
13001300+ optionalAttrs :: Bool -> AttrSet -> AttrSet
13011301+ ```
13021302+13031303+ # Examples
13041304+ :::{.example}
13051305+ ## `lib.attrsets.optionalAttrs` usage example
13061306+13071307+ ```nix
13081308+ optionalAttrs (true) { my = "set"; }
13091309+ => { my = "set"; }
13101310+ optionalAttrs (false) { my = "set"; }
13111311+ => { }
13121312+ ```
13131313+13141314+ :::
8241315 */
8251316 optionalAttrs =
826826- # Condition under which the `as` attribute set is returned.
8271317 cond:
828828- # The attribute set to return if `cond` is `true`.
8291318 as:
8301319 if cond then as else {};
83113208321321833833- /* Merge sets of attributes and use the function `f` to merge attributes
834834- values.
13221322+ /**
13231323+ Merge sets of attributes and use the function `f` to merge attributes
13241324+ values.
8351325836836- Example:
837837- zipAttrsWithNames ["a"] (name: vs: vs) [{a = "x";} {a = "y"; b = "z";}]
838838- => { a = ["x" "y"]; }
13261326+13271327+ # Inputs
8391328840840- Type:
841841- zipAttrsWithNames :: [ String ] -> (String -> [ Any ] -> Any) -> [ AttrSet ] -> AttrSet
13291329+ `names`
13301330+13311331+ : List of attribute names to zip.
13321332+13331333+ `f`
13341334+13351335+ : A function, accepts an attribute name, all the values, and returns a combined value.
13361336+13371337+ `sets`
13381338+13391339+ : List of values from the list of attribute sets.
13401340+13411341+ # Type
13421342+13431343+ ```
13441344+ zipAttrsWithNames :: [ String ] -> (String -> [ Any ] -> Any) -> [ AttrSet ] -> AttrSet
13451345+ ```
13461346+13471347+ # Examples
13481348+ :::{.example}
13491349+ ## `lib.attrsets.zipAttrsWithNames` usage example
13501350+13511351+ ```nix
13521352+ zipAttrsWithNames ["a"] (name: vs: vs) [{a = "x";} {a = "y"; b = "z";}]
13531353+ => { a = ["x" "y"]; }
13541354+ ```
13551355+13561356+ :::
8421357 */
8431358 zipAttrsWithNames =
844844- # List of attribute names to zip.
8451359 names:
846846- # A function, accepts an attribute name, all the values, and returns a combined value.
8471360 f:
848848- # List of values from the list of attribute sets.
8491361 sets:
8501362 listToAttrs (map (name: {
8511363 inherit name;
···8531365 }) names);
85413668551367856856- /* Merge sets of attributes and use the function f to merge attribute values.
857857- Like `lib.attrsets.zipAttrsWithNames` with all key names are passed for `names`.
13681368+ /**
13691369+ Merge sets of attributes and use the function f to merge attribute values.
13701370+ Like `lib.attrsets.zipAttrsWithNames` with all key names are passed for `names`.
13711371+13721372+ Implementation note: Common names appear multiple times in the list of
13731373+ names, hopefully this does not affect the system because the maximal
13741374+ laziness avoid computing twice the same expression and `listToAttrs` does
13751375+ not care about duplicated attribute names.
13761376+13771377+ # Type
13781378+13791379+ ```
13801380+ zipAttrsWith :: (String -> [ Any ] -> Any) -> [ AttrSet ] -> AttrSet
13811381+ ```
8581382859859- Implementation note: Common names appear multiple times in the list of
860860- names, hopefully this does not affect the system because the maximal
861861- laziness avoid computing twice the same expression and `listToAttrs` does
862862- not care about duplicated attribute names.
13831383+ # Examples
13841384+ :::{.example}
13851385+ ## `lib.attrsets.zipAttrsWith` usage example
8631386864864- Example:
865865- zipAttrsWith (name: values: values) [{a = "x";} {a = "y"; b = "z";}]
866866- => { a = ["x" "y"]; b = ["z"]; }
13871387+ ```nix
13881388+ zipAttrsWith (name: values: values) [{a = "x";} {a = "y"; b = "z";}]
13891389+ => { a = ["x" "y"]; b = ["z"]; }
13901390+ ```
8671391868868- Type:
869869- zipAttrsWith :: (String -> [ Any ] -> Any) -> [ AttrSet ] -> AttrSet
13921392+ :::
8701393 */
8711394 zipAttrsWith =
8721395 builtins.zipAttrsWith or (f: sets: zipAttrsWithNames (concatMap attrNames sets) f sets);
87313968741397875875- /* Merge sets of attributes and combine each attribute value in to a list.
13981398+ /**
13991399+ Merge sets of attributes and combine each attribute value in to a list.
8761400877877- Like `lib.attrsets.zipAttrsWith` with `(name: values: values)` as the function.
14011401+ Like `lib.attrsets.zipAttrsWith` with `(name: values: values)` as the function.
8781402879879- Example:
880880- zipAttrs [{a = "x";} {a = "y"; b = "z";}]
881881- => { a = ["x" "y"]; b = ["z"]; }
14031403+ # Type
14041404+14051405+ ```
14061406+ zipAttrs :: [ AttrSet ] -> AttrSet
14071407+ ```
14081408+14091409+ # Examples
14101410+ :::{.example}
14111411+ ## `lib.attrsets.zipAttrs` usage example
14121412+14131413+ ```nix
14141414+ zipAttrs [{a = "x";} {a = "y"; b = "z";}]
14151415+ => { a = ["x" "y"]; b = ["z"]; }
14161416+ ```
8821417883883- Type:
884884- zipAttrs :: [ AttrSet ] -> AttrSet
14181418+ :::
8851419 */
8861420 zipAttrs = zipAttrsWith (name: values: values);
8871421888888- /*
14221422+ /**
8891423 Merge a list of attribute sets together using the `//` operator.
8901424 In case of duplicate attributes, values from later list elements take precedence over earlier ones.
8911425 The result is the same as `foldl mergeAttrs { }`, but the performance is better for large inputs.
8921426 For n list elements, each with an attribute set containing m unique attributes, the complexity of this operation is O(nm log n).
8931427894894- Type:
895895- mergeAttrsList :: [ Attrs ] -> Attrs
14281428+14291429+ # Inputs
14301430+14311431+ `list`
14321432+14331433+ : 1\. Function argument
14341434+14351435+ # Type
14361436+14371437+ ```
14381438+ mergeAttrsList :: [ Attrs ] -> Attrs
14391439+ ```
8961440897897- Example:
898898- mergeAttrsList [ { a = 0; b = 1; } { c = 2; d = 3; } ]
899899- => { a = 0; b = 1; c = 2; d = 3; }
900900- mergeAttrsList [ { a = 0; } { a = 1; } ]
901901- => { a = 1; }
14411441+ # Examples
14421442+ :::{.example}
14431443+ ## `lib.attrsets.mergeAttrsList` usage example
14441444+14451445+ ```nix
14461446+ mergeAttrsList [ { a = 0; b = 1; } { c = 2; d = 3; } ]
14471447+ => { a = 0; b = 1; c = 2; d = 3; }
14481448+ mergeAttrsList [ { a = 0; } { a = 1; } ]
14491449+ => { a = 1; }
14501450+ ```
14511451+14521452+ :::
9021453 */
9031454 mergeAttrsList = list:
9041455 let
···9221473 binaryMerge 0 (length list);
92314749241475925925- /* Does the same as the update operator '//' except that attributes are
926926- merged until the given predicate is verified. The predicate should
927927- accept 3 arguments which are the path to reach the attribute, a part of
928928- the first attribute set and a part of the second attribute set. When
929929- the predicate is satisfied, the value of the first attribute set is
930930- replaced by the value of the second attribute set.
14761476+ /**
14771477+ Does the same as the update operator '//' except that attributes are
14781478+ merged until the given predicate is verified. The predicate should
14791479+ accept 3 arguments which are the path to reach the attribute, a part of
14801480+ the first attribute set and a part of the second attribute set. When
14811481+ the predicate is satisfied, the value of the first attribute set is
14821482+ replaced by the value of the second attribute set.
9311483932932- Example:
933933- recursiveUpdateUntil (path: l: r: path == ["foo"]) {
934934- # first attribute set
935935- foo.bar = 1;
936936- foo.baz = 2;
937937- bar = 3;
938938- } {
939939- #second attribute set
940940- foo.bar = 1;
941941- foo.quz = 2;
942942- baz = 4;
943943- }
14841484+14851485+ # Inputs
14861486+14871487+ `pred`
14881488+14891489+ : Predicate, taking the path to the current attribute as a list of strings for attribute names, and the two values at that path from the original arguments.
14901490+14911491+ `lhs`
14921492+14931493+ : Left attribute set of the merge.
14941494+14951495+ `rhs`
14961496+14971497+ : Right attribute set of the merge.
14981498+14991499+ # Type
15001500+15011501+ ```
15021502+ recursiveUpdateUntil :: ( [ String ] -> AttrSet -> AttrSet -> Bool ) -> AttrSet -> AttrSet -> AttrSet
15031503+ ```
9441504945945- => {
946946- foo.bar = 1; # 'foo.*' from the second set
947947- foo.quz = 2; #
948948- bar = 3; # 'bar' from the first set
949949- baz = 4; # 'baz' from the second set
950950- }
15051505+ # Examples
15061506+ :::{.example}
15071507+ ## `lib.attrsets.recursiveUpdateUntil` usage example
9511508952952- Type:
953953- recursiveUpdateUntil :: ( [ String ] -> AttrSet -> AttrSet -> Bool ) -> AttrSet -> AttrSet -> AttrSet
15091509+ ```nix
15101510+ recursiveUpdateUntil (path: l: r: path == ["foo"]) {
15111511+ # first attribute set
15121512+ foo.bar = 1;
15131513+ foo.baz = 2;
15141514+ bar = 3;
15151515+ } {
15161516+ #second attribute set
15171517+ foo.bar = 1;
15181518+ foo.quz = 2;
15191519+ baz = 4;
15201520+ }
15211521+15221522+ => {
15231523+ foo.bar = 1; # 'foo.*' from the second set
15241524+ foo.quz = 2; #
15251525+ bar = 3; # 'bar' from the first set
15261526+ baz = 4; # 'baz' from the second set
15271527+ }
15281528+ ```
15291529+15301530+ :::
9541531 */
9551532 recursiveUpdateUntil =
956956- # Predicate, taking the path to the current attribute as a list of strings for attribute names, and the two values at that path from the original arguments.
9571533 pred:
958958- # Left attribute set of the merge.
9591534 lhs:
960960- # Right attribute set of the merge.
9611535 rhs:
9621536 let f = attrPath:
9631537 zipAttrsWith (n: values:
···9711545 in f [] [rhs lhs];
97215469731547974974- /* A recursive variant of the update operator ‘//’. The recursion
975975- stops when one of the attribute values is not an attribute set,
976976- in which case the right hand side value takes precedence over the
977977- left hand side value.
15481548+ /**
15491549+ A recursive variant of the update operator ‘//’. The recursion
15501550+ stops when one of the attribute values is not an attribute set,
15511551+ in which case the right hand side value takes precedence over the
15521552+ left hand side value.
15531553+15541554+15551555+ # Inputs
15561556+15571557+ `lhs`
15581558+15591559+ : Left attribute set of the merge.
9781560979979- Example:
980980- recursiveUpdate {
981981- boot.loader.grub.enable = true;
982982- boot.loader.grub.device = "/dev/hda";
983983- } {
984984- boot.loader.grub.device = "";
985985- }
15611561+ `rhs`
9861562987987- returns: {
988988- boot.loader.grub.enable = true;
989989- boot.loader.grub.device = "";
990990- }
15631563+ : Right attribute set of the merge.
9911564992992- Type:
993993- recursiveUpdate :: AttrSet -> AttrSet -> AttrSet
15651565+ # Type
15661566+15671567+ ```
15681568+ recursiveUpdate :: AttrSet -> AttrSet -> AttrSet
15691569+ ```
15701570+15711571+ # Examples
15721572+ :::{.example}
15731573+ ## `lib.attrsets.recursiveUpdate` usage example
15741574+15751575+ ```nix
15761576+ recursiveUpdate {
15771577+ boot.loader.grub.enable = true;
15781578+ boot.loader.grub.device = "/dev/hda";
15791579+ } {
15801580+ boot.loader.grub.device = "";
15811581+ }
15821582+15831583+ returns: {
15841584+ boot.loader.grub.enable = true;
15851585+ boot.loader.grub.device = "";
15861586+ }
15871587+ ```
15881588+15891589+ :::
9941590 */
9951591 recursiveUpdate =
996996- # Left attribute set of the merge.
9971592 lhs:
998998- # Right attribute set of the merge.
9991593 rhs:
10001594 recursiveUpdateUntil (path: lhs: rhs: !(isAttrs lhs && isAttrs rhs)) lhs rhs;
100115951002159610031003- /*
15971597+ /**
10041598 Recurse into every attribute set of the first argument and check that:
10051599 - Each attribute path also exists in the second argument.
10061600 - If the attribute's value is not a nested attribute set, it must have the same value in the right argument.
1007160110081008- Example:
10091009- matchAttrs { cpu = {}; } { cpu = { bits = 64; }; }
10101010- => true
16021602+16031603+ # Inputs
16041604+16051605+ `pattern`
16061606+16071607+ : Attribute set structure to match
16081608+16091609+ `attrs`
16101610+16111611+ : Attribute set to check
1011161210121012- Type:
10131013- matchAttrs :: AttrSet -> AttrSet -> Bool
16131613+ # Type
16141614+16151615+ ```
16161616+ matchAttrs :: AttrSet -> AttrSet -> Bool
16171617+ ```
16181618+16191619+ # Examples
16201620+ :::{.example}
16211621+ ## `lib.attrsets.matchAttrs` usage example
16221622+16231623+ ```nix
16241624+ matchAttrs { cpu = {}; } { cpu = { bits = 64; }; }
16251625+ => true
16261626+ ```
16271627+16281628+ :::
10141629 */
10151630 matchAttrs =
10161016- # Attribute set structure to match
10171631 pattern:
10181018- # Attribute set to check
10191632 attrs:
10201633 assert isAttrs pattern;
10211634 all
···10341647 )
10351648 (attrNames pattern);
1036164910371037- /* Override only the attributes that are already present in the old set
16501650+ /**
16511651+ Override only the attributes that are already present in the old set
10381652 useful for deep-overriding.
1039165310401040- Example:
10411041- overrideExisting {} { a = 1; }
10421042- => {}
10431043- overrideExisting { b = 2; } { a = 1; }
10441044- => { b = 2; }
10451045- overrideExisting { a = 3; b = 2; } { a = 1; }
10461046- => { a = 1; b = 2; }
16541654+16551655+ # Inputs
16561656+16571657+ `old`
16581658+16591659+ : Original attribute set
16601660+16611661+ `new`
16621662+16631663+ : Attribute set with attributes to override in `old`.
16641664+16651665+ # Type
16661666+16671667+ ```
16681668+ overrideExisting :: AttrSet -> AttrSet -> AttrSet
16691669+ ```
16701670+16711671+ # Examples
16721672+ :::{.example}
16731673+ ## `lib.attrsets.overrideExisting` usage example
16741674+16751675+ ```nix
16761676+ overrideExisting {} { a = 1; }
16771677+ => {}
16781678+ overrideExisting { b = 2; } { a = 1; }
16791679+ => { b = 2; }
16801680+ overrideExisting { a = 3; b = 2; } { a = 1; }
16811681+ => { a = 1; b = 2; }
16821682+ ```
1047168310481048- Type:
10491049- overrideExisting :: AttrSet -> AttrSet -> AttrSet
16841684+ :::
10501685 */
10511686 overrideExisting =
10521052- # Original attribute set
10531687 old:
10541054- # Attribute set with attributes to override in `old`.
10551688 new:
10561689 mapAttrs (name: value: new.${name} or value) old;
105716901058169110591059- /* Turns a list of strings into a human-readable description of those
16921692+ /**
16931693+ Turns a list of strings into a human-readable description of those
10601694 strings represented as an attribute path. The result of this function is
10611695 not intended to be machine-readable.
10621696 Create a new attribute set with `value` set at the nested attribute location specified in `attrPath`.
1063169710641064- Example:
10651065- showAttrPath [ "foo" "10" "bar" ]
10661066- => "foo.\"10\".bar"
10671067- showAttrPath []
10681068- => "<root attribute path>"
1069169810701070- Type:
10711071- showAttrPath :: [String] -> String
16991699+ # Inputs
17001700+17011701+ `path`
17021702+17031703+ : Attribute path to render to a string
17041704+17051705+ # Type
17061706+17071707+ ```
17081708+ showAttrPath :: [String] -> String
17091709+ ```
17101710+17111711+ # Examples
17121712+ :::{.example}
17131713+ ## `lib.attrsets.showAttrPath` usage example
17141714+17151715+ ```nix
17161716+ showAttrPath [ "foo" "10" "bar" ]
17171717+ => "foo.\"10\".bar"
17181718+ showAttrPath []
17191719+ => "<root attribute path>"
17201720+ ```
17211721+17221722+ :::
10721723 */
10731724 showAttrPath =
10741074- # Attribute path to render to a string
10751725 path:
10761726 if path == [] then "<root attribute path>"
10771727 else concatMapStringsSep "." escapeNixIdentifier path;
107817281079172910801080- /* Get a package output.
10811081- If no output is found, fallback to `.out` and then to the default.
17301730+ /**
17311731+ Get a package output.
17321732+ If no output is found, fallback to `.out` and then to the default.
17331733+17341734+17351735+ # Inputs
17361736+17371737+ `output`
17381738+17391739+ : 1\. Function argument
1082174010831083- Example:
10841084- getOutput "dev" pkgs.openssl
10851085- => "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-dev"
17411741+ `pkg`
1086174210871087- Type:
10881088- getOutput :: String -> Derivation -> String
17431743+ : 2\. Function argument
17441744+17451745+ # Type
17461746+17471747+ ```
17481748+ getOutput :: String -> Derivation -> String
17491749+ ```
17501750+17511751+ # Examples
17521752+ :::{.example}
17531753+ ## `lib.attrsets.getOutput` usage example
17541754+17551755+ ```nix
17561756+ getOutput "dev" pkgs.openssl
17571757+ => "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-dev"
17581758+ ```
17591759+17601760+ :::
10891761 */
10901762 getOutput = output: pkg:
10911763 if ! pkg ? outputSpecified || ! pkg.outputSpecified
10921764 then pkg.${output} or pkg.out or pkg
10931765 else pkg;
1094176610951095- /* Get a package's `bin` output.
10961096- If the output does not exist, fallback to `.out` and then to the default.
17671767+ /**
17681768+ Get a package's `bin` output.
17691769+ If the output does not exist, fallback to `.out` and then to the default.
17701770+17711771+ # Inputs
17721772+17731773+ `pkg`
17741774+17751775+ : The package whose `bin` output will be retrieved.
17761776+17771777+ # Type
17781778+17791779+ ```
17801780+ getBin :: Derivation -> String
17811781+ ```
1097178210981098- Example:
10991099- getBin pkgs.openssl
11001100- => "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r"
17831783+ # Examples
17841784+ :::{.example}
17851785+ ## `lib.attrsets.getBin` usage example
1101178611021102- Type:
11031103- getBin :: Derivation -> String
17871787+ ```nix
17881788+ getBin pkgs.openssl
17891789+ => "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r"
17901790+ ```
17911791+17921792+ :::
11041793 */
11051794 getBin = getOutput "bin";
110617951107179611081108- /* Get a package's `lib` output.
11091109- If the output does not exist, fallback to `.out` and then to the default.
17971797+ /**
17981798+ Get a package's `lib` output.
17991799+ If the output does not exist, fallback to `.out` and then to the default.
1110180011111111- Example:
11121112- getLib pkgs.openssl
11131113- => "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-lib"
18011801+ # Inputs
18021802+18031803+ `pkg`
1114180411151115- Type:
11161116- getLib :: Derivation -> String
18051805+ : The package whose `lib` output will be retrieved.
18061806+18071807+ # Type
18081808+18091809+ ```
18101810+ getLib :: Derivation -> String
18111811+ ```
18121812+18131813+ # Examples
18141814+ :::{.example}
18151815+ ## `lib.attrsets.getLib` usage example
18161816+18171817+ ```nix
18181818+ getLib pkgs.openssl
18191819+ => "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-lib"
18201820+ ```
18211821+18221822+ :::
11171823 */
11181824 getLib = getOutput "lib";
111918251120182611211121- /* Get a package's `dev` output.
11221122- If the output does not exist, fallback to `.out` and then to the default.
18271827+ /**
18281828+ Get a package's `dev` output.
18291829+ If the output does not exist, fallback to `.out` and then to the default.
18301830+18311831+ # Inputs
18321832+18331833+ `pkg`
18341834+18351835+ : The package whose `dev` output will be retrieved.
18361836+18371837+ # Type
18381838+18391839+ ```
18401840+ getDev :: Derivation -> String
18411841+ ```
1123184211241124- Example:
11251125- getDev pkgs.openssl
11261126- => "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-dev"
18431843+ # Examples
18441844+ :::{.example}
18451845+ ## `lib.attrsets.getDev` usage example
18461846+18471847+ ```nix
18481848+ getDev pkgs.openssl
18491849+ => "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-dev"
18501850+ ```
1127185111281128- Type:
11291129- getDev :: Derivation -> String
18521852+ :::
11301853 */
11311854 getDev = getOutput "dev";
113218551133185611341134- /* Get a package's `man` output.
11351135- If the output does not exist, fallback to `.out` and then to the default.
18571857+ /**
18581858+ Get a package's `man` output.
18591859+ If the output does not exist, fallback to `.out` and then to the default.
1136186011371137- Example:
11381138- getMan pkgs.openssl
11391139- => "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-man"
18611861+ # Inputs
1140186211411141- Type:
11421142- getMan :: Derivation -> String
18631863+ `pkg`
18641864+18651865+ : The package whose `man` output will be retrieved.
18661866+18671867+ # Type
18681868+18691869+ ```
18701870+ getMan :: Derivation -> String
18711871+ ```
18721872+18731873+ # Examples
18741874+ :::{.example}
18751875+ ## `lib.attrsets.getMan` usage example
18761876+18771877+ ```nix
18781878+ getMan pkgs.openssl
18791879+ => "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-man"
18801880+ ```
18811881+18821882+ :::
11431883 */
11441884 getMan = getOutput "man";
1145188511461146- /* Pick the outputs of packages to place in `buildInputs`
18861886+ /**
18871887+ Pick the outputs of packages to place in `buildInputs`
18881888+18891889+ # Inputs
18901890+18911891+ `pkgs`
18921892+18931893+ : List of packages.
1147189411481148- Type: chooseDevOutputs :: [Derivation] -> [String]
18951895+ # Type
1149189618971897+ ```
18981898+ chooseDevOutputs :: [Derivation] -> [String]
18991899+ ```
11501900 */
11511901 chooseDevOutputs = builtins.map getDev;
1152190211531153- /* Make various Nix tools consider the contents of the resulting
11541154- attribute set when looking for what to build, find, etc.
19031903+ /**
19041904+ Make various Nix tools consider the contents of the resulting
19051905+ attribute set when looking for what to build, find, etc.
19061906+19071907+ This function only affects a single attribute set; it does not
19081908+ apply itself recursively for nested attribute sets.
19091909+1155191011561156- This function only affects a single attribute set; it does not
11571157- apply itself recursively for nested attribute sets.
19111911+ # Inputs
1158191211591159- Example:
11601160- { pkgs ? import <nixpkgs> {} }:
11611161- {
11621162- myTools = pkgs.lib.recurseIntoAttrs {
11631163- inherit (pkgs) hello figlet;
11641164- };
11651165- }
19131913+ `attrs`
1166191411671167- Type:
11681168- recurseIntoAttrs :: AttrSet -> AttrSet
19151915+ : An attribute set to scan for derivations.
19161916+19171917+ # Type
1169191811701170- */
19191919+ ```
19201920+ recurseIntoAttrs :: AttrSet -> AttrSet
19211921+ ```
19221922+19231923+ # Examples
19241924+ :::{.example}
19251925+ ## `lib.attrsets.recurseIntoAttrs` usage example
19261926+19271927+ ```nix
19281928+ { pkgs ? import <nixpkgs> {} }:
19291929+ {
19301930+ myTools = pkgs.lib.recurseIntoAttrs {
19311931+ inherit (pkgs) hello figlet;
19321932+ };
19331933+ }
19341934+ ```
19351935+19361936+ :::
19371937+ */
11711938 recurseIntoAttrs =
11721172- # An attribute set to scan for derivations.
11731939 attrs:
11741940 attrs // { recurseForDerivations = true; };
1175194111761176- /* Undo the effect of recurseIntoAttrs.
19421942+ /**
19431943+ Undo the effect of recurseIntoAttrs.
19441944+19451945+19461946+ # Inputs
19471947+19481948+ `attrs`
1177194911781178- Type:
11791179- dontRecurseIntoAttrs :: AttrSet -> AttrSet
11801180- */
19501950+ : An attribute set to not scan for derivations.
19511951+19521952+ # Type
19531953+19541954+ ```
19551955+ dontRecurseIntoAttrs :: AttrSet -> AttrSet
19561956+ ```
19571957+ */
11811958 dontRecurseIntoAttrs =
11821182- # An attribute set to not scan for derivations.
11831959 attrs:
11841960 attrs // { recurseForDerivations = false; };
1185196111861186- /* `unionOfDisjoint x y` is equal to `x // y // z` where the
11871187- attrnames in `z` are the intersection of the attrnames in `x` and
11881188- `y`, and all values `assert` with an error message. This
11891189- operator is commutative, unlike (//).
19621962+ /**
19631963+ `unionOfDisjoint x y` is equal to `x // y // z` where the
19641964+ attrnames in `z` are the intersection of the attrnames in `x` and
19651965+ `y`, and all values `assert` with an error message. This
19661966+ operator is commutative, unlike (//).
1190196711911191- Type: unionOfDisjoint :: AttrSet -> AttrSet -> AttrSet
19681968+19691969+ # Inputs
19701970+19711971+ `x`
19721972+19731973+ : 1\. Function argument
19741974+19751975+ `y`
19761976+19771977+ : 2\. Function argument
19781978+19791979+ # Type
19801980+19811981+ ```
19821982+ unionOfDisjoint :: AttrSet -> AttrSet -> AttrSet
19831983+ ```
11921984 */
11931985 unionOfDisjoint = x: y:
11941986 let