flake: don't refetch unmodified inputs by recursive follows
Closes #460
I managed to trigger the issue by having the following inputs (shortened):
authentik-nix.url = "github:nix-community/authentik-nix";
authentik-nix.inputs.poetry2nix.inputs.nixpkgs.follows = "nixpkgs";
When evaluating this using
nix-eval-jobs --flake .#hydraJobs
I got the following error:
error: cannot update unlocked flake input 'authentik-nix/poetry2nix' in pure mode
The issue we have here is that `authentik-nix/poetry2nix` was written
into the `overrideMap` which caused Nix to assume it's a new input and
tried to refetch it (#460) or errored out in pure mode
(nix-eval-jobs / Hydra).
The testcase unfortunately only involves checking for the output log
and makes sure that something *is* logged on the first fetch so that
the test doesn't rot when the logging changes since I didn't
manage to trigger the error above with the reproducer from #460. In
fact, I only managed to trigger the `cannot update unlocked flake input`
error in this context with `nix-eval-jobs`.
Change-Id: Ifd00091eec9a0067ed4bb3e5765a15d027328807
This commit is contained in:
parent
e727dbc3a3
commit
040e783232
|
@ -342,8 +342,21 @@ static void updateOverrides(std::map<InputPath, FlakeInput> & overrideMap, const
|
|||
for (auto & [id, input] : overrides) {
|
||||
auto inputPath(inputPathPrefix);
|
||||
inputPath.push_back(id);
|
||||
// Do not override existing assignment from outer flake
|
||||
overrideMap.insert({inputPath, input});
|
||||
|
||||
/* Given
|
||||
*
|
||||
* { inputs.hydra.inputs.nix-eval-jobs.inputs.lix.follows = "lix"; }
|
||||
*
|
||||
* then `nix-eval-jobs` doesn't have an override.
|
||||
* It's neither replaced using follows nor by a different
|
||||
* URL. Thus no need to add it to overrides and thus re-fetch
|
||||
* it.
|
||||
*/
|
||||
if (input.ref || input.follows) {
|
||||
// Do not override existing assignment from outer flake
|
||||
overrideMap.insert({inputPath, input});
|
||||
}
|
||||
|
||||
updateOverrides(overrideMap, input.overrides, inputPath);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -307,3 +307,58 @@ cat <<EOF > $flakeFollowsB/flake.nix
|
|||
EOF
|
||||
|
||||
nix flake update --flake $flakeFollowsA 2>&1 | grepQuiet "warning: input 'B/C' has an override for a non-existent input 'E'"
|
||||
|
||||
# Test for Nested follows cause flake interactions to update the nested input #460
|
||||
for letter in {A..E}; do
|
||||
path="flakeFollows${letter}"
|
||||
rm -f "${!path}"/flake.lock
|
||||
done
|
||||
|
||||
cat <<EOF > $flakeFollowsA/flake.nix
|
||||
{
|
||||
inputs = {
|
||||
B.url = "path:$flakeFollowsB";
|
||||
C = {
|
||||
url = "path:$flakeFollowsC";
|
||||
inputs.D.inputs.E.follows = "B";
|
||||
};
|
||||
};
|
||||
outputs = _: {};
|
||||
}
|
||||
EOF
|
||||
|
||||
cat <<EOF > $flakeFollowsB/flake.nix
|
||||
{
|
||||
outputs = _: {};
|
||||
}
|
||||
EOF
|
||||
|
||||
cat <<EOF > $flakeFollowsC/flake.nix
|
||||
{
|
||||
inputs = {
|
||||
D.url = "path:$flakeFollowsD";
|
||||
};
|
||||
outputs = _: {};
|
||||
}
|
||||
EOF
|
||||
|
||||
cat <<EOF > $flakeFollowsD/flake.nix
|
||||
{
|
||||
inputs = {
|
||||
E.url = "path:$flakeFollowsE";
|
||||
};
|
||||
outputs = _: {};
|
||||
}
|
||||
EOF
|
||||
|
||||
# Lockfiles are cleared, initially the dependency needs to be fetched.
|
||||
out="$(nix --verbose flake show path:$flakeFollowsA 2>&1)"
|
||||
echo "$out"
|
||||
[[ "$out" = *$'\n'"fetching path input 'path:"*"/flakeD'"$'\n'* ]]
|
||||
|
||||
# But on another flake command it doesn't.
|
||||
out="$(nix --verbose flake show path:$flakeFollowsA 2>&1)"
|
||||
[[ "$out" != *$'\n'"fetching path input 'path:"*"/flakeD'"$'\n'* ]]
|
||||
|
||||
# Make sure the nested override is actually correct in this testcase.
|
||||
[[ "$(nix flake metadata path:$flakeFollowsA --json | jq '.locks.nodes.D.inputs.E|.[]' -r)" = "B" ]]
|
||||
|
|
Loading…
Reference in a new issue