diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2022-01-03 20:51:58 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-03 20:51:58 +0100 |
commit | 96d08fcd66e2c38598bab4f39a37a98d58347467 (patch) | |
tree | 9d5de878c6c36cff30220498ae909bba1e9dad6f | |
parent | 70dfcbbb37c114550fe1228748d30fd60520fe10 (diff) | |
parent | 2664a216e57169ec57d7f51be1b8383c1be83fd5 (diff) |
Merge pull request #5839 from tweag/balsoft/yet-another-follows-bugfix
flake.cc: computeLocks: Only verify overrides when they could change
-rw-r--r-- | src/libexpr/flake/flake.cc | 36 | ||||
-rw-r--r-- | tests/flakes.sh | 10 |
2 files changed, 25 insertions, 21 deletions
diff --git a/src/libexpr/flake/flake.cc b/src/libexpr/flake/flake.cc index b15878d5c..c549c5971 100644 --- a/src/libexpr/flake/flake.cc +++ b/src/libexpr/flake/flake.cc @@ -344,7 +344,8 @@ LockedFlake lockFlake( const InputPath & inputPathPrefix, std::shared_ptr<const Node> oldNode, const LockParent & parent, - const Path & parentPath)> + const Path & parentPath, + bool trustLock)> computeLocks; computeLocks = [&]( @@ -353,7 +354,8 @@ LockedFlake lockFlake( const InputPath & inputPathPrefix, std::shared_ptr<const Node> oldNode, const LockParent & parent, - const Path & parentPath) + const Path & parentPath, + bool trustLock) { debug("computing lock file node '%s'", printInputPath(inputPathPrefix)); @@ -464,14 +466,20 @@ 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()) { - mustRefetch = true; - // There's no point populating the rest of the fake inputs, - // since we'll refetch the flake anyways. - break; + if (! trustLock) { + // It is possible that the flake has changed, + // so we must confirm all the follows that are in the lockfile are also in the flake. + auto overridePath(inputPath); + overridePath.push_back(i.first); + auto o = overrides.find(overridePath); + // If the override disappeared, we have to refetch the flake, + // since some of the inputs may not be present in the lockfile. + if (o == overrides.end()) { + mustRefetch = 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, @@ -482,14 +490,14 @@ LockedFlake lockFlake( LockParent newParent { .path = inputPath, - .absolute = false + .absolute = true }; computeLocks( mustRefetch ? getFlake(state, oldLock->lockedRef, false, flakeCache).inputs : fakeInputs, - childNode, inputPath, oldLock, newParent, parentPath); + childNode, inputPath, oldLock, newParent, parentPath, !mustRefetch); } else { /* We need to create a new lock file entry. So fetch @@ -546,7 +554,7 @@ LockedFlake lockFlake( ? std::dynamic_pointer_cast<const Node>(oldLock) : LockFile::read( inputFlake.sourceInfo->actualPath + "/" + inputFlake.lockedRef.subdir + "/flake.lock").root, - newParent, localPath); + newParent, localPath, false); } else { @@ -574,7 +582,7 @@ LockedFlake lockFlake( computeLocks( flake.inputs, newLockFile.root, {}, - lockFlags.recreateLockFile ? nullptr : oldLockFile.root, parent, parentPath); + lockFlags.recreateLockFile ? nullptr : oldLockFile.root, parent, parentPath, false); for (auto & i : lockFlags.inputOverrides) if (!overridesUsed.count(i.first)) diff --git a/tests/flakes.sh b/tests/flakes.sh index 942d07010..20e6d09c1 100644 --- a/tests/flakes.sh +++ b/tests/flakes.sh @@ -716,11 +716,10 @@ cat > $flakeFollowsA/flake.nix <<EOF inputs = { B = { url = "path:./flakeB"; - inputs.foobar.follows = "D"; - inputs.nonFlake.follows = "D"; + inputs.foobar.follows = "foobar"; }; - D.url = "path:./flakeD"; + foobar.url = "path:$flakeFollowsA/flakeE"; }; outputs = { ... }: {}; } @@ -731,8 +730,6 @@ cat > $flakeFollowsB/flake.nix <<EOF description = "Flake B"; inputs = { foobar.url = "path:$flakeFollowsA/flakeE"; - nonFlake.url = "path:$nonFlakeDir"; - goodoo.follows = "C/goodoo"; C = { url = "path:./flakeC"; inputs.foobar.follows = "foobar"; @@ -747,7 +744,6 @@ cat > $flakeFollowsC/flake.nix <<EOF description = "Flake C"; inputs = { foobar.url = "path:$flakeFollowsA/flakeE"; - goodoo.follows = "foobar"; }; outputs = { ... }: {}; } @@ -785,7 +781,7 @@ 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.foobar $flakeFollowsA/flake.lock) = '["D"]' ]] +[[ $(jq -c .nodes.B.inputs.foobar $flakeFollowsA/flake.lock) = '["foobar"]' ]] [[ $(jq -c .nodes.C.inputs.foobar $flakeFollowsA/flake.lock) = '["B","foobar"]' ]] # Ensure removing follows from flake.nix removes them from the lockfile |