1# Nixpkgs lib 2 3This directory contains the implementation, documentation and tests for the Nixpkgs `lib` library. 4 5## Overview 6 7The evaluation entry point for `lib` is [`default.nix`](default.nix). 8This file evaluates to an attribute set containing two separate kinds of attributes: 9- Sub-libraries: 10 Attribute sets grouping together similar functionality. 11 Each sub-library is defined in a separate file usually matching its attribute name. 12 13 Example: `lib.lists` is a sub-library containing list-related functionality such as `lib.lists.take` and `lib.lists.imap0`. 14 These are defined in the file [`lists.nix`](lists.nix). 15 16- Aliases: 17 Attributes that point to an attribute of the same name in some sub-library. 18 19 Example: `lib.take` is an alias for `lib.lists.take`. 20 21Most files in this directory are definitions of sub-libraries, but there are a few others: 22- [`minfeatures.nix`](minfeatures.nix): A list of conditions for the used Nix version to match that are required to evaluate Nixpkgs. 23- [`tests`](tests): Tests, see [Running tests](#running-tests) 24 - [`release.nix`](tests/release.nix): A derivation aggregating all tests 25 - [`misc.nix`](tests/misc.nix): Evaluation unit tests for most sub-libraries 26 - `*.sh`: Bash scripts that run tests for specific sub-libraries 27 - All other files in this directory exist to support the tests 28- [`systems`](systems): The `lib.systems` sub-library, structured into a directory instead of a file due to its complexity 29- [`path`](path): The `lib.path` sub-library, which includes tests as well as a document describing the design goals of `lib.path` 30- All other files in this directory are sub-libraries 31 32### Module system 33 34The [module system](https://nixos.org/manual/nixpkgs/#module-system) spans multiple sub-libraries: 35- [`modules.nix`](modules.nix): `lib.modules` for the core functions and anything not relating to option definitions 36- [`options.nix`](options.nix): `lib.options` for anything relating to option definitions 37- [`types.nix`](types.nix): `lib.types` for module system types 38 39## PR Guidelines 40 41Follow these guidelines for proposing a change to the interface of `lib`. 42 43### Provide a Motivation 44 45Clearly describe why the change is necessary and its use cases. 46 47Make sure that the change benefits the user more than the added mental effort of looking it up and keeping track of its definition. 48If the same can reasonably be done with the existing interface, 49consider just updating the documentation with more examples and links. 50This is also known as the [Fairbairn Threshold](https://wiki.haskell.org/Fairbairn_threshold). 51 52Through this principle we avoid the human cost of duplicated functionality in an overly large library. 53 54### Make one PR for each change 55 56Don't have multiple changes in one PR, instead split it up into multiple ones. 57 58This keeps the conversation focused and has a higher chance of getting merged. 59 60### Name the interface appropriately 61 62When introducing new names to the interface, such as new function, or new function attributes, 63make sure to name it appropriately. 64 65Names should be self-explanatory and consistent with the rest of `lib`. 66If there's no obvious best name, include the alternatives you considered. 67 68### Write documentation 69 70Update the [reference documentation](#reference-documentation) to reflect the change. 71 72Be generous with links to related functionality. 73 74### Write tests 75 76Add good test coverage for the change, including: 77 78- Tests for edge cases, such as empty values or lists. 79- Tests for tricky inputs, such as a string with string context or a path that doesn't exist. 80- Test all code paths, such as `if-then-else` branches and returned attributes. 81- If the tests for the sub-library are written in bash, 82 test messages of custom errors, such as `throw` or `abortMsg`, 83 84 At the time this is only not necessary for sub-libraries tested with [`tests/misc.nix`](./tests/misc.nix). 85 86See [running tests](#running-tests) for more details on the test suites. 87 88### Write tidy code 89 90Name variables well, even if they're internal. 91The code should be as self-explanatory as possible. 92Be generous with code comments when appropriate. 93 94As a baseline, follow the [Nixpkgs code conventions](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md#code-conventions). 95 96### Write efficient code 97 98Nix generally does not have free abstractions. 99Be aware that seemingly straightforward changes can cause more allocations and a decrease in performance. 100That said, don't optimise prematurely, especially in new code. 101 102## Reference documentation 103 104Reference documentation for library functions is written above each function as a multi-line comment. 105These comments are processed using [nixdoc](https://github.com/nix-community/nixdoc) and [rendered in the Nixpkgs manual](https://nixos.org/manual/nixpkgs/stable/#chap-functions). 106The nixdoc README describes the [comment format](https://github.com/nix-community/nixdoc#comment-format). 107 108See [doc/README.md](../doc/README.md) for how to build the manual. 109 110## Running tests 111 112All library tests can be run by building the derivation in [`tests/release.nix`](tests/release.nix): 113 114```bash 115nix-build tests/release.nix 116``` 117 118Some commands for quicker iteration over parts of the test suite are also available: 119 120```bash 121# Run all evaluation unit tests in tests/misc.nix 122# if the resulting list is empty, all tests passed 123nix-instantiate --eval --strict tests/misc.nix 124 125# Run the module system tests 126tests/modules.sh 127 128# Run the lib.sources tests 129tests/sources.sh 130 131# Run the lib.filesystem tests 132tests/filesystem.sh 133 134# Run the lib.path property tests 135path/tests/prop.sh 136 137# Run the lib.fileset tests 138fileset/tests.sh 139``` 140 141## Commit conventions 142 143- Make sure you read about the [commit conventions](../CONTRIBUTING.md#commit-conventions) common to Nixpkgs as a whole. 144 145- Format the commit messages in the following way: 146 147 ``` 148 lib.(section): (init | add additional argument | refactor | etc) 149 150 (Motivation for change. Additional information.) 151 ``` 152 153 Examples: 154 155 * lib.getExe': check arguments 156 * lib.fileset: Add an additional argument in the design docs 157 158 Closes #264537 159