FAQ/Pinning Nixpkgs: Difference between revisions

imported>Grahamc
First load, testing newlines.
 
imported>Grahamc
Complete the page on pinning and patching Nixpkgs.
Line 9: Line 9:
host Nixpkgs is using a very stable API, and will be thrown away as
host Nixpkgs is using a very stable API, and will be thrown away as
soon as we are done importing the pinned version of Nixpkgs.
soon as we are done importing the pinned version of Nixpkgs.
Where before you would use <code>pkgs = import <nixpkgs> {}</code>
(which uses the host's Nixpkgs version) you can pin to an exact
version of Nixpkgs by instead using:
<syntaxhighlight lang="nix">
pkgs = let
  hostPkgs = import <nixpkgs> {};
  pinnedPkgs = hostPkgs.fetchFromGitHub {
    owner = "NixOS";
    repo = "nixpkgs-channels";
    # nixos-unstable as of 2017-11-13T08:53:10-00:00
    rev = "ac355040656de04f59406ba2380a96f4124ebdad";
    sha256 = "0frhc7mnx88sird6ipp6578k5badibsl0jfa22ab9w6qrb88j825";
  };
in import pinnedPkgs {};
</syntaxhighlight>
This can also be instead used to pull nixpkgs from an internal fork of
Nixpkgs, with your own changes on top. Note, however, as it stands
Nix 1.11 has difficulties fetching repositories which require
authentication, this is to be fixed in Nix 1.12.
The package <code>nix-prefetch-git</code> can be used to automatically
calculate the current version and hash of a branch, and output the
information to a file:
<syntaxhighlight>
$ nix-shell -p nix-prefetch-git
[nix-shell:~]$ nix-prefetch-git https://github.com/nixos/nixpkgs-channels.git refs/heads/nixos-unstable > nixpkgs-version.json
...
[nix-shell:~]$ cat nixpkgs-version.json
{
  "url": "https://github.com/nixos/nixpkgs-channels.git",
  "rev": "f607771d0f5e4fa905afff1c772febd9f3103e1a",
  "date": "2018-01-09T11:18:25-05:00",
  "sha256": "1icphqpdcl8akqhfij2pxkfr7wfn86z5sr3jdjh88p9vv1550dx7",
  "fetchSubmodules": true
}
</syntaxhighlight>
This file can then be used to specify the version of Nixpkgs:
<syntaxhighlight lang="nix">
pkgs = let
  hostPkgs = import <nixpkgs> {};
  pinnedVersion = hostPkgs.lib.importJSON ./nixpkgs-version.json
  pinnedPkgs = hostPkgs.fetchFromGitHub {
    owner = "NixOS";
    repo = "nixpkgs-channels";
    inherit (pinnedVersion) rev sha256;
  };
in import pinnedPkgs {};
</syntaxhighlight>
Finally, this can be taken a step further, and you can apply extra
patches to the pinned version of Nixpkgs, for perhaps PRs that are not
yet merged, or private internal changes that you need. If you take
this route, probably best to move the following in to its own file
that you then import.
<syntaxhighlight lang="nix">
pkgs = let
  hostPkgs = import <nixpkgs> {};
  pinnedVersion = hostPkgs.lib.importJSON ./nixpkgs-version.json
  pinnedPkgs = hostPkgs.fetchFromGitHub {
    owner = "NixOS";
    repo = "nixpkgs-channels";
    inherit (pinnedVersion) rev sha256;
  };
  patches = [
    ./patches/0001-my-nixpkgs-change.patch
  ];
  patchedPkgs = hostPkgs.runCommand "nixpkgs-${pinnedVersion.rev}"
    {
      inherit pinnedPkgs;
      inherit patches;
    }
    ''
      cp -r $pinnedPkgs $out
      chmod -R +w $out
      for p in $patches; do
        echo "Applying patch $p";
        patch -d $out -p1 < "$p";
      done
    '';
in import patchedPkgs {};
</syntaxhighlight>