Skip to content

Commit

Permalink
Flakes: refetch the input when a follows disappears
Browse files Browse the repository at this point in the history
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 #5289
  • Loading branch information
balsoft committed Nov 11, 2021
1 parent 52a3b2e commit 07bffe7
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 3 deletions.
14 changes: 14 additions & 0 deletions src/libexpr/flake/flake.cc
Original file line number Diff line number Diff line change
Expand Up @@ -462,19 +462,33 @@ 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 {
.ref = (*lockedNode)->originalRef,
.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);
}

Expand Down
28 changes: 25 additions & 3 deletions tests/flakes.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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 = { ... }: {};
}
Expand All @@ -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";
Expand All @@ -734,7 +735,7 @@ cat > $flakeFollowsC/flake.nix <<EOF
{
description = "Flake C";
inputs = {
foobar.url = "path:./../../flakeE";
foobar.url = "path:$flakeFollowsA/flakeE";
};
outputs = { ... }: {};
}
Expand Down Expand Up @@ -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
{
Expand Down

0 comments on commit 07bffe7

Please sign in to comment.