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:
parent
52a3b2ee63
commit
07bffe7998
2 changed files with 39 additions and 3 deletions
|
@ -462,6 +462,8 @@ LockedFlake lockFlake(
|
||||||
those. */
|
those. */
|
||||||
FlakeInputs fakeInputs;
|
FlakeInputs fakeInputs;
|
||||||
|
|
||||||
|
bool refetch = false;
|
||||||
|
|
||||||
for (auto & i : oldLock->inputs) {
|
for (auto & i : oldLock->inputs) {
|
||||||
if (auto lockedNode = std::get_if<0>(&i.second)) {
|
if (auto lockedNode = std::get_if<0>(&i.second)) {
|
||||||
fakeInputs.emplace(i.first, FlakeInput {
|
fakeInputs.emplace(i.first, FlakeInput {
|
||||||
|
@ -469,12 +471,24 @@ LockedFlake lockFlake(
|
||||||
.isFlake = (*lockedNode)->isFlake,
|
.isFlake = (*lockedNode)->isFlake,
|
||||||
});
|
});
|
||||||
} else if (auto follows = std::get_if<1>(&i.second)) {
|
} 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 {
|
fakeInputs.emplace(i.first, FlakeInput {
|
||||||
.follows = *follows,
|
.follows = *follows,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (refetch)
|
||||||
|
fakeInputs = getFlake(state, oldLock->lockedRef, false, flakeCache).inputs;
|
||||||
|
|
||||||
computeLocks(fakeInputs, childNode, inputPath, oldLock, parent, parentPath);
|
computeLocks(fakeInputs, childNode, inputPath, oldLock, parent, parentPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -707,10 +707,10 @@ cat > $flakeFollowsA/flake.nix <<EOF
|
||||||
B = {
|
B = {
|
||||||
url = "path:./flakeB";
|
url = "path:./flakeB";
|
||||||
inputs.foobar.follows = "D";
|
inputs.foobar.follows = "D";
|
||||||
|
inputs.nonFlake.follows = "D";
|
||||||
};
|
};
|
||||||
|
|
||||||
D.url = "path:./flakeD";
|
D.url = "path:./flakeD";
|
||||||
foobar.url = "path:./flakeE";
|
|
||||||
};
|
};
|
||||||
outputs = { ... }: {};
|
outputs = { ... }: {};
|
||||||
}
|
}
|
||||||
|
@ -720,7 +720,8 @@ cat > $flakeFollowsB/flake.nix <<EOF
|
||||||
{
|
{
|
||||||
description = "Flake B";
|
description = "Flake B";
|
||||||
inputs = {
|
inputs = {
|
||||||
foobar.url = "path:./../flakeE";
|
foobar.url = "path:$flakeFollowsA/flakeE";
|
||||||
|
nonFlake.url = "path:$nonFlakeDir";
|
||||||
C = {
|
C = {
|
||||||
url = "path:./flakeC";
|
url = "path:./flakeC";
|
||||||
inputs.foobar.follows = "foobar";
|
inputs.foobar.follows = "foobar";
|
||||||
|
@ -734,7 +735,7 @@ cat > $flakeFollowsC/flake.nix <<EOF
|
||||||
{
|
{
|
||||||
description = "Flake C";
|
description = "Flake C";
|
||||||
inputs = {
|
inputs = {
|
||||||
foobar.url = "path:./../../flakeE";
|
foobar.url = "path:$flakeFollowsA/flakeE";
|
||||||
};
|
};
|
||||||
outputs = { ... }: {};
|
outputs = { ... }: {};
|
||||||
}
|
}
|
||||||
|
@ -765,6 +766,27 @@ nix flake lock $flakeFollowsA
|
||||||
[[ $(jq -c .nodes.B.inputs.foobar $flakeFollowsA/flake.lock) = '["D"]' ]]
|
[[ $(jq -c .nodes.B.inputs.foobar $flakeFollowsA/flake.lock) = '["D"]' ]]
|
||||||
[[ $(jq -c .nodes.C.inputs.foobar $flakeFollowsA/flake.lock) = '["B","foobar"]' ]]
|
[[ $(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
|
# Ensure a relative path is not allowed to go outside the store path
|
||||||
cat > $flakeFollowsA/flake.nix <<EOF
|
cat > $flakeFollowsA/flake.nix <<EOF
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue