# Nixpkgs lib
This directory contains the implementation, documentation and tests for the Nixpkgs `lib` library.
## Overview
The evaluation entry point for `lib` is [`default.nix`](default.nix).
This file evaluates to an attribute set containing two separate kinds of attributes:
- Sub-libraries:
Attribute sets grouping together similar functionality.
Each sub-library is defined in a separate file usually matching its attribute name.
Example: `lib.lists` is a sub-library containing list-related functionality such as `lib.lists.take` and `lib.lists.imap0`.
These are defined in the file [`lists.nix`](lists.nix).
- Aliases:
Attributes that point to an attribute of the same name in some sub-library.
Example: `lib.take` is an alias for `lib.lists.take`.
Most files in this directory are definitions of sub-libraries, but there are a few others:
- [`minver.nix`](minver.nix): A string of the minimum version of Nix that is required to evaluate Nixpkgs.
- [`tests`](tests): Tests, see [Running tests](#running-tests)
- [`release.nix`](tests/release.nix): A derivation aggregating all tests
- [`misc.nix`](tests/misc.nix): Evaluation unit tests for most sub-libraries
- `*.sh`: Bash scripts that run tests for specific sub-libraries
- All other files in this directory exist to support the tests
- [`systems`](systems): The `lib.systems` sub-library, structured into a directory instead of a file due to its complexity
- [`path`](path): The `lib.path` sub-library, which includes tests as well as a document describing the design goals of `lib.path`
- All other files in this directory are sub-libraries
### Module system
The [module system](https://nixos.org/manual/nixpkgs/#module-system) spans multiple sub-libraries:
- [`modules.nix`](modules.nix): `lib.modules` for the core functions and anything not relating to option definitions
- [`options.nix`](options.nix): `lib.options` for anything relating to option definitions
- [`types.nix`](types.nix): `lib.types` for module system types
## PR Guidelines
Follow these guidelines for proposing a change to the interface of `lib`.
### Provide a Motivation
Clearly describe why the change is necessary and its use cases.
Make sure that the change benefits the user more than the added mental effort of looking it up and keeping track of its definition.
If the same can reasonably be done with the existing interface,
consider just updating the documentation with more examples and links.
This is also known as the [Fairbairn Threshold](https://wiki.haskell.org/Fairbairn_threshold).
Through this principle we avoid the human cost of duplicated functionality in an overly large library.
### Make one PR for each change
Don't have multiple changes in one PR, instead split it up into multiple ones.
This keeps the conversation focused and has a higher chance of getting merged.
### Name the interface appropriately
When introducing new names to the interface, such as new function, or new function attributes,
make sure to name it appropriately.
Names should be self-explanatory and consistent with the rest of `lib`.