Skip to content

Commit

Permalink
rewrite guide to pinning dependencies with niv
Browse files Browse the repository at this point in the history
  • Loading branch information
fricklerhandwerk committed Nov 2, 2023
1 parent 5c0ac8a commit 3aabd3f
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 45 deletions.
101 changes: 101 additions & 0 deletions source/guides/recipes/dependency-management.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
(dependency-management-niv)=
# Managing remote sources with niv

The Nix language can be used to describe dependencies between files managed by Nix.
Nix expressions themselves can depend on remote sources, and there are multiple ways to specify their origin, as shown in [](pinning-nixpkgs).

For more automation around handling remote sources, set up [niv](https://github.com/nmattia/niv/) in your project:

```shell-session
$ nix-shell -p niv --run "niv init"
```

This command will generate `nix/sources.json` in the current directory, which is a lock file for dependencies.
It will also create `nix/sources.nix`, which exposes those dependencies as an attribute set.

:::{note}
By default, `niv init` will add the latest revision of `nixpkgs-unstable` as a source.
If you need the latest revision of a specific branch:

```shell-session
niv init --nixpkgs nixos/nixpkgs --nixpkgs-branch nixos-23.05
```
:::

Import the generated `nix/sources.nix` for the top-level argument in the top-level `default.nix` and use it to refer to the Nixpkgs source directory:

```nix
{ sources ? import ./nix/sources.nix }:
let
pkgs = import sources.nixpkgs {};
build = pkgs.hello;
in {
inherit build;
}
```

`nix-build` will call the top-level function with the default argument.
This pattern allows [overriding remote sources](overriding-sources-niv) programmatically.

Add niv to the development environment for your project to have it readily available:

```diff
{ sources ? import ./nix/sources.nix }:
let
pkgs = import sources.nixpkgs {};
build = pkgs.hello;
in {
inherit build;
+ shell = pkgs.mkShell {
+ inputsFrom = [ build ];
+ packages = with pkgs; [
+ niv
+ ];
+ };
}
```

See [](./sharing-dependencies) for details.

(overriding-sources-niv)=
## Overriding sources

As an example, we will use the previously created expression with an older version of Nixpkgs.

Create a new directory and set up niv with a different version of Nixpkgs:

```shell-session
mkdir old
cd old
niv init --nixpkgs nixos/nixpkgs --nixpkgs-branch 18.09
```

Create a file `default.nix` in the new directory, and import the original one with the `sources` just created.

```nix
import ../default.nix { sources = import ./nix/sources.nix; }
```

This will result in a different version being built:

```shell-session
$ nix-build -A build
$ ./result/bin/hello --version | head -1
hello (GNU Hello) 2.10
```

Sources can also be overridden on the command line:

```shell-session
nix-build .. -A build --arg sources 'import ./nix/sources.nix'
```

Check the built-in help for details:

```shell-session
niv --help
```

## Next steps

- For more details and examples of the different ways to specify remote sources, see [](pinning-nixpkgs).
1 change: 1 addition & 0 deletions source/guides/recipes/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
sharing-dependencies.md
Automatic environments <direnv>
dependency-management.md
Python development environment <./python-environment.md>
```
Original file line number Diff line number Diff line change
Expand Up @@ -36,51 +36,7 @@ When choosing a commit, it is recommended to follow either
- the **latest stable NixOS** release by using a specific version, such as `nixos-21.05`, **or**
- the latest **unstable release** via `nixos-unstable`.

## Dependency management with niv

If you'd like a bit more automation around bumping dependencies, including Nixpkgs,
[niv](https://github.com/nmattia/niv/) is made for exactly that. Niv itself is available
in `nixpkgs` so using it is simple:

```shell-session
$ nix-shell -p niv --run "niv init"
```

This command will generate `nix/sources.json` with information about how and where
dependencies are fetched. It will also create `nix/sources.nix`, which glues the sources together in Nix.

By default, `niv` will use the **latest stable** NixOS release. However, you should check to see which version is currently specified in [the niv repository](https://github.com/nmattia/niv) if you require a specific release, as it might lag behind.

You can see which version `niv` is tracking as follows:

```shell-session
$ niv show
```

And you can change the tracking branch to the one you want like this:

```shell-session
$ niv modify nixpkgs --branch nixos-21.05
```

You can use the generated `nix/sources.nix` with a top-level `default.nix`:

```nix
{ sources ? import ./nix/sources.nix
, pkgs ? import sources.nixpkgs {}
}:
...
```

And you can update all the dependencies by running:

```shell-session
$ nix-shell -p niv --run "niv update"
```

## Next steps

- For more examples and details of the different ways to pin `nixpkgs`, see {ref}`ref-pinning-nixpkgs`.
- To quickly set up a Nix project, read through
[Getting started Nix template](https://github.com/nix-dot-dev/getting-started-nix-template).
- [](dependency-management-niv)

0 comments on commit 3aabd3f

Please sign in to comment.