Let’s use the following sample flake:
{
inputs = {
systems.url = "github:nix-systems/default";
nixpkgs.url = "nixpkgs/nixos-unstable";
};
outputs = inputs:
let
eachSystem = f:
let
supportedSystems = import inputs.systems;
in
inputs.nixpkgs.lib.genAttrs
supportedSystems
(system:
let
pkgs = (import inputs.nixpkgs) {
inherit system;
overlays = [ inputs.self.overlays.default ];
};
in
f pkgs);
in
{
overlays.default = _: prev: {
check = prev.writeShellApplication {
name = "breaker";
text = "echo 'hello'";
};
};
devShells = eachSystem (pkgs: {
default = pkgs.mkShellNoCC {
name = "test";
packages = [ pkgs.nodePackages.prettier ];
};
});
};
}
In one of my project flakes, which has nodePackages.prettier
in the development shell packages, I added an overlay for check
, which is just a generated script. This was done just like in the example. This would serve as an “alias” of sort in the development shell, where I use it to run nix flake check
at the root of the project. This was inspired by the following from flake.nix
from the-nix-way/dev-templates. This works great, especially because aliases don’t work when entering the shell through direnv
. No issues here.
However, in my project, I noticed that it would cause a massive multi-gigabyte download and rebuild where Nix would build systemd and Python packages, which should have no ties to the development environment. Removing the check
overlay, fixed this, where Nix would source what was expected. Re-introducing the overlay for check
caused the massive rebuilds and downloads again. If allowed to complete, after a few minutes, the environment did behave as intended, with check
correctly being linked to the generated script and PATH
appearing normal.
After some fiddling around, I determined that nodePackages.prettier
was the culprit. Removing it from the shell packages would not produce the massive builds with the check
overlay applied. Re-adding it re-introduced the issue. The example shows the basic needed to reproduce the issue. Either dropping the check
overlay or nodePackages.prettier
from the shell fixes it.
I realise that the overlay itself is not necessary, as the package can just be declared and built separately and added to the development shell packages directly, rather than through an overlay, whereby a “pure” instance of nixpkgs
can be used to source nodePackages.prettier
or anything else. Building the check
script in packages.<system>.check
and adding that to the packages with inputs.self.packages.<system>.check
without the use of overlays, allows both it and nodePackages.prettier
to be added without triggering the massive build.
However, I figured I’d ask here for educational purposes since I spent a few hours trying to figure out what is going on here to no avail. Some insight from those of you that are more experienced as to what causes this would be great. I’m eager to learn. Many thanks.