Flakes: computeLocks: pass correct LockParent when reusing oldLock

Previously, when we were attempting to reuse the old lockfile
information in the computeLocks function, we have passed the parent of
the current input to the next computeLocks call. This was incorrect,
since the follows are resolved relative to the parent. This caused
issues when we tried to reuse oldLock but couldn't for some
reason (read: mustRefetch is true), in that case the follows were
resolved incorrectly.

Fix this by passing the correct parent, and adding some tests to
prevent this particular regression from happening again.

Closes https://github.com/NixOS/nix/issues/5697
This commit is contained in:
Alexander Bantyev 2021-12-02 11:35:50 +03:00
parent f3f32f0c30
commit 8cbf862e6f
No known key found for this signature in database
GPG key ID: E081FF12ADCB4AD5
2 changed files with 18 additions and 1 deletions

View file

@ -480,11 +480,16 @@ LockedFlake lockFlake(
} }
} }
LockParent newParent {
.path = inputPath,
.absolute = false
};
computeLocks( computeLocks(
mustRefetch mustRefetch
? getFlake(state, oldLock->lockedRef, false, flakeCache).inputs ? getFlake(state, oldLock->lockedRef, false, flakeCache).inputs
: fakeInputs, : fakeInputs,
childNode, inputPath, oldLock, parent, parentPath); childNode, inputPath, oldLock, newParent, parentPath);
} else { } else {
/* We need to create a new lock file entry. So fetch /* We need to create a new lock file entry. So fetch

View file

@ -722,6 +722,7 @@ cat > $flakeFollowsB/flake.nix <<EOF
inputs = { inputs = {
foobar.url = "path:$flakeFollowsA/flakeE"; foobar.url = "path:$flakeFollowsA/flakeE";
nonFlake.url = "path:$nonFlakeDir"; nonFlake.url = "path:$nonFlakeDir";
goodoo.follows = "C/goodoo";
C = { C = {
url = "path:./flakeC"; url = "path:./flakeC";
inputs.foobar.follows = "foobar"; inputs.foobar.follows = "foobar";
@ -736,6 +737,7 @@ cat > $flakeFollowsC/flake.nix <<EOF
description = "Flake C"; description = "Flake C";
inputs = { inputs = {
foobar.url = "path:$flakeFollowsA/flakeE"; foobar.url = "path:$flakeFollowsA/flakeE";
goodoo.follows = "foobar";
}; };
outputs = { ... }: {}; outputs = { ... }: {};
} }
@ -760,8 +762,18 @@ EOF
git -C $flakeFollowsA add flake.nix flakeB/flake.nix \ git -C $flakeFollowsA add flake.nix flakeB/flake.nix \
flakeB/flakeC/flake.nix flakeD/flake.nix flakeE/flake.nix flakeB/flakeC/flake.nix flakeD/flake.nix flakeE/flake.nix
nix flake update $flakeFollowsA
oldLock="$(cat "$flakeFollowsA/flake.lock")"
# Ensure that locking twice doesn't change anything
nix flake lock $flakeFollowsA nix flake lock $flakeFollowsA
newLock="$(cat "$flakeFollowsA/flake.lock")"
diff <(echo "$newLock") <(echo "$oldLock")
[[ $(jq -c .nodes.B.inputs.C $flakeFollowsA/flake.lock) = '"C"' ]] [[ $(jq -c .nodes.B.inputs.C $flakeFollowsA/flake.lock) = '"C"' ]]
[[ $(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"]' ]]