This is happening because of 2 things:
filterSource
uses the name of the directory the filter is applied to as the store path name (the part after the hash) for the one it creates. It is not possible to specify the name yourself usingfilterSource
.- Nix moves all the files tracked by the version control inside the
self
repository (i.e. directory the flake belongs to) to the Nix store. This happens even before the evaluation of the flake starts. So the flake evaluates inside a directory named<hash>-source
in the Nix store, where<hash>
depends on all the files tracked by the versions control.
During the evaluation, filterSource
will create a directory named <hash2>-<hash>-source
that includes the files that passed the filter you specified. Since <hash2>
also depends on <hash>-source
, we get different hashes even if the change is in a file that didn’t pass the filter.
I think this means builtins.filterSource
is useless inside a flake.
Using builtins.path
, which allows specifying the store path name, like below should fix the problem.
src = builtins.path {
path = ./.;
name = "sile";
filter = path: type:
let
ignoreFiles = [
# Nix files
"flake.nix"
"flake.lock"
"default.nix"
"shell.nix"
# git commit and editing format files
".commitlintrc.yml"
"package.json"
".husky"
".editorconfig"
# CI files
".cirrus.yml"
"action.yml"
"azure-pipelines.yml"
"Dockerfile"
# Git files
".github"
".gitattributes"
".gitignore"
".git"
];
in
# If the `path` checked is found in ignoreFiles, don't add it to the source
if pkgs.lib.lists.any (p: p == (baseNameOf path)) ignoreFiles then
false
else
true
;
};
Also I suggest nix-filter rather than creating the filtering boilerplate yourself in every project.
correction
I realized my previous answer was not entirely correct. It included this paragraph:
Source directories without an explicit name are not reproducible. The default name uses the
basename
of the current directory. Without flakes, this doesn’t change as long as you don’t rename the project directory. So it might be harder for you to discover the reproducibility issue without flakes. Also see Best practices — nix.dev documentation
The mentioned impurity is only valid for non-flake evaluations, because flake uses source
as the store path name, regardless of the directory name. So saying it might be harder to discover without flakes was wrong.