Fix transitive input locking.

Fixes reproducibility issue described in #9143

Fixes #9143
This commit is contained in:
Vladimir Kryachko 2023-10-16 16:51:49 -04:00
parent 201c115c3e
commit a2f0ba6a6d

View file

@ -351,10 +351,13 @@ LockedFlake lockFlake(
debug("old lock file: %s", oldLockFile); debug("old lock file: %s", oldLockFile);
std::map<InputPath, FlakeInput> overrides; std::map<InputPath, FlakeInput> overrides;
std::set<InputPath> explicitCliOverrides;
std::set<InputPath> overridesUsed, updatesUsed; std::set<InputPath> overridesUsed, updatesUsed;
for (auto & i : lockFlags.inputOverrides) for (auto & i : lockFlags.inputOverrides) {
overrides.insert_or_assign(i.first, FlakeInput { .ref = i.second }); overrides.insert_or_assign(i.first, FlakeInput { .ref = i.second });
explicitCliOverrides.insert(i.first);
}
LockFile newLockFile; LockFile newLockFile;
@ -425,6 +428,7 @@ LockedFlake lockFlake(
ancestors? */ ancestors? */
auto i = overrides.find(inputPath); auto i = overrides.find(inputPath);
bool hasOverride = i != overrides.end(); bool hasOverride = i != overrides.end();
bool hasCliOverride = explicitCliOverrides.find(inputPath) != explicitCliOverrides.end();
if (hasOverride) { if (hasOverride) {
overridesUsed.insert(inputPath); overridesUsed.insert(inputPath);
// Respect the “flakeness” of the input even if we // Respect the “flakeness” of the input even if we
@ -460,7 +464,7 @@ LockedFlake lockFlake(
if (oldLock if (oldLock
&& oldLock->originalRef == *input.ref && oldLock->originalRef == *input.ref
&& !hasOverride) && !hasCliOverride)
{ {
debug("keeping existing input '%s'", inputPathS); debug("keeping existing input '%s'", inputPathS);
@ -541,7 +545,7 @@ LockedFlake lockFlake(
nuked the next time we update the lock nuked the next time we update the lock
file. That is, overrides are sticky unless you file. That is, overrides are sticky unless you
use --no-write-lock-file. */ use --no-write-lock-file. */
auto ref = input2.ref ? *input2.ref : *input.ref; auto ref = (input2.ref && explicitCliOverrides.contains(inputPath)) ? *input2.ref : *input.ref;
if (input.isFlake) { if (input.isFlake) {
Path localPath = parentPath; Path localPath = parentPath;