Skip to content

Commit 20ecf69

Browse files
Fix "follows" paths in subordinate lockfiles
1 parent e700ecb commit 20ecf69

File tree

1 file changed

+27
-11
lines changed

1 file changed

+27
-11
lines changed

src/libexpr/flake/flake.cc

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -317,20 +317,24 @@ LockedFlake lockFlake(
317317

318318
std::vector<FlakeRef> parents;
319319

320+
// isFlake = whether we are currently inside a subordinate flake
321+
// inputDepth = inputs deep we are relative to the current root or subordinate flake
320322
std::function<void(
321323
const FlakeInputs & flakeInputs,
322324
std::shared_ptr<Node> node,
323325
const InputPath & inputPathPrefix,
324-
std::shared_ptr<const Node> oldNode)>
326+
std::shared_ptr<const Node> oldNode,
327+
const bool isFlake, const int inputDepth)>
325328
computeLocks;
326329

327330
computeLocks = [&](
328331
const FlakeInputs & flakeInputs,
329332
std::shared_ptr<Node> node,
330333
const InputPath & inputPathPrefix,
331-
std::shared_ptr<const Node> oldNode)
334+
std::shared_ptr<const Node> oldNode,
335+
const bool isFlake, const int inputDepth)
332336
{
333-
debug("computing lock file node '%s'", printInputPath(inputPathPrefix));
337+
debug("computing lock file node '%s' (depth %i)", printInputPath(inputPathPrefix), inputDepth);
334338

335339
/* Get the overrides (i.e. attributes of the form
336340
'inputs.nixops.inputs.nixpkgs.url = ...'). */
@@ -371,11 +375,21 @@ LockedFlake lockFlake(
371375
path we haven't processed yet. */
372376
if (input.follows) {
373377
InputPath target;
374-
if (hasOverride || input.absolute)
378+
if (hasOverride || input.absolute) {
375379
/* 'follows' from an override is relative to the
376-
root of the graph. */
377-
target = *input.follows;
378-
else {
380+
root of the graph, but we need to fix up the path for subordinate lockfiles */
381+
if (isFlake) {
382+
target = inputPathPrefix;
383+
384+
int subtract = inputDepth;
385+
if (subtract == 0) subtract = 1;
386+
387+
for (int i = 0; i < subtract; i++) target.pop_back();
388+
for (auto & i : *input.follows) target.push_back(i);
389+
} else {
390+
target = *input.follows;
391+
}
392+
} else {
379393
/* Otherwise, it's relative to the current flake. */
380394
target = inputPathPrefix;
381395
for (auto & i : *input.follows) target.push_back(i);
@@ -425,7 +439,7 @@ LockedFlake lockFlake(
425439
if (hasChildUpdate) {
426440
auto inputFlake = getFlake(
427441
state, oldLock->lockedRef, false, flakeCache);
428-
computeLocks(inputFlake.inputs, childNode, inputPath, oldLock);
442+
computeLocks(inputFlake.inputs, childNode, inputPath, oldLock, isFlake, inputDepth + 1);
429443
} else {
430444
/* No need to fetch this flake, we can be
431445
lazy. However there may be new overrides on the
@@ -447,7 +461,7 @@ LockedFlake lockFlake(
447461
}
448462
}
449463

450-
computeLocks(fakeInputs, childNode, inputPath, oldLock);
464+
computeLocks(fakeInputs, childNode, inputPath, oldLock, isFlake, inputDepth + 1);
451465
}
452466

453467
} else {
@@ -489,7 +503,9 @@ LockedFlake lockFlake(
489503
oldLock
490504
? std::dynamic_pointer_cast<const Node>(oldLock)
491505
: LockFile::read(
492-
inputFlake.sourceInfo->actualPath + "/" + inputFlake.lockedRef.subdir + "/flake.lock").root);
506+
inputFlake.sourceInfo->actualPath + "/" + inputFlake.lockedRef.subdir + "/flake.lock").root,
507+
// Increment input depth if we're entering a non-lockfile flake
508+
true, oldLock ? inputDepth + 1 : inputDepth);
493509
}
494510

495511
else {
@@ -509,7 +525,7 @@ LockedFlake lockFlake(
509525

510526
computeLocks(
511527
flake.inputs, newLockFile.root, {},
512-
lockFlags.recreateLockFile ? nullptr : oldLockFile.root);
528+
lockFlags.recreateLockFile ? nullptr : oldLockFile.root, false, 0);
513529

514530
for (auto & i : lockFlags.inputOverrides)
515531
if (!overridesUsed.count(i.first))

0 commit comments

Comments
 (0)