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> |