From 3aabd3f5a9b04f299e9719b19facaec0ba2a3348 Mon Sep 17 00:00:00 2001 From: fricklerhandwerk Date: Thu, 2 Nov 2023 05:04:48 +0100 Subject: [PATCH] rewrite guide to pinning dependencies with niv --- .../guides/recipes/dependency-management.md | 101 ++++++++++++++++++ source/guides/recipes/index.md | 1 + ...towards-reproducibility-pinning-nixpkgs.md | 46 +------- 3 files changed, 103 insertions(+), 45 deletions(-) create mode 100644 source/guides/recipes/dependency-management.md diff --git a/source/guides/recipes/dependency-management.md b/source/guides/recipes/dependency-management.md new file mode 100644 index 000000000..de36d4775 --- /dev/null +++ b/source/guides/recipes/dependency-management.md @@ -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). diff --git a/source/guides/recipes/index.md b/source/guides/recipes/index.md index 33b9b0de7..ccf16d7b7 100644 --- a/source/guides/recipes/index.md +++ b/source/guides/recipes/index.md @@ -6,5 +6,6 @@ sharing-dependencies.md Automatic environments +dependency-management.md Python development environment <./python-environment.md> ``` diff --git a/source/tutorials/first-steps/towards-reproducibility-pinning-nixpkgs.md b/source/tutorials/first-steps/towards-reproducibility-pinning-nixpkgs.md index 8f5e3769d..7282841c7 100644 --- a/source/tutorials/first-steps/towards-reproducibility-pinning-nixpkgs.md +++ b/source/tutorials/first-steps/towards-reproducibility-pinning-nixpkgs.md @@ -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)