Flakes: refetch the input when a follows disappears

When an input follows disappears, we can't just reuse the old lock
file entries since we may be missing some required ones. Refetch the
input when this happens.

Closes https://github.com/NixOS/nix/issues/5289
This commit is contained in:
Alexander Bantyev 2021-11-10 14:56:22 +03:00
parent 52a3b2ee63
commit 07bffe7998
No known key found for this signature in database
GPG key ID: E081FF12ADCB4AD5
2 changed files with 39 additions and 3 deletions

View file

@ -462,6 +462,8 @@ LockedFlake lockFlake(
those. */
FlakeInputs fakeInputs;
bool refetch = false;
for (auto & i : oldLock->inputs) {
if (auto lockedNode = std::get_if<0>(&i.second)) {
fakeInputs.emplace(i.first, FlakeInput {
@ -469,12 +471,24 @@ LockedFlake lockFlake(
.isFlake = (*lockedNode)->isFlake,
});
} else if (auto follows = std::get_if<1>(&i.second)) {
auto o = input.overrides.find(i.first);
// If the override disappeared, we have to refetch the flake,
// since some of the inputs may not be present in the lockfile.
if (o == input.overrides.end()) {
refetch = true;
// There's no point populating the rest of the fake inputs,
// since we'll refetch the flake anyways.
break;
}
fakeInputs.emplace(i.first, FlakeInput {
.follows = *follows,
});
}
}
if (refetch)
fakeInputs = getFlake(state, oldLock->lockedRef, false, flakeCache).inputs;
computeLocks(fakeInputs, childNode, inputPath, oldLock, parent, parentPath);
}

View file

@ -707,10 +707,10 @@ cat > $flakeFollowsA/flake.nix <<EOF
B = {
url = "path:./flakeB";
inputs.foobar.follows = "D";
inputs.nonFlake.follows = "D";
};
D.url = "path:./flakeD";
foobar.url = "path:./flakeE";
};
outputs = { ... }: {};
}
@ -720,7 +720,8 @@ cat > $flakeFollowsB/flake.nix <<EOF
{
description = "Flake B";
inputs = {
foobar.url = "path:./../flakeE";
foobar.url = "path:$flakeFollowsA/flakeE";
nonFlake.url = "path:$nonFlakeDir";
C = {
url = "path:./flakeC";
inputs.foobar.follows = "foobar";
@ -734,7 +735,7 @@ cat > $flakeFollowsC/flake.nix <<EOF
{
description = "Flake C";
inputs = {
foobar.url = "path:./../../flakeE";
foobar.url = "path:$flakeFollowsA/flakeE";
};
outputs = { ... }: {};
}
@ -765,6 +766,27 @@ nix flake lock $flakeFollowsA
[[ $(jq -c .nodes.B.inputs.foobar $flakeFollowsA/flake.lock) = '["D"]' ]]
[[ $(jq -c .nodes.C.inputs.foobar $flakeFollowsA/flake.lock) = '["B","foobar"]' ]]
# Ensure removing follows from flake.nix removes them from the lockfile
cat > $flakeFollowsA/flake.nix <<EOF
{
description = "Flake A";
inputs = {
B = {
url = "path:./flakeB";
inputs.nonFlake.follows = "D";
};
D.url = "path:./flakeD";
};
outputs = { ... }: {};
}
EOF
nix flake lock $flakeFollowsA
[[ $(jq -c .nodes.B.inputs.foobar $flakeFollowsA/flake.lock) = '"foobar"' ]]
jq -r -c '.nodes | keys | .[]' $flakeFollowsA/flake.lock | grep "^foobar$"
# Ensure a relative path is not allowed to go outside the store path
cat > $flakeFollowsA/flake.nix <<EOF
{