lol

Merge pull request #296186 from hsjobeki/doc/attrsets

doc: migrate lib.attrsets to use doc-comments

authored by

Daniel Sidhion and committed by
GitHub
a737a781 4f1e887e

+1308 -516
+1308 -516
lib/attrsets.nix
··· 1 - /* Operations on attribute sets. */ 1 + /** 2 + Operations on attribute sets. 3 + */ 2 4 { lib }: 3 5 4 6 let ··· 12 14 inherit (builtins) attrNames listToAttrs hasAttr isAttrs getAttr removeAttrs; 13 15 14 16 15 - /* Return an attribute from nested attribute sets. 17 + /** 18 + Return an attribute from nested attribute sets. 19 + 20 + 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: 21 + 22 + ```nix 23 + (x.a.b or 6) == attrByPath ["a" "b"] 6 x 24 + # and 25 + (x.${f p}."example.com" or 6) == attrByPath [ (f p) "example.com" ] 6 x 26 + ``` 27 + 28 + 29 + # Inputs 30 + 31 + `attrPath` 32 + 33 + : A list of strings representing the attribute path to return from `set` 16 34 17 - 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: 35 + `default` 36 + 37 + : Default value if `attrPath` does not resolve to an existing value 38 + 39 + `set` 40 + 41 + : The nested attribute set to select values from 18 42 19 - ```nix 20 - (x.a.b or 6) == attrByPath ["a" "b"] 6 x 21 - # and 22 - (x.${f p}."example.com" or 6) == attrByPath [ (f p) "example.com" ] 6 x 23 - ``` 43 + # Type 24 44 25 - Example: 26 - x = { a = { b = 3; }; } 27 - # ["a" "b"] is equivalent to x.a.b 28 - # 6 is a default value to return if the path does not exist in attrset 29 - attrByPath ["a" "b"] 6 x 30 - => 3 31 - attrByPath ["z" "z"] 6 x 32 - => 6 45 + ``` 46 + attrByPath :: [String] -> Any -> AttrSet -> Any 47 + ``` 33 48 34 - Type: 35 - attrByPath :: [String] -> Any -> AttrSet -> Any 49 + # Examples 50 + :::{.example} 51 + ## `lib.attrsets.attrByPath` usage example 36 52 53 + ```nix 54 + x = { a = { b = 3; }; } 55 + # ["a" "b"] is equivalent to x.a.b 56 + # 6 is a default value to return if the path does not exist in attrset 57 + attrByPath ["a" "b"] 6 x 58 + => 3 59 + attrByPath ["z" "z"] 6 x 60 + => 6 61 + ``` 62 + 63 + ::: 37 64 */ 38 65 attrByPath = 39 - # A list of strings representing the attribute path to return from `set` 40 66 attrPath: 41 - # Default value if `attrPath` does not resolve to an existing value 42 67 default: 43 - # The nested attribute set to select values from 44 68 set: 45 69 let 46 70 lenAttrPath = length attrPath; ··· 57 81 in 58 82 attrByPath' 0 set; 59 83 60 - /* Return if an attribute from nested attribute set exists. 84 + /** 85 + Return if an attribute from nested attribute set exists. 86 + 87 + 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: 88 + 89 + ```nix 90 + (x?a.b) == hasAttryByPath ["a" "b"] x 91 + # and 92 + (x?${f p}."example.com") == hasAttryByPath [ (f p) "example.com" ] x 93 + ``` 94 + 95 + **Laws**: 96 + 1. ```nix 97 + hasAttrByPath [] x == true 98 + ``` 99 + 100 + 101 + # Inputs 102 + 103 + `attrPath` 61 104 62 - 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: 105 + : A list of strings representing the attribute path to check from `set` 63 106 64 - ```nix 65 - (x?a.b) == hasAttryByPath ["a" "b"] x 66 - # and 67 - (x?${f p}."example.com") == hasAttryByPath [ (f p) "example.com" ] x 68 - ``` 107 + `e` 69 108 70 - **Laws**: 71 - 1. ```nix 72 - hasAttrByPath [] x == true 73 - ``` 109 + : The nested attribute set to check 74 110 75 - Example: 76 - x = { a = { b = 3; }; } 77 - hasAttrByPath ["a" "b"] x 78 - => true 79 - hasAttrByPath ["z" "z"] x 80 - => false 81 - hasAttrByPath [] (throw "no need") 82 - => true 111 + # Type 83 112 84 - Type: 85 - hasAttrByPath :: [String] -> AttrSet -> Bool 113 + ``` 114 + hasAttrByPath :: [String] -> AttrSet -> Bool 115 + ``` 116 + 117 + # Examples 118 + :::{.example} 119 + ## `lib.attrsets.hasAttrByPath` usage example 120 + 121 + ```nix 122 + x = { a = { b = 3; }; } 123 + hasAttrByPath ["a" "b"] x 124 + => true 125 + hasAttrByPath ["z" "z"] x 126 + => false 127 + hasAttrByPath [] (throw "no need") 128 + => true 129 + ``` 130 + 131 + ::: 86 132 */ 87 133 hasAttrByPath = 88 - # A list of strings representing the attribute path to check from `set` 89 134 attrPath: 90 - # The nested attribute set to check 91 135 e: 92 136 let 93 137 lenAttrPath = length attrPath; ··· 103 147 in 104 148 hasAttrByPath' 0 e; 105 149 106 - /* 150 + /** 107 151 Return the longest prefix of an attribute path that refers to an existing attribute in a nesting of attribute sets. 108 152 109 153 Can be used after [`mapAttrsRecursiveCond`](#function-library-lib.attrsets.mapAttrsRecursiveCond) to apply a condition, ··· 120 164 hasAttrByPath (attrsets.longestValidPathPrefix p x) x == true 121 165 ``` 122 166 123 - Example: 124 - x = { a = { b = 3; }; } 125 - attrsets.longestValidPathPrefix ["a" "b" "c"] x 126 - => ["a" "b"] 127 - attrsets.longestValidPathPrefix ["a"] x 128 - => ["a"] 129 - attrsets.longestValidPathPrefix ["z" "z"] x 130 - => [] 131 - attrsets.longestValidPathPrefix ["z" "z"] (throw "no need") 132 - => [] 167 + 168 + # Inputs 169 + 170 + `attrPath` 171 + 172 + : A list of strings representing the longest possible path that may be returned. 173 + 174 + `v` 175 + 176 + : The nested attribute set to check. 133 177 134 - Type: 135 - attrsets.longestValidPathPrefix :: [String] -> Value -> [String] 178 + # Type 179 + 180 + ``` 181 + attrsets.longestValidPathPrefix :: [String] -> Value -> [String] 182 + ``` 183 + 184 + # Examples 185 + :::{.example} 186 + ## `lib.attrsets.longestValidPathPrefix` usage example 187 + 188 + ```nix 189 + x = { a = { b = 3; }; } 190 + attrsets.longestValidPathPrefix ["a" "b" "c"] x 191 + => ["a" "b"] 192 + attrsets.longestValidPathPrefix ["a"] x 193 + => ["a"] 194 + attrsets.longestValidPathPrefix ["z" "z"] x 195 + => [] 196 + attrsets.longestValidPathPrefix ["z" "z"] (throw "no need") 197 + => [] 198 + ``` 199 + 200 + ::: 136 201 */ 137 202 longestValidPathPrefix = 138 - # A list of strings representing the longest possible path that may be returned. 139 203 attrPath: 140 - # The nested attribute set to check. 141 204 v: 142 205 let 143 206 lenAttrPath = length attrPath; ··· 168 231 in 169 232 getPrefixForSetAtIndex v 0; 170 233 171 - /* Create a new attribute set with `value` set at the nested attribute location specified in `attrPath`. 234 + /** 235 + Create a new attribute set with `value` set at the nested attribute location specified in `attrPath`. 236 + 237 + 238 + # Inputs 239 + 240 + `attrPath` 241 + 242 + : A list of strings representing the attribute path to set 243 + 244 + `value` 245 + 246 + : The value to set at the location described by `attrPath` 247 + 248 + # Type 249 + 250 + ``` 251 + setAttrByPath :: [String] -> Any -> AttrSet 252 + ``` 172 253 173 - Example: 174 - setAttrByPath ["a" "b"] 3 175 - => { a = { b = 3; }; } 254 + # Examples 255 + :::{.example} 256 + ## `lib.attrsets.setAttrByPath` usage example 176 257 177 - Type: 178 - setAttrByPath :: [String] -> Any -> AttrSet 258 + ```nix 259 + setAttrByPath ["a" "b"] 3 260 + => { a = { b = 3; }; } 261 + ``` 262 + 263 + ::: 179 264 */ 180 265 setAttrByPath = 181 - # A list of strings representing the attribute path to set 182 266 attrPath: 183 - # The value to set at the location described by `attrPath` 184 267 value: 185 268 let 186 269 len = length attrPath; ··· 190 273 else { ${elemAt attrPath n} = atDepth (n + 1); }; 191 274 in atDepth 0; 192 275 193 - /* Like `attrByPath`, but without a default value. If it doesn't find the 194 - path it will throw an error. 276 + /** 277 + Like `attrByPath`, but without a default value. If it doesn't find the 278 + path it will throw an error. 195 279 196 - 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: 280 + 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: 197 281 198 282 ```nix 199 - x.a.b == getAttrByPath ["a" "b"] x 200 - # and 201 - x.${f p}."example.com" == getAttrByPath [ (f p) "example.com" ] x 202 - ``` 283 + x.a.b == getAttrByPath ["a" "b"] x 284 + # and 285 + x.${f p}."example.com" == getAttrByPath [ (f p) "example.com" ] x 286 + ``` 203 287 204 - Example: 205 - x = { a = { b = 3; }; } 206 - getAttrFromPath ["a" "b"] x 207 - => 3 208 - getAttrFromPath ["z" "z"] x 209 - => error: cannot find attribute `z.z' 288 + 289 + # Inputs 290 + 291 + `attrPath` 292 + 293 + : A list of strings representing the attribute path to get from `set` 294 + 295 + `set` 296 + 297 + : The nested attribute set to find the value in. 298 + 299 + # Type 300 + 301 + ``` 302 + getAttrFromPath :: [String] -> AttrSet -> Any 303 + ``` 304 + 305 + # Examples 306 + :::{.example} 307 + ## `lib.attrsets.getAttrFromPath` usage example 308 + 309 + ```nix 310 + x = { a = { b = 3; }; } 311 + getAttrFromPath ["a" "b"] x 312 + => 3 313 + getAttrFromPath ["z" "z"] x 314 + => error: cannot find attribute `z.z' 315 + ``` 210 316 211 - Type: 212 - getAttrFromPath :: [String] -> AttrSet -> Any 317 + ::: 213 318 */ 214 319 getAttrFromPath = 215 - # A list of strings representing the attribute path to get from `set` 216 320 attrPath: 217 - # The nested attribute set to find the value in. 218 321 set: 219 322 attrByPath attrPath (abort ("cannot find attribute `" + concatStringsSep "." attrPath + "'")) set; 220 323 221 - /* Map each attribute in the given set and merge them into a new attribute set. 324 + /** 325 + Map each attribute in the given set and merge them into a new attribute set. 222 326 223 - Type: 224 - concatMapAttrs :: (String -> a -> AttrSet) -> AttrSet -> AttrSet 225 327 226 - Example: 227 - concatMapAttrs 228 - (name: value: { 229 - ${name} = value; 230 - ${name + value} = value; 231 - }) 232 - { x = "a"; y = "b"; } 233 - => { x = "a"; xa = "a"; y = "b"; yb = "b"; } 328 + # Inputs 329 + 330 + `f` 331 + 332 + : 1\. Function argument 333 + 334 + `v` 335 + 336 + : 2\. Function argument 337 + 338 + # Type 339 + 340 + ``` 341 + concatMapAttrs :: (String -> a -> AttrSet) -> AttrSet -> AttrSet 342 + ``` 343 + 344 + # Examples 345 + :::{.example} 346 + ## `lib.attrsets.concatMapAttrs` usage example 347 + 348 + ```nix 349 + concatMapAttrs 350 + (name: value: { 351 + ${name} = value; 352 + ${name + value} = value; 353 + }) 354 + { x = "a"; y = "b"; } 355 + => { x = "a"; xa = "a"; y = "b"; yb = "b"; } 356 + ``` 357 + 358 + ::: 234 359 */ 235 360 concatMapAttrs = f: v: 236 361 foldl' mergeAttrs { } ··· 239 364 ); 240 365 241 366 242 - /* Update or set specific paths of an attribute set. 367 + /** 368 + Update or set specific paths of an attribute set. 243 369 244 - Takes a list of updates to apply and an attribute set to apply them to, 245 - and returns the attribute set with the updates applied. Updates are 246 - represented as `{ path = ...; update = ...; }` values, where `path` is a 247 - list of strings representing the attribute path that should be updated, 248 - and `update` is a function that takes the old value at that attribute path 249 - as an argument and returns the new 250 - value it should be. 370 + Takes a list of updates to apply and an attribute set to apply them to, 371 + and returns the attribute set with the updates applied. Updates are 372 + represented as `{ path = ...; update = ...; }` values, where `path` is a 373 + list of strings representing the attribute path that should be updated, 374 + and `update` is a function that takes the old value at that attribute path 375 + as an argument and returns the new 376 + value it should be. 251 377 252 - Properties: 378 + Properties: 253 379 254 - - Updates to deeper attribute paths are applied before updates to more 255 - shallow attribute paths 380 + - Updates to deeper attribute paths are applied before updates to more 381 + shallow attribute paths 256 382 257 - - Multiple updates to the same attribute path are applied in the order 258 - they appear in the update list 383 + - Multiple updates to the same attribute path are applied in the order 384 + they appear in the update list 259 385 260 - - If any but the last `path` element leads into a value that is not an 261 - attribute set, an error is thrown 386 + - If any but the last `path` element leads into a value that is not an 387 + attribute set, an error is thrown 262 388 263 - - If there is an update for an attribute path that doesn't exist, 264 - accessing the argument in the update function causes an error, but 265 - intermediate attribute sets are implicitly created as needed 389 + - If there is an update for an attribute path that doesn't exist, 390 + accessing the argument in the update function causes an error, but 391 + intermediate attribute sets are implicitly created as needed 266 392 267 - Example: 268 - updateManyAttrsByPath [ 269 - { 270 - path = [ "a" "b" ]; 271 - update = old: { d = old.c; }; 272 - } 273 - { 274 - path = [ "a" "b" "c" ]; 275 - update = old: old + 1; 276 - } 277 - { 278 - path = [ "x" "y" ]; 279 - update = old: "xy"; 280 - } 281 - ] { a.b.c = 0; } 282 - => { a = { b = { d = 1; }; }; x = { y = "xy"; }; } 393 + # Type 394 + 395 + ``` 396 + updateManyAttrsByPath :: [{ path :: [String]; update :: (Any -> Any); }] -> AttrSet -> AttrSet 397 + ``` 398 + 399 + # Examples 400 + :::{.example} 401 + ## `lib.attrsets.updateManyAttrsByPath` usage example 402 + 403 + ```nix 404 + updateManyAttrsByPath [ 405 + { 406 + path = [ "a" "b" ]; 407 + update = old: { d = old.c; }; 408 + } 409 + { 410 + path = [ "a" "b" "c" ]; 411 + update = old: old + 1; 412 + } 413 + { 414 + path = [ "x" "y" ]; 415 + update = old: "xy"; 416 + } 417 + ] { a.b.c = 0; } 418 + => { a = { b = { d = 1; }; }; x = { y = "xy"; }; } 419 + ``` 283 420 284 - Type: updateManyAttrsByPath :: [{ path :: [String]; update :: (Any -> Any); }] -> AttrSet -> AttrSet 421 + ::: 285 422 */ 286 423 updateManyAttrsByPath = let 287 424 # When recursing into attributes, instead of updating the `path` of each ··· 342 479 343 480 in updates: value: go 0 true value updates; 344 481 345 - /* Return the specified attributes from a set. 482 + /** 483 + Return the specified attributes from a set. 346 484 347 - Example: 348 - attrVals ["a" "b" "c"] as 349 - => [as.a as.b as.c] 485 + 486 + # Inputs 487 + 488 + `nameList` 489 + 490 + : The list of attributes to fetch from `set`. Each attribute name must exist on the attrbitue set 491 + 492 + `set` 493 + 494 + : The set to get attribute values from 495 + 496 + # Type 497 + 498 + ``` 499 + attrVals :: [String] -> AttrSet -> [Any] 500 + ``` 501 + 502 + # Examples 503 + :::{.example} 504 + ## `lib.attrsets.attrVals` usage example 505 + 506 + ```nix 507 + attrVals ["a" "b" "c"] as 508 + => [as.a as.b as.c] 509 + ``` 350 510 351 - Type: 352 - attrVals :: [String] -> AttrSet -> [Any] 511 + ::: 353 512 */ 354 513 attrVals = 355 - # The list of attributes to fetch from `set`. Each attribute name must exist on the attrbitue set 356 514 nameList: 357 - # The set to get attribute values from 358 515 set: map (x: set.${x}) nameList; 359 516 360 517 361 - /* Return the values of all attributes in the given set, sorted by 362 - attribute name. 518 + /** 519 + Return the values of all attributes in the given set, sorted by 520 + attribute name. 363 521 364 - Example: 365 - attrValues {c = 3; a = 1; b = 2;} 366 - => [1 2 3] 522 + # Type 367 523 368 - Type: 369 - attrValues :: AttrSet -> [Any] 524 + ``` 525 + attrValues :: AttrSet -> [Any] 526 + ``` 527 + 528 + # Examples 529 + :::{.example} 530 + ## `lib.attrsets.attrValues` usage example 531 + 532 + ```nix 533 + attrValues {c = 3; a = 1; b = 2;} 534 + => [1 2 3] 535 + ``` 536 + 537 + ::: 370 538 */ 371 539 attrValues = builtins.attrValues; 372 540 373 541 374 - /* Given a set of attribute names, return the set of the corresponding 375 - attributes from the given set. 542 + /** 543 + Given a set of attribute names, return the set of the corresponding 544 + attributes from the given set. 545 + 546 + 547 + # Inputs 548 + 549 + `names` 550 + 551 + : A list of attribute names to get out of `set` 552 + 553 + `attrs` 554 + 555 + : The set to get the named attributes from 556 + 557 + # Type 376 558 377 - Example: 378 - getAttrs [ "a" "b" ] { a = 1; b = 2; c = 3; } 379 - => { a = 1; b = 2; } 559 + ``` 560 + getAttrs :: [String] -> AttrSet -> AttrSet 561 + ``` 562 + 563 + # Examples 564 + :::{.example} 565 + ## `lib.attrsets.getAttrs` usage example 566 + 567 + ```nix 568 + getAttrs [ "a" "b" ] { a = 1; b = 2; c = 3; } 569 + => { a = 1; b = 2; } 570 + ``` 380 571 381 - Type: 382 - getAttrs :: [String] -> AttrSet -> AttrSet 572 + ::: 383 573 */ 384 574 getAttrs = 385 - # A list of attribute names to get out of `set` 386 575 names: 387 - # The set to get the named attributes from 388 576 attrs: genAttrs names (name: attrs.${name}); 389 577 390 - /* Collect each attribute named `attr` from a list of attribute 391 - sets. Sets that don't contain the named attribute are ignored. 578 + /** 579 + Collect each attribute named `attr` from a list of attribute 580 + sets. Sets that don't contain the named attribute are ignored. 392 581 393 - Example: 394 - catAttrs "a" [{a = 1;} {b = 0;} {a = 2;}] 395 - => [1 2] 582 + # Inputs 396 583 397 - Type: 398 - catAttrs :: String -> [AttrSet] -> [Any] 584 + `attr` 585 + 586 + : The attribute name to get out of the sets. 587 + 588 + `list` 589 + 590 + : The list of attribute sets to go through 591 + 592 + # Type 593 + 594 + ``` 595 + catAttrs :: String -> [AttrSet] -> [Any] 596 + ``` 597 + 598 + # Examples 599 + :::{.example} 600 + ## `lib.attrsets.catAttrs` usage example 601 + 602 + ```nix 603 + catAttrs "a" [{a = 1;} {b = 0;} {a = 2;}] 604 + => [1 2] 605 + ``` 606 + 607 + ::: 399 608 */ 400 609 catAttrs = builtins.catAttrs; 401 610 402 611 403 - /* Filter an attribute set by removing all attributes for which the 404 - given predicate return false. 612 + /** 613 + Filter an attribute set by removing all attributes for which the 614 + given predicate return false. 615 + 616 + 617 + # Inputs 618 + 619 + `pred` 620 + 621 + : Predicate taking an attribute name and an attribute value, which returns `true` to include the attribute, or `false` to exclude the attribute. 622 + 623 + `set` 405 624 406 - Example: 407 - filterAttrs (n: v: n == "foo") { foo = 1; bar = 2; } 408 - => { foo = 1; } 625 + : The attribute set to filter 409 626 410 - Type: 411 - filterAttrs :: (String -> Any -> Bool) -> AttrSet -> AttrSet 627 + # Type 628 + 629 + ``` 630 + filterAttrs :: (String -> Any -> Bool) -> AttrSet -> AttrSet 631 + ``` 632 + 633 + # Examples 634 + :::{.example} 635 + ## `lib.attrsets.filterAttrs` usage example 636 + 637 + ```nix 638 + filterAttrs (n: v: n == "foo") { foo = 1; bar = 2; } 639 + => { foo = 1; } 640 + ``` 641 + 642 + ::: 412 643 */ 413 644 filterAttrs = 414 - # Predicate taking an attribute name and an attribute value, which returns `true` to include the attribute, or `false` to exclude the attribute. 415 645 pred: 416 - # The attribute set to filter 417 646 set: 418 647 listToAttrs (concatMap (name: let v = set.${name}; in if pred name v then [(nameValuePair name v)] else []) (attrNames set)); 419 648 420 649 421 - /* Filter an attribute set recursively by removing all attributes for 422 - which the given predicate return false. 650 + /** 651 + Filter an attribute set recursively by removing all attributes for 652 + which the given predicate return false. 653 + 654 + 655 + # Inputs 656 + 657 + `pred` 658 + 659 + : Predicate taking an attribute name and an attribute value, which returns `true` to include the attribute, or `false` to exclude the attribute. 660 + 661 + `set` 662 + 663 + : The attribute set to filter 664 + 665 + # Type 666 + 667 + ``` 668 + filterAttrsRecursive :: (String -> Any -> Bool) -> AttrSet -> AttrSet 669 + ``` 423 670 424 - Example: 425 - filterAttrsRecursive (n: v: v != null) { foo = { bar = null; }; } 426 - => { foo = {}; } 671 + # Examples 672 + :::{.example} 673 + ## `lib.attrsets.filterAttrsRecursive` usage example 674 + 675 + ```nix 676 + filterAttrsRecursive (n: v: v != null) { foo = { bar = null; }; } 677 + => { foo = {}; } 678 + ``` 427 679 428 - Type: 429 - filterAttrsRecursive :: (String -> Any -> Bool) -> AttrSet -> AttrSet 680 + ::: 430 681 */ 431 682 filterAttrsRecursive = 432 - # Predicate taking an attribute name and an attribute value, which returns `true` to include the attribute, or `false` to exclude the attribute. 433 683 pred: 434 - # The attribute set to filter 435 684 set: 436 685 listToAttrs ( 437 686 concatMap (name: ··· 445 694 ) (attrNames set) 446 695 ); 447 696 448 - /* 697 + /** 449 698 Like [`lib.lists.foldl'`](#function-library-lib.lists.foldl-prime) but for attribute sets. 450 699 Iterates over every name-value pair in the given attribute set. 451 700 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`. 452 701 453 702 Attention: 454 - There is a completely different function 455 - `lib.foldAttrs` 456 - which has nothing to do with this function, despite the similar name. 457 703 458 - Example: 459 - foldlAttrs 460 - (acc: name: value: { 461 - sum = acc.sum + value; 462 - names = acc.names ++ [name]; 463 - }) 464 - { sum = 0; names = []; } 465 - { 466 - foo = 1; 467 - bar = 10; 468 - } 469 - -> 470 - { 471 - sum = 11; 472 - names = ["bar" "foo"]; 473 - } 704 + There is a completely different function `lib.foldAttrs` 705 + which has nothing to do with this function, despite the similar name. 706 + 707 + 708 + # Inputs 709 + 710 + `f` 711 + 712 + : 1\. Function argument 713 + 714 + `init` 715 + 716 + : 2\. Function argument 717 + 718 + `set` 474 719 475 - foldlAttrs 476 - (throw "function not needed") 477 - 123 478 - {}; 479 - -> 480 - 123 720 + : 3\. Function argument 481 721 482 - foldlAttrs 483 - (acc: _: _: acc) 484 - 3 485 - { z = throw "value not needed"; a = throw "value not needed"; }; 486 - -> 487 - 3 722 + # Type 488 723 489 - The accumulator doesn't have to be an attrset. 490 - It can be as simple as a number or string. 724 + ``` 725 + foldlAttrs :: ( a -> String -> b -> a ) -> a -> { ... :: b } -> a 726 + ``` 491 727 492 - foldlAttrs 493 - (acc: _: v: acc * 10 + v) 494 - 1 495 - { z = 1; a = 2; }; 496 - -> 497 - 121 728 + # Examples 729 + :::{.example} 730 + ## `lib.attrsets.foldlAttrs` usage example 498 731 499 - Type: 500 - foldlAttrs :: ( a -> String -> b -> a ) -> a -> { ... :: b } -> a 732 + ```nix 733 + foldlAttrs 734 + (acc: name: value: { 735 + sum = acc.sum + value; 736 + names = acc.names ++ [name]; 737 + }) 738 + { sum = 0; names = []; } 739 + { 740 + foo = 1; 741 + bar = 10; 742 + } 743 + -> 744 + { 745 + sum = 11; 746 + names = ["bar" "foo"]; 747 + } 748 + 749 + foldlAttrs 750 + (throw "function not needed") 751 + 123 752 + {}; 753 + -> 754 + 123 755 + 756 + foldlAttrs 757 + (acc: _: _: acc) 758 + 3 759 + { z = throw "value not needed"; a = throw "value not needed"; }; 760 + -> 761 + 3 762 + 763 + The accumulator doesn't have to be an attrset. 764 + It can be as simple as a number or string. 765 + 766 + foldlAttrs 767 + (acc: _: v: acc * 10 + v) 768 + 1 769 + { z = 1; a = 2; }; 770 + -> 771 + 121 772 + ``` 773 + 774 + ::: 501 775 */ 502 776 foldlAttrs = f: init: set: 503 777 foldl' ··· 505 779 init 506 780 (attrNames set); 507 781 508 - /* Apply fold functions to values grouped by key. 782 + /** 783 + Apply fold functions to values grouped by key. 509 784 510 - Example: 511 - foldAttrs (item: acc: [item] ++ acc) [] [{ a = 2; } { a = 3; }] 512 - => { a = [ 2 3 ]; } 785 + 786 + # Inputs 513 787 514 - Type: 515 - foldAttrs :: (Any -> Any -> Any) -> Any -> [AttrSets] -> Any 788 + `op` 516 789 790 + : A function, given a value and a collector combines the two. 791 + 792 + `nul` 793 + 794 + : The starting value. 795 + 796 + `list_of_attrs` 797 + 798 + : A list of attribute sets to fold together by key. 799 + 800 + # Type 801 + 802 + ``` 803 + foldAttrs :: (Any -> Any -> Any) -> Any -> [AttrSets] -> Any 804 + ``` 805 + 806 + # Examples 807 + :::{.example} 808 + ## `lib.attrsets.foldAttrs` usage example 809 + 810 + ```nix 811 + foldAttrs (item: acc: [item] ++ acc) [] [{ a = 2; } { a = 3; }] 812 + => { a = [ 2 3 ]; } 813 + ``` 814 + 815 + ::: 517 816 */ 518 817 foldAttrs = 519 - # A function, given a value and a collector combines the two. 520 818 op: 521 - # The starting value. 522 819 nul: 523 - # A list of attribute sets to fold together by key. 524 820 list_of_attrs: 525 821 foldr (n: a: 526 822 foldr (name: o: ··· 529 825 ) {} list_of_attrs; 530 826 531 827 532 - /* Recursively collect sets that verify a given predicate named `pred` 533 - from the set `attrs`. The recursion is stopped when the predicate is 534 - verified. 828 + /** 829 + Recursively collect sets that verify a given predicate named `pred` 830 + from the set `attrs`. The recursion is stopped when the predicate is 831 + verified. 832 + 833 + 834 + # Inputs 835 + 836 + `pred` 837 + 838 + : Given an attribute's value, determine if recursion should stop. 839 + 840 + `attrs` 841 + 842 + : The attribute set to recursively collect. 535 843 536 - Example: 537 - collect isList { a = { b = ["b"]; }; c = [1]; } 538 - => [["b"] [1]] 844 + # Type 539 845 540 - collect (x: x ? outPath) 541 - { a = { outPath = "a/"; }; b = { outPath = "b/"; }; } 542 - => [{ outPath = "a/"; } { outPath = "b/"; }] 846 + ``` 847 + collect :: (AttrSet -> Bool) -> AttrSet -> [x] 848 + ``` 543 849 544 - Type: 545 - collect :: (AttrSet -> Bool) -> AttrSet -> [x] 850 + # Examples 851 + :::{.example} 852 + ## `lib.attrsets.collect` usage example 853 + 854 + ```nix 855 + collect isList { a = { b = ["b"]; }; c = [1]; } 856 + => [["b"] [1]] 857 + 858 + collect (x: x ? outPath) 859 + { a = { outPath = "a/"; }; b = { outPath = "b/"; }; } 860 + => [{ outPath = "a/"; } { outPath = "b/"; }] 861 + ``` 862 + 863 + ::: 546 864 */ 547 865 collect = 548 - # Given an attribute's value, determine if recursion should stop. 549 - pred: 550 - # The attribute set to recursively collect. 551 - attrs: 866 + pred: 867 + attrs: 552 868 if pred attrs then 553 869 [ attrs ] 554 870 else if isAttrs attrs then ··· 556 872 else 557 873 []; 558 874 559 - /* Return the cartesian product of attribute set value combinations. 875 + /** 876 + Return the cartesian product of attribute set value combinations. 877 + 878 + 879 + # Inputs 880 + 881 + `attrsOfLists` 882 + 883 + : Attribute set with attributes that are lists of values 884 + 885 + # Type 886 + 887 + ``` 888 + cartesianProductOfSets :: AttrSet -> [AttrSet] 889 + ``` 890 + 891 + # Examples 892 + :::{.example} 893 + ## `lib.attrsets.cartesianProductOfSets` usage example 894 + 895 + ```nix 896 + cartesianProductOfSets { a = [ 1 2 ]; b = [ 10 20 ]; } 897 + => [ 898 + { a = 1; b = 10; } 899 + { a = 1; b = 20; } 900 + { a = 2; b = 10; } 901 + { a = 2; b = 20; } 902 + ] 903 + ``` 560 904 561 - Example: 562 - cartesianProductOfSets { a = [ 1 2 ]; b = [ 10 20 ]; } 563 - => [ 564 - { a = 1; b = 10; } 565 - { a = 1; b = 20; } 566 - { a = 2; b = 10; } 567 - { a = 2; b = 20; } 568 - ] 569 - Type: 570 - cartesianProductOfSets :: AttrSet -> [AttrSet] 905 + ::: 571 906 */ 572 907 cartesianProductOfSets = 573 - # Attribute set with attributes that are lists of values 574 908 attrsOfLists: 575 909 foldl' (listOfAttrs: attrName: 576 910 concatMap (attrs: ··· 579 913 ) [{}] (attrNames attrsOfLists); 580 914 581 915 582 - /* Utility function that creates a `{name, value}` pair as expected by `builtins.listToAttrs`. 916 + /** 917 + Utility function that creates a `{name, value}` pair as expected by `builtins.listToAttrs`. 583 918 584 - Example: 585 - nameValuePair "some" 6 586 - => { name = "some"; value = 6; } 587 919 588 - Type: 589 - nameValuePair :: String -> Any -> { name :: String; value :: Any; } 920 + # Inputs 921 + 922 + `name` 923 + 924 + : Attribute name 925 + 926 + `value` 927 + 928 + : Attribute value 929 + 930 + # Type 931 + 932 + ``` 933 + nameValuePair :: String -> Any -> { name :: String; value :: Any; } 934 + ``` 935 + 936 + # Examples 937 + :::{.example} 938 + ## `lib.attrsets.nameValuePair` usage example 939 + 940 + ```nix 941 + nameValuePair "some" 6 942 + => { name = "some"; value = 6; } 943 + ``` 944 + 945 + ::: 590 946 */ 591 947 nameValuePair = 592 - # Attribute name 593 948 name: 594 - # Attribute value 595 949 value: 596 950 { inherit name value; }; 597 951 598 952 599 - /* Apply a function to each element in an attribute set, creating a new attribute set. 953 + /** 954 + Apply a function to each element in an attribute set, creating a new attribute set. 600 955 601 - Example: 602 - mapAttrs (name: value: name + "-" + value) 603 - { x = "foo"; y = "bar"; } 604 - => { x = "x-foo"; y = "y-bar"; } 956 + # Inputs 605 957 606 - Type: 607 - mapAttrs :: (String -> Any -> Any) -> AttrSet -> AttrSet 958 + `f` 959 + 960 + : A function that takes an attribute name and its value, and returns the new value for the attribute. 961 + 962 + `attrset` 963 + 964 + : The attribute set to iterate through. 965 + 966 + # Type 967 + 968 + ``` 969 + mapAttrs :: (String -> Any -> Any) -> AttrSet -> AttrSet 970 + ``` 971 + 972 + # Examples 973 + :::{.example} 974 + ## `lib.attrsets.mapAttrs` usage example 975 + 976 + ```nix 977 + mapAttrs (name: value: name + "-" + value) 978 + { x = "foo"; y = "bar"; } 979 + => { x = "x-foo"; y = "y-bar"; } 980 + ``` 981 + 982 + ::: 608 983 */ 609 984 mapAttrs = builtins.mapAttrs; 610 985 611 986 612 - /* Like `mapAttrs`, but allows the name of each attribute to be 613 - changed in addition to the value. The applied function should 614 - return both the new name and value as a `nameValuePair`. 987 + /** 988 + Like `mapAttrs`, but allows the name of each attribute to be 989 + changed in addition to the value. The applied function should 990 + return both the new name and value as a `nameValuePair`. 991 + 992 + 993 + # Inputs 994 + 995 + `f` 996 + 997 + : A function, given an attribute's name and value, returns a new `nameValuePair`. 998 + 999 + `set` 1000 + 1001 + : Attribute set to map over. 1002 + 1003 + # Type 1004 + 1005 + ``` 1006 + mapAttrs' :: (String -> Any -> { name :: String; value :: Any; }) -> AttrSet -> AttrSet 1007 + ``` 1008 + 1009 + # Examples 1010 + :::{.example} 1011 + ## `lib.attrsets.mapAttrs'` usage example 615 1012 616 - Example: 617 - mapAttrs' (name: value: nameValuePair ("foo_" + name) ("bar-" + value)) 618 - { x = "a"; y = "b"; } 619 - => { foo_x = "bar-a"; foo_y = "bar-b"; } 1013 + ```nix 1014 + mapAttrs' (name: value: nameValuePair ("foo_" + name) ("bar-" + value)) 1015 + { x = "a"; y = "b"; } 1016 + => { foo_x = "bar-a"; foo_y = "bar-b"; } 1017 + ``` 620 1018 621 - Type: 622 - mapAttrs' :: (String -> Any -> { name :: String; value :: Any; }) -> AttrSet -> AttrSet 1019 + ::: 623 1020 */ 624 1021 mapAttrs' = 625 - # A function, given an attribute's name and value, returns a new `nameValuePair`. 626 1022 f: 627 - # Attribute set to map over. 628 1023 set: 629 1024 listToAttrs (map (attr: f attr set.${attr}) (attrNames set)); 630 1025 631 1026 632 - /* Call a function for each attribute in the given set and return 633 - the result in a list. 1027 + /** 1028 + Call a function for each attribute in the given set and return 1029 + the result in a list. 634 1030 635 - Example: 636 - mapAttrsToList (name: value: name + value) 637 - { x = "a"; y = "b"; } 638 - => [ "xa" "yb" ] 1031 + # Inputs 1032 + 1033 + `f` 1034 + 1035 + : A function, given an attribute's name and value, returns a new value. 1036 + 1037 + `attrs` 1038 + 1039 + : Attribute set to map over. 1040 + 1041 + # Type 1042 + 1043 + ``` 1044 + mapAttrsToList :: (String -> a -> b) -> AttrSet -> [b] 1045 + ``` 639 1046 640 - Type: 641 - mapAttrsToList :: (String -> a -> b) -> AttrSet -> [b] 1047 + # Examples 1048 + :::{.example} 1049 + ## `lib.attrsets.mapAttrsToList` usage example 642 1050 1051 + ```nix 1052 + mapAttrsToList (name: value: name + value) 1053 + { x = "a"; y = "b"; } 1054 + => [ "xa" "yb" ] 1055 + ``` 1056 + 1057 + ::: 643 1058 */ 644 1059 mapAttrsToList = 645 - # A function, given an attribute's name and value, returns a new value. 646 1060 f: 647 - # Attribute set to map over. 648 1061 attrs: 649 1062 map (name: f name attrs.${name}) (attrNames attrs); 650 1063 651 - /* 1064 + /** 652 1065 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). 653 1066 Each element of the resulting list is an attribute set with these attributes: 654 1067 - `name` (string): The name of the attribute ··· 668 1081 This is because the `listToAttrs` removes duplicate names and doesn't preserve the order of the list. 669 1082 ::: 670 1083 671 - Example: 672 - attrsToList { foo = 1; bar = "asdf"; } 673 - => [ { name = "bar"; value = "asdf"; } { name = "foo"; value = 1; } ] 1084 + # Inputs 1085 + 1086 + `set` 1087 + 1088 + : The attribute set to deconstruct. 674 1089 675 - Type: 676 - attrsToList :: AttrSet -> [ { name :: String; value :: Any; } ] 1090 + # Type 677 1091 1092 + ``` 1093 + attrsToList :: AttrSet -> [ { name :: String; value :: Any; } ] 1094 + ``` 1095 + 1096 + # Examples 1097 + :::{.example} 1098 + ## `lib.attrsets.attrsToList` usage example 1099 + 1100 + ```nix 1101 + attrsToList { foo = 1; bar = "asdf"; } 1102 + => [ { name = "bar"; value = "asdf"; } { name = "foo"; value = 1; } ] 1103 + ``` 1104 + 1105 + ::: 678 1106 */ 679 1107 attrsToList = mapAttrsToList nameValuePair; 680 1108 ··· 705 1133 ``` 706 1134 */ 707 1135 mapAttrsRecursive = 708 - # A function that, given an attribute path as a list of strings and the corresponding attribute value, returns a new value. 709 1136 f: 710 - # Attribute set to recursively map over. 711 1137 set: 712 1138 mapAttrsRecursiveCond (as: true) f set; 713 1139 ··· 736 1162 ``` 737 1163 */ 738 1164 mapAttrsRecursiveCond = 739 - # A function that, given the attribute set the recursion is currently at, determines if to recurse deeper into that attribute set. 740 1165 cond: 741 - # A function that, given an attribute path as a list of strings and the corresponding attribute value, returns a new value. 742 - # The attribute value is either an attribute set for which `cond` returns false, or something other than an attribute set. 743 1166 f: 744 - # Attribute set to recursively map over. 745 1167 set: 746 1168 let 747 1169 recurse = path: ··· 754 1176 recurse [ ] set; 755 1177 756 1178 757 - /* Generate an attribute set by mapping a function over a list of 758 - attribute names. 1179 + /** 1180 + Generate an attribute set by mapping a function over a list of 1181 + attribute names. 1182 + 1183 + 1184 + # Inputs 1185 + 1186 + `names` 1187 + 1188 + : Names of values in the resulting attribute set. 1189 + 1190 + `f` 1191 + 1192 + : A function, given the name of the attribute, returns the attribute's value. 1193 + 1194 + # Type 1195 + 1196 + ``` 1197 + genAttrs :: [ String ] -> (String -> Any) -> AttrSet 1198 + ``` 1199 + 1200 + # Examples 1201 + :::{.example} 1202 + ## `lib.attrsets.genAttrs` usage example 759 1203 760 - Example: 761 - genAttrs [ "foo" "bar" ] (name: "x_" + name) 762 - => { foo = "x_foo"; bar = "x_bar"; } 1204 + ```nix 1205 + genAttrs [ "foo" "bar" ] (name: "x_" + name) 1206 + => { foo = "x_foo"; bar = "x_bar"; } 1207 + ``` 763 1208 764 - Type: 765 - genAttrs :: [ String ] -> (String -> Any) -> AttrSet 1209 + ::: 766 1210 */ 767 1211 genAttrs = 768 - # Names of values in the resulting attribute set. 769 1212 names: 770 - # A function, given the name of the attribute, returns the attribute's value. 771 1213 f: 772 1214 listToAttrs (map (n: nameValuePair n (f n)) names); 773 1215 774 1216 775 - /* Check whether the argument is a derivation. Any set with 776 - `{ type = "derivation"; }` counts as a derivation. 1217 + /** 1218 + Check whether the argument is a derivation. Any set with 1219 + `{ type = "derivation"; }` counts as a derivation. 777 1220 778 - Example: 779 - nixpkgs = import <nixpkgs> {} 780 - isDerivation nixpkgs.ruby 781 - => true 782 - isDerivation "foobar" 783 - => false 784 1221 785 - Type: 786 - isDerivation :: Any -> Bool 1222 + # Inputs 1223 + 1224 + `value` 1225 + 1226 + : Value to check. 1227 + 1228 + # Type 1229 + 1230 + ``` 1231 + isDerivation :: Any -> Bool 1232 + ``` 1233 + 1234 + # Examples 1235 + :::{.example} 1236 + ## `lib.attrsets.isDerivation` usage example 1237 + 1238 + ```nix 1239 + nixpkgs = import <nixpkgs> {} 1240 + isDerivation nixpkgs.ruby 1241 + => true 1242 + isDerivation "foobar" 1243 + => false 1244 + ``` 1245 + 1246 + ::: 787 1247 */ 788 1248 isDerivation = 789 - # Value to check. 790 1249 value: value.type or null == "derivation"; 791 1250 792 - /* Converts a store path to a fake derivation. 1251 + /** 1252 + Converts a store path to a fake derivation. 1253 + 793 1254 794 - Type: 795 - toDerivation :: Path -> Derivation 796 - */ 1255 + # Inputs 1256 + 1257 + `path` 1258 + 1259 + : A store path to convert to a derivation. 1260 + 1261 + # Type 1262 + 1263 + ``` 1264 + toDerivation :: Path -> Derivation 1265 + ``` 1266 + */ 797 1267 toDerivation = 798 - # A store path to convert to a derivation. 799 1268 path: 800 1269 let 801 1270 path' = builtins.storePath path; ··· 810 1279 in res; 811 1280 812 1281 813 - /* If `cond` is true, return the attribute set `as`, 814 - otherwise an empty attribute set. 1282 + /** 1283 + If `cond` is true, return the attribute set `as`, 1284 + otherwise an empty attribute set. 815 1285 816 - Example: 817 - optionalAttrs (true) { my = "set"; } 818 - => { my = "set"; } 819 - optionalAttrs (false) { my = "set"; } 820 - => { } 821 1286 822 - Type: 823 - optionalAttrs :: Bool -> AttrSet -> AttrSet 1287 + # Inputs 1288 + 1289 + `cond` 1290 + 1291 + : Condition under which the `as` attribute set is returned. 1292 + 1293 + `as` 1294 + 1295 + : The attribute set to return if `cond` is `true`. 1296 + 1297 + # Type 1298 + 1299 + ``` 1300 + optionalAttrs :: Bool -> AttrSet -> AttrSet 1301 + ``` 1302 + 1303 + # Examples 1304 + :::{.example} 1305 + ## `lib.attrsets.optionalAttrs` usage example 1306 + 1307 + ```nix 1308 + optionalAttrs (true) { my = "set"; } 1309 + => { my = "set"; } 1310 + optionalAttrs (false) { my = "set"; } 1311 + => { } 1312 + ``` 1313 + 1314 + ::: 824 1315 */ 825 1316 optionalAttrs = 826 - # Condition under which the `as` attribute set is returned. 827 1317 cond: 828 - # The attribute set to return if `cond` is `true`. 829 1318 as: 830 1319 if cond then as else {}; 831 1320 832 1321 833 - /* Merge sets of attributes and use the function `f` to merge attributes 834 - values. 1322 + /** 1323 + Merge sets of attributes and use the function `f` to merge attributes 1324 + values. 835 1325 836 - Example: 837 - zipAttrsWithNames ["a"] (name: vs: vs) [{a = "x";} {a = "y"; b = "z";}] 838 - => { a = ["x" "y"]; } 1326 + 1327 + # Inputs 839 1328 840 - Type: 841 - zipAttrsWithNames :: [ String ] -> (String -> [ Any ] -> Any) -> [ AttrSet ] -> AttrSet 1329 + `names` 1330 + 1331 + : List of attribute names to zip. 1332 + 1333 + `f` 1334 + 1335 + : A function, accepts an attribute name, all the values, and returns a combined value. 1336 + 1337 + `sets` 1338 + 1339 + : List of values from the list of attribute sets. 1340 + 1341 + # Type 1342 + 1343 + ``` 1344 + zipAttrsWithNames :: [ String ] -> (String -> [ Any ] -> Any) -> [ AttrSet ] -> AttrSet 1345 + ``` 1346 + 1347 + # Examples 1348 + :::{.example} 1349 + ## `lib.attrsets.zipAttrsWithNames` usage example 1350 + 1351 + ```nix 1352 + zipAttrsWithNames ["a"] (name: vs: vs) [{a = "x";} {a = "y"; b = "z";}] 1353 + => { a = ["x" "y"]; } 1354 + ``` 1355 + 1356 + ::: 842 1357 */ 843 1358 zipAttrsWithNames = 844 - # List of attribute names to zip. 845 1359 names: 846 - # A function, accepts an attribute name, all the values, and returns a combined value. 847 1360 f: 848 - # List of values from the list of attribute sets. 849 1361 sets: 850 1362 listToAttrs (map (name: { 851 1363 inherit name; ··· 853 1365 }) names); 854 1366 855 1367 856 - /* Merge sets of attributes and use the function f to merge attribute values. 857 - Like `lib.attrsets.zipAttrsWithNames` with all key names are passed for `names`. 1368 + /** 1369 + Merge sets of attributes and use the function f to merge attribute values. 1370 + Like `lib.attrsets.zipAttrsWithNames` with all key names are passed for `names`. 1371 + 1372 + Implementation note: Common names appear multiple times in the list of 1373 + names, hopefully this does not affect the system because the maximal 1374 + laziness avoid computing twice the same expression and `listToAttrs` does 1375 + not care about duplicated attribute names. 1376 + 1377 + # Type 1378 + 1379 + ``` 1380 + zipAttrsWith :: (String -> [ Any ] -> Any) -> [ AttrSet ] -> AttrSet 1381 + ``` 858 1382 859 - Implementation note: Common names appear multiple times in the list of 860 - names, hopefully this does not affect the system because the maximal 861 - laziness avoid computing twice the same expression and `listToAttrs` does 862 - not care about duplicated attribute names. 1383 + # Examples 1384 + :::{.example} 1385 + ## `lib.attrsets.zipAttrsWith` usage example 863 1386 864 - Example: 865 - zipAttrsWith (name: values: values) [{a = "x";} {a = "y"; b = "z";}] 866 - => { a = ["x" "y"]; b = ["z"]; } 1387 + ```nix 1388 + zipAttrsWith (name: values: values) [{a = "x";} {a = "y"; b = "z";}] 1389 + => { a = ["x" "y"]; b = ["z"]; } 1390 + ``` 867 1391 868 - Type: 869 - zipAttrsWith :: (String -> [ Any ] -> Any) -> [ AttrSet ] -> AttrSet 1392 + ::: 870 1393 */ 871 1394 zipAttrsWith = 872 1395 builtins.zipAttrsWith or (f: sets: zipAttrsWithNames (concatMap attrNames sets) f sets); 873 1396 874 1397 875 - /* Merge sets of attributes and combine each attribute value in to a list. 1398 + /** 1399 + Merge sets of attributes and combine each attribute value in to a list. 876 1400 877 - Like `lib.attrsets.zipAttrsWith` with `(name: values: values)` as the function. 1401 + Like `lib.attrsets.zipAttrsWith` with `(name: values: values)` as the function. 878 1402 879 - Example: 880 - zipAttrs [{a = "x";} {a = "y"; b = "z";}] 881 - => { a = ["x" "y"]; b = ["z"]; } 1403 + # Type 1404 + 1405 + ``` 1406 + zipAttrs :: [ AttrSet ] -> AttrSet 1407 + ``` 1408 + 1409 + # Examples 1410 + :::{.example} 1411 + ## `lib.attrsets.zipAttrs` usage example 1412 + 1413 + ```nix 1414 + zipAttrs [{a = "x";} {a = "y"; b = "z";}] 1415 + => { a = ["x" "y"]; b = ["z"]; } 1416 + ``` 882 1417 883 - Type: 884 - zipAttrs :: [ AttrSet ] -> AttrSet 1418 + ::: 885 1419 */ 886 1420 zipAttrs = zipAttrsWith (name: values: values); 887 1421 888 - /* 1422 + /** 889 1423 Merge a list of attribute sets together using the `//` operator. 890 1424 In case of duplicate attributes, values from later list elements take precedence over earlier ones. 891 1425 The result is the same as `foldl mergeAttrs { }`, but the performance is better for large inputs. 892 1426 For n list elements, each with an attribute set containing m unique attributes, the complexity of this operation is O(nm log n). 893 1427 894 - Type: 895 - mergeAttrsList :: [ Attrs ] -> Attrs 1428 + 1429 + # Inputs 1430 + 1431 + `list` 1432 + 1433 + : 1\. Function argument 1434 + 1435 + # Type 1436 + 1437 + ``` 1438 + mergeAttrsList :: [ Attrs ] -> Attrs 1439 + ``` 896 1440 897 - Example: 898 - mergeAttrsList [ { a = 0; b = 1; } { c = 2; d = 3; } ] 899 - => { a = 0; b = 1; c = 2; d = 3; } 900 - mergeAttrsList [ { a = 0; } { a = 1; } ] 901 - => { a = 1; } 1441 + # Examples 1442 + :::{.example} 1443 + ## `lib.attrsets.mergeAttrsList` usage example 1444 + 1445 + ```nix 1446 + mergeAttrsList [ { a = 0; b = 1; } { c = 2; d = 3; } ] 1447 + => { a = 0; b = 1; c = 2; d = 3; } 1448 + mergeAttrsList [ { a = 0; } { a = 1; } ] 1449 + => { a = 1; } 1450 + ``` 1451 + 1452 + ::: 902 1453 */ 903 1454 mergeAttrsList = list: 904 1455 let ··· 922 1473 binaryMerge 0 (length list); 923 1474 924 1475 925 - /* Does the same as the update operator '//' except that attributes are 926 - merged until the given predicate is verified. The predicate should 927 - accept 3 arguments which are the path to reach the attribute, a part of 928 - the first attribute set and a part of the second attribute set. When 929 - the predicate is satisfied, the value of the first attribute set is 930 - replaced by the value of the second attribute set. 1476 + /** 1477 + Does the same as the update operator '//' except that attributes are 1478 + merged until the given predicate is verified. The predicate should 1479 + accept 3 arguments which are the path to reach the attribute, a part of 1480 + the first attribute set and a part of the second attribute set. When 1481 + the predicate is satisfied, the value of the first attribute set is 1482 + replaced by the value of the second attribute set. 931 1483 932 - Example: 933 - recursiveUpdateUntil (path: l: r: path == ["foo"]) { 934 - # first attribute set 935 - foo.bar = 1; 936 - foo.baz = 2; 937 - bar = 3; 938 - } { 939 - #second attribute set 940 - foo.bar = 1; 941 - foo.quz = 2; 942 - baz = 4; 943 - } 1484 + 1485 + # Inputs 1486 + 1487 + `pred` 1488 + 1489 + : 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. 1490 + 1491 + `lhs` 1492 + 1493 + : Left attribute set of the merge. 1494 + 1495 + `rhs` 1496 + 1497 + : Right attribute set of the merge. 1498 + 1499 + # Type 1500 + 1501 + ``` 1502 + recursiveUpdateUntil :: ( [ String ] -> AttrSet -> AttrSet -> Bool ) -> AttrSet -> AttrSet -> AttrSet 1503 + ``` 944 1504 945 - => { 946 - foo.bar = 1; # 'foo.*' from the second set 947 - foo.quz = 2; # 948 - bar = 3; # 'bar' from the first set 949 - baz = 4; # 'baz' from the second set 950 - } 1505 + # Examples 1506 + :::{.example} 1507 + ## `lib.attrsets.recursiveUpdateUntil` usage example 951 1508 952 - Type: 953 - recursiveUpdateUntil :: ( [ String ] -> AttrSet -> AttrSet -> Bool ) -> AttrSet -> AttrSet -> AttrSet 1509 + ```nix 1510 + recursiveUpdateUntil (path: l: r: path == ["foo"]) { 1511 + # first attribute set 1512 + foo.bar = 1; 1513 + foo.baz = 2; 1514 + bar = 3; 1515 + } { 1516 + #second attribute set 1517 + foo.bar = 1; 1518 + foo.quz = 2; 1519 + baz = 4; 1520 + } 1521 + 1522 + => { 1523 + foo.bar = 1; # 'foo.*' from the second set 1524 + foo.quz = 2; # 1525 + bar = 3; # 'bar' from the first set 1526 + baz = 4; # 'baz' from the second set 1527 + } 1528 + ``` 1529 + 1530 + ::: 954 1531 */ 955 1532 recursiveUpdateUntil = 956 - # 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. 957 1533 pred: 958 - # Left attribute set of the merge. 959 1534 lhs: 960 - # Right attribute set of the merge. 961 1535 rhs: 962 1536 let f = attrPath: 963 1537 zipAttrsWith (n: values: ··· 971 1545 in f [] [rhs lhs]; 972 1546 973 1547 974 - /* A recursive variant of the update operator ‘//’. The recursion 975 - stops when one of the attribute values is not an attribute set, 976 - in which case the right hand side value takes precedence over the 977 - left hand side value. 1548 + /** 1549 + A recursive variant of the update operator ‘//’. The recursion 1550 + stops when one of the attribute values is not an attribute set, 1551 + in which case the right hand side value takes precedence over the 1552 + left hand side value. 1553 + 1554 + 1555 + # Inputs 1556 + 1557 + `lhs` 1558 + 1559 + : Left attribute set of the merge. 978 1560 979 - Example: 980 - recursiveUpdate { 981 - boot.loader.grub.enable = true; 982 - boot.loader.grub.device = "/dev/hda"; 983 - } { 984 - boot.loader.grub.device = ""; 985 - } 1561 + `rhs` 986 1562 987 - returns: { 988 - boot.loader.grub.enable = true; 989 - boot.loader.grub.device = ""; 990 - } 1563 + : Right attribute set of the merge. 991 1564 992 - Type: 993 - recursiveUpdate :: AttrSet -> AttrSet -> AttrSet 1565 + # Type 1566 + 1567 + ``` 1568 + recursiveUpdate :: AttrSet -> AttrSet -> AttrSet 1569 + ``` 1570 + 1571 + # Examples 1572 + :::{.example} 1573 + ## `lib.attrsets.recursiveUpdate` usage example 1574 + 1575 + ```nix 1576 + recursiveUpdate { 1577 + boot.loader.grub.enable = true; 1578 + boot.loader.grub.device = "/dev/hda"; 1579 + } { 1580 + boot.loader.grub.device = ""; 1581 + } 1582 + 1583 + returns: { 1584 + boot.loader.grub.enable = true; 1585 + boot.loader.grub.device = ""; 1586 + } 1587 + ``` 1588 + 1589 + ::: 994 1590 */ 995 1591 recursiveUpdate = 996 - # Left attribute set of the merge. 997 1592 lhs: 998 - # Right attribute set of the merge. 999 1593 rhs: 1000 1594 recursiveUpdateUntil (path: lhs: rhs: !(isAttrs lhs && isAttrs rhs)) lhs rhs; 1001 1595 1002 1596 1003 - /* 1597 + /** 1004 1598 Recurse into every attribute set of the first argument and check that: 1005 1599 - Each attribute path also exists in the second argument. 1006 1600 - If the attribute's value is not a nested attribute set, it must have the same value in the right argument. 1007 1601 1008 - Example: 1009 - matchAttrs { cpu = {}; } { cpu = { bits = 64; }; } 1010 - => true 1602 + 1603 + # Inputs 1604 + 1605 + `pattern` 1606 + 1607 + : Attribute set structure to match 1608 + 1609 + `attrs` 1610 + 1611 + : Attribute set to check 1011 1612 1012 - Type: 1013 - matchAttrs :: AttrSet -> AttrSet -> Bool 1613 + # Type 1614 + 1615 + ``` 1616 + matchAttrs :: AttrSet -> AttrSet -> Bool 1617 + ``` 1618 + 1619 + # Examples 1620 + :::{.example} 1621 + ## `lib.attrsets.matchAttrs` usage example 1622 + 1623 + ```nix 1624 + matchAttrs { cpu = {}; } { cpu = { bits = 64; }; } 1625 + => true 1626 + ``` 1627 + 1628 + ::: 1014 1629 */ 1015 1630 matchAttrs = 1016 - # Attribute set structure to match 1017 1631 pattern: 1018 - # Attribute set to check 1019 1632 attrs: 1020 1633 assert isAttrs pattern; 1021 1634 all ··· 1034 1647 ) 1035 1648 (attrNames pattern); 1036 1649 1037 - /* Override only the attributes that are already present in the old set 1650 + /** 1651 + Override only the attributes that are already present in the old set 1038 1652 useful for deep-overriding. 1039 1653 1040 - Example: 1041 - overrideExisting {} { a = 1; } 1042 - => {} 1043 - overrideExisting { b = 2; } { a = 1; } 1044 - => { b = 2; } 1045 - overrideExisting { a = 3; b = 2; } { a = 1; } 1046 - => { a = 1; b = 2; } 1654 + 1655 + # Inputs 1656 + 1657 + `old` 1658 + 1659 + : Original attribute set 1660 + 1661 + `new` 1662 + 1663 + : Attribute set with attributes to override in `old`. 1664 + 1665 + # Type 1666 + 1667 + ``` 1668 + overrideExisting :: AttrSet -> AttrSet -> AttrSet 1669 + ``` 1670 + 1671 + # Examples 1672 + :::{.example} 1673 + ## `lib.attrsets.overrideExisting` usage example 1674 + 1675 + ```nix 1676 + overrideExisting {} { a = 1; } 1677 + => {} 1678 + overrideExisting { b = 2; } { a = 1; } 1679 + => { b = 2; } 1680 + overrideExisting { a = 3; b = 2; } { a = 1; } 1681 + => { a = 1; b = 2; } 1682 + ``` 1047 1683 1048 - Type: 1049 - overrideExisting :: AttrSet -> AttrSet -> AttrSet 1684 + ::: 1050 1685 */ 1051 1686 overrideExisting = 1052 - # Original attribute set 1053 1687 old: 1054 - # Attribute set with attributes to override in `old`. 1055 1688 new: 1056 1689 mapAttrs (name: value: new.${name} or value) old; 1057 1690 1058 1691 1059 - /* Turns a list of strings into a human-readable description of those 1692 + /** 1693 + Turns a list of strings into a human-readable description of those 1060 1694 strings represented as an attribute path. The result of this function is 1061 1695 not intended to be machine-readable. 1062 1696 Create a new attribute set with `value` set at the nested attribute location specified in `attrPath`. 1063 1697 1064 - Example: 1065 - showAttrPath [ "foo" "10" "bar" ] 1066 - => "foo.\"10\".bar" 1067 - showAttrPath [] 1068 - => "<root attribute path>" 1069 1698 1070 - Type: 1071 - showAttrPath :: [String] -> String 1699 + # Inputs 1700 + 1701 + `path` 1702 + 1703 + : Attribute path to render to a string 1704 + 1705 + # Type 1706 + 1707 + ``` 1708 + showAttrPath :: [String] -> String 1709 + ``` 1710 + 1711 + # Examples 1712 + :::{.example} 1713 + ## `lib.attrsets.showAttrPath` usage example 1714 + 1715 + ```nix 1716 + showAttrPath [ "foo" "10" "bar" ] 1717 + => "foo.\"10\".bar" 1718 + showAttrPath [] 1719 + => "<root attribute path>" 1720 + ``` 1721 + 1722 + ::: 1072 1723 */ 1073 1724 showAttrPath = 1074 - # Attribute path to render to a string 1075 1725 path: 1076 1726 if path == [] then "<root attribute path>" 1077 1727 else concatMapStringsSep "." escapeNixIdentifier path; 1078 1728 1079 1729 1080 - /* Get a package output. 1081 - If no output is found, fallback to `.out` and then to the default. 1730 + /** 1731 + Get a package output. 1732 + If no output is found, fallback to `.out` and then to the default. 1733 + 1734 + 1735 + # Inputs 1736 + 1737 + `output` 1738 + 1739 + : 1\. Function argument 1082 1740 1083 - Example: 1084 - getOutput "dev" pkgs.openssl 1085 - => "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-dev" 1741 + `pkg` 1086 1742 1087 - Type: 1088 - getOutput :: String -> Derivation -> String 1743 + : 2\. Function argument 1744 + 1745 + # Type 1746 + 1747 + ``` 1748 + getOutput :: String -> Derivation -> String 1749 + ``` 1750 + 1751 + # Examples 1752 + :::{.example} 1753 + ## `lib.attrsets.getOutput` usage example 1754 + 1755 + ```nix 1756 + getOutput "dev" pkgs.openssl 1757 + => "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-dev" 1758 + ``` 1759 + 1760 + ::: 1089 1761 */ 1090 1762 getOutput = output: pkg: 1091 1763 if ! pkg ? outputSpecified || ! pkg.outputSpecified 1092 1764 then pkg.${output} or pkg.out or pkg 1093 1765 else pkg; 1094 1766 1095 - /* Get a package's `bin` output. 1096 - If the output does not exist, fallback to `.out` and then to the default. 1767 + /** 1768 + Get a package's `bin` output. 1769 + If the output does not exist, fallback to `.out` and then to the default. 1770 + 1771 + # Inputs 1772 + 1773 + `pkg` 1774 + 1775 + : The package whose `bin` output will be retrieved. 1776 + 1777 + # Type 1778 + 1779 + ``` 1780 + getBin :: Derivation -> String 1781 + ``` 1097 1782 1098 - Example: 1099 - getBin pkgs.openssl 1100 - => "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r" 1783 + # Examples 1784 + :::{.example} 1785 + ## `lib.attrsets.getBin` usage example 1101 1786 1102 - Type: 1103 - getBin :: Derivation -> String 1787 + ```nix 1788 + getBin pkgs.openssl 1789 + => "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r" 1790 + ``` 1791 + 1792 + ::: 1104 1793 */ 1105 1794 getBin = getOutput "bin"; 1106 1795 1107 1796 1108 - /* Get a package's `lib` output. 1109 - If the output does not exist, fallback to `.out` and then to the default. 1797 + /** 1798 + Get a package's `lib` output. 1799 + If the output does not exist, fallback to `.out` and then to the default. 1110 1800 1111 - Example: 1112 - getLib pkgs.openssl 1113 - => "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-lib" 1801 + # Inputs 1802 + 1803 + `pkg` 1114 1804 1115 - Type: 1116 - getLib :: Derivation -> String 1805 + : The package whose `lib` output will be retrieved. 1806 + 1807 + # Type 1808 + 1809 + ``` 1810 + getLib :: Derivation -> String 1811 + ``` 1812 + 1813 + # Examples 1814 + :::{.example} 1815 + ## `lib.attrsets.getLib` usage example 1816 + 1817 + ```nix 1818 + getLib pkgs.openssl 1819 + => "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-lib" 1820 + ``` 1821 + 1822 + ::: 1117 1823 */ 1118 1824 getLib = getOutput "lib"; 1119 1825 1120 1826 1121 - /* Get a package's `dev` output. 1122 - If the output does not exist, fallback to `.out` and then to the default. 1827 + /** 1828 + Get a package's `dev` output. 1829 + If the output does not exist, fallback to `.out` and then to the default. 1830 + 1831 + # Inputs 1832 + 1833 + `pkg` 1834 + 1835 + : The package whose `dev` output will be retrieved. 1836 + 1837 + # Type 1838 + 1839 + ``` 1840 + getDev :: Derivation -> String 1841 + ``` 1123 1842 1124 - Example: 1125 - getDev pkgs.openssl 1126 - => "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-dev" 1843 + # Examples 1844 + :::{.example} 1845 + ## `lib.attrsets.getDev` usage example 1846 + 1847 + ```nix 1848 + getDev pkgs.openssl 1849 + => "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-dev" 1850 + ``` 1127 1851 1128 - Type: 1129 - getDev :: Derivation -> String 1852 + ::: 1130 1853 */ 1131 1854 getDev = getOutput "dev"; 1132 1855 1133 1856 1134 - /* Get a package's `man` output. 1135 - If the output does not exist, fallback to `.out` and then to the default. 1857 + /** 1858 + Get a package's `man` output. 1859 + If the output does not exist, fallback to `.out` and then to the default. 1136 1860 1137 - Example: 1138 - getMan pkgs.openssl 1139 - => "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-man" 1861 + # Inputs 1140 1862 1141 - Type: 1142 - getMan :: Derivation -> String 1863 + `pkg` 1864 + 1865 + : The package whose `man` output will be retrieved. 1866 + 1867 + # Type 1868 + 1869 + ``` 1870 + getMan :: Derivation -> String 1871 + ``` 1872 + 1873 + # Examples 1874 + :::{.example} 1875 + ## `lib.attrsets.getMan` usage example 1876 + 1877 + ```nix 1878 + getMan pkgs.openssl 1879 + => "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-man" 1880 + ``` 1881 + 1882 + ::: 1143 1883 */ 1144 1884 getMan = getOutput "man"; 1145 1885 1146 - /* Pick the outputs of packages to place in `buildInputs` 1886 + /** 1887 + Pick the outputs of packages to place in `buildInputs` 1888 + 1889 + # Inputs 1890 + 1891 + `pkgs` 1892 + 1893 + : List of packages. 1147 1894 1148 - Type: chooseDevOutputs :: [Derivation] -> [String] 1895 + # Type 1149 1896 1897 + ``` 1898 + chooseDevOutputs :: [Derivation] -> [String] 1899 + ``` 1150 1900 */ 1151 1901 chooseDevOutputs = builtins.map getDev; 1152 1902 1153 - /* Make various Nix tools consider the contents of the resulting 1154 - attribute set when looking for what to build, find, etc. 1903 + /** 1904 + Make various Nix tools consider the contents of the resulting 1905 + attribute set when looking for what to build, find, etc. 1906 + 1907 + This function only affects a single attribute set; it does not 1908 + apply itself recursively for nested attribute sets. 1909 + 1155 1910 1156 - This function only affects a single attribute set; it does not 1157 - apply itself recursively for nested attribute sets. 1911 + # Inputs 1158 1912 1159 - Example: 1160 - { pkgs ? import <nixpkgs> {} }: 1161 - { 1162 - myTools = pkgs.lib.recurseIntoAttrs { 1163 - inherit (pkgs) hello figlet; 1164 - }; 1165 - } 1913 + `attrs` 1166 1914 1167 - Type: 1168 - recurseIntoAttrs :: AttrSet -> AttrSet 1915 + : An attribute set to scan for derivations. 1916 + 1917 + # Type 1169 1918 1170 - */ 1919 + ``` 1920 + recurseIntoAttrs :: AttrSet -> AttrSet 1921 + ``` 1922 + 1923 + # Examples 1924 + :::{.example} 1925 + ## `lib.attrsets.recurseIntoAttrs` usage example 1926 + 1927 + ```nix 1928 + { pkgs ? import <nixpkgs> {} }: 1929 + { 1930 + myTools = pkgs.lib.recurseIntoAttrs { 1931 + inherit (pkgs) hello figlet; 1932 + }; 1933 + } 1934 + ``` 1935 + 1936 + ::: 1937 + */ 1171 1938 recurseIntoAttrs = 1172 - # An attribute set to scan for derivations. 1173 1939 attrs: 1174 1940 attrs // { recurseForDerivations = true; }; 1175 1941 1176 - /* Undo the effect of recurseIntoAttrs. 1942 + /** 1943 + Undo the effect of recurseIntoAttrs. 1944 + 1945 + 1946 + # Inputs 1947 + 1948 + `attrs` 1177 1949 1178 - Type: 1179 - dontRecurseIntoAttrs :: AttrSet -> AttrSet 1180 - */ 1950 + : An attribute set to not scan for derivations. 1951 + 1952 + # Type 1953 + 1954 + ``` 1955 + dontRecurseIntoAttrs :: AttrSet -> AttrSet 1956 + ``` 1957 + */ 1181 1958 dontRecurseIntoAttrs = 1182 - # An attribute set to not scan for derivations. 1183 1959 attrs: 1184 1960 attrs // { recurseForDerivations = false; }; 1185 1961 1186 - /* `unionOfDisjoint x y` is equal to `x // y // z` where the 1187 - attrnames in `z` are the intersection of the attrnames in `x` and 1188 - `y`, and all values `assert` with an error message. This 1189 - operator is commutative, unlike (//). 1962 + /** 1963 + `unionOfDisjoint x y` is equal to `x // y // z` where the 1964 + attrnames in `z` are the intersection of the attrnames in `x` and 1965 + `y`, and all values `assert` with an error message. This 1966 + operator is commutative, unlike (//). 1190 1967 1191 - Type: unionOfDisjoint :: AttrSet -> AttrSet -> AttrSet 1968 + 1969 + # Inputs 1970 + 1971 + `x` 1972 + 1973 + : 1\. Function argument 1974 + 1975 + `y` 1976 + 1977 + : 2\. Function argument 1978 + 1979 + # Type 1980 + 1981 + ``` 1982 + unionOfDisjoint :: AttrSet -> AttrSet -> AttrSet 1983 + ``` 1192 1984 */ 1193 1985 unionOfDisjoint = x: y: 1194 1986 let