104 lines
3.5 KiB
Markdown
104 lines
3.5 KiB
Markdown
![]() |
# Notes for 7th of June, 2023
|
|||
|
|
|||
|
Those are my notes on extending nixpkgs with your own functions and
|
|||
|
abstractions. There may be other ways of doing it, but this is the one I find
|
|||
|
to be most ergonomic.
|
|||
|
|
|||
|
## What is `nixpkgs.lib`
|
|||
|
|
|||
|
In the context of the Nix package manager and NixOS, `nixpkgs.lib` refers to
|
|||
|
a module within the Nixpkgs repository. The `nixpkgs.lib` module provides a
|
|||
|
set of utility functions and definitions that are commonly used across the
|
|||
|
Nixpkgs repository. It contains various helper functions and abstractions that
|
|||
|
make it easier to write Nix expressions and define packages. We often use those
|
|||
|
functions to simplify our configurations and the nix package build processes.
|
|||
|
|
|||
|
## Why would you need to extend `nixpkgs.lib`
|
|||
|
|
|||
|
While the library functions provided by nixpkgs is quite extensive and usually
|
|||
|
suits my needs, I sometimes feel the need to define my own function or wrap an
|
|||
|
existing function to complete a task. Normally we can handle the process of a
|
|||
|
function inside a simple `let in` and be well off, but there may be times you
|
|||
|
need to re-use the existing function across your configuration file.
|
|||
|
|
|||
|
In such times, you might want to either write your own lib and inherit it at
|
|||
|
the source of your `flake.nix` to then inherit them across your configuration.
|
|||
|
|
|||
|
Today's notes document the process of doing exactly that.
|
|||
|
|
|||
|
## Extending `nixpkgs.lib`
|
|||
|
|
|||
|
I find the easiest way of extending nixpkgs.lib to be using an overlay.
|
|||
|
|
|||
|
```nix
|
|||
|
# lib/default.nix
|
|||
|
{
|
|||
|
nixpkgs,
|
|||
|
lib,
|
|||
|
inputs,
|
|||
|
...
|
|||
|
}: nixpkgs.lib.extend (
|
|||
|
final: prev: {
|
|||
|
# your functions go here
|
|||
|
}
|
|||
|
)
|
|||
|
```
|
|||
|
|
|||
|
The above structure takes the existing `lib` from `nixpkgs`, and appends your
|
|||
|
own configurations to it. You may then import this library in your `flake.nix`
|
|||
|
to pass it to other imports and definitions.
|
|||
|
|
|||
|
```nix
|
|||
|
# flake.nix
|
|||
|
flake = let
|
|||
|
# extended nixpkgs lib, contains my custom functions
|
|||
|
lib = import ./lib {inherit nixpkgs lib inputs;};
|
|||
|
in {
|
|||
|
# entry-point for nixos configurations
|
|||
|
nixosConfigurations = import ./hosts {inherit nixpkgs self lib;};
|
|||
|
};
|
|||
|
```
|
|||
|
|
|||
|
In this example (see my `flake.nix` for the actual implementation) I import my
|
|||
|
extended lib from `lib/default.nix`, where I defined the overlay. I then pass
|
|||
|
the extended lib to my `nixosConfiguratiıns`, which is an entry-point for all
|
|||
|
of my NixOS configurations. As such, I am able to re-use my own utility
|
|||
|
functions across my system as I see fit.
|
|||
|
|
|||
|
The problem with this approach is that it may be confusing for other people
|
|||
|
reviewing your configuration. With this approach, `lib.customFunction` looks
|
|||
|
identical to any lib function, which may lead to people thinking the function
|
|||
|
exists in nixpkgs itself while it is only provided by your configuration. The
|
|||
|
solution for that is simple though, instead of extending `nixpkgs.lib`, you may
|
|||
|
define your own lib that does not inherit from `nixpkgs.lib` and only contains
|
|||
|
your functions. The process would be similar, and you would not need to define
|
|||
|
an overlay.
|
|||
|
|
|||
|
```nix
|
|||
|
# flake.nix
|
|||
|
flake = let
|
|||
|
# extended nixpkgs lib, contains my custom functions
|
|||
|
lib' = import ./lib {inherit nixpkgs lib inputs;};
|
|||
|
in {
|
|||
|
# entry-point for nixos configurations
|
|||
|
nixosConfigurations = import ./hosts {inherit nixpkgs self lib';};
|
|||
|
};
|
|||
|
```
|
|||
|
|
|||
|
where your `lib/default.nix` looks like
|
|||
|
|
|||
|
```nix
|
|||
|
# lib/default.nix
|
|||
|
{
|
|||
|
nixpkgs,
|
|||
|
lib,
|
|||
|
inputs,
|
|||
|
...
|
|||
|
}: {
|
|||
|
# your functions here
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
You can find a real life example of the alternative approach in
|
|||
|
my [neovim-flake's lib](https://github.com/NotAShelf/neovim-flake/blob/main/lib/stdlib-extended.nix).
|