aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Bantyev <balsoft@balsoft.ru>2021-11-10 14:56:22 +0300
committerAlexander Bantyev <balsoft@balsoft.ru>2021-11-11 12:05:18 +0300
commit07bffe799853ef5e2757b9892e4e3dac89bfccbb (patch)
treedd018691cea9213888a7e45438f6c350bba95920
parent52a3b2ee6367306a3f17fe9a2d0e2e4096852e05 (diff)
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
-rw-r--r--src/libexpr/flake/flake.cc14
-rw-r--r--tests/flakes.sh28
2 files changed, 39 insertions, 3 deletions
diff --git a/src/libexpr/flake/flake.cc b/src/libexpr/flake/flake.cc
index 07ed3caa2..1dc6f5694 100644
--- a/src/libexpr/flake/flake.cc
+++ b/src/libexpr/flake/flake.cc
@@ -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);
}
diff --git a/tests/flakes.sh b/tests/flakes.sh
index 57d1b9aad..9e10322b9 100644
--- a/tests/flakes.sh
+++ b/tests/flakes.sh
@@ -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
{