If I am prudent then I should precisely pin the version of nixpkgs that each of my projects uses so that if I return to it in a few months then it still builds correctly.
This works well for the first few times, it works well for the first few months but if over the course of a year or ten years I amass 100 or 1000 projects each with their own individual pin then the approach starts to break down.
In each folder I have a pin to a specific version of nixpkgs so in my store I will have potentially 1000 different copies of GHC for each one of my projects. Some of these might be significantly different versions of the compiler but mostly they are “duplicates” where an unimportant dependency has been changed which caused a rebuild. Each of these is a GB so I would require 1TB drive just to store all the versions of GHC for all my projects.
Over the course of 10 years there will only be 20 different versions of GHC so instead I might try to abstract away the pin and maintain a separate pin overlay which contains information about the pins I might want to use for the projects. These attributes are immutable but new ones are added over time. This somewhat solves the problem but now if someone else wants to build the project then I also have to distribute the pin layer.
pins = {
ghc-8.2.2 = fetchFromGitHub { ... };
ghc-8.4.3 = fetchFromGitHub { ... };
}
Possible solutions to this problem:
- Add a compilation step which inlines the pin definition into the
default.nix
file before distributing the package. - Create a set of blessed pins which are distributed with nixpkgs itself. These are immutable and a new one is added once a month.
An advantage to (2) is that if many different people are sharing pins then the amount of rebuilding necessary for pinning projects will be reduced. At the moment if you build at a very old pin you have to rebuild the whole world usually.
Has anyone else considered this problem?