Skip to content

Commit dea7318

Browse files
Fix "follows" paths in subordinate lockfiles
1 parent 8127094 commit dea7318

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+
// subordinate = 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 subordinate, 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 subordinate, 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 = ...'). */
@@ -366,11 +370,21 @@ LockedFlake lockFlake(
366370
path we haven't processed yet. */
367371
if (input.follows) {
368372
InputPath target;
369-
if (hasOverride || input.absolute)
373+
if (hasOverride || input.absolute) {
370374
/* 'follows' from an override is relative to the
371-
root of the graph. */
372-
target = *input.follows;
373-
else {
375+
root of the graph, but we need to fix up the path for subordinate lockfiles */
376+
if (subordinate) {
377+
target = inputPathPrefix;
378+
379+
int subtract = inputDepth;
380+
if (subtract == 0) subtract = 1;
381+
382+
for (int i = 0; i < subtract; i++) target.pop_back();
383+
for (auto & i : *input.follows) target.push_back(i);
384+
} else {
385+
target = *input.follows;
386+
}
387+
} else {
374388
/* Otherwise, it's relative to the current flake. */
375389
target = inputPathPrefix;
376390
for (auto & i : *input.follows) target.push_back(i);
@@ -420,7 +434,7 @@ LockedFlake lockFlake(
420434
if (hasChildUpdate) {
421435
auto inputFlake = getFlake(
422436
state, oldLock->lockedRef, false, flakeCache);
423-
computeLocks(inputFlake.inputs, childNode, inputPath, oldLock);
437+
computeLocks(inputFlake.inputs, childNode, inputPath, oldLock, subordinate, inputDepth + 1);
424438
} else {
425439
/* No need to fetch this flake, we can be
426440
lazy. However there may be new overrides on the
@@ -442,7 +456,7 @@ LockedFlake lockFlake(
442456
}
443457
}
444458

445-
computeLocks(fakeInputs, childNode, inputPath, oldLock);
459+
computeLocks(fakeInputs, childNode, inputPath, oldLock, subordinate, inputDepth + 1);
446460
}
447461

448462
} else {
@@ -484,7 +498,9 @@ LockedFlake lockFlake(
484498
oldLock
485499
? std::dynamic_pointer_cast<const Node>(oldLock)
486500
: LockFile::read(
487-
inputFlake.sourceInfo->actualPath + "/" + inputFlake.lockedRef.subdir + "/flake.lock").root);
501+
inputFlake.sourceInfo->actualPath + "/" + inputFlake.lockedRef.subdir + "/flake.lock").root,
502+
// Increment input depth if we're entering a non-lockfile flake
503+
!oldLock, oldLock ? inputDepth + 1 : inputDepth);
488504
}
489505

490506
else {
@@ -504,7 +520,7 @@ LockedFlake lockFlake(
504520

505521
computeLocks(
506522
flake.inputs, newLockFile.root, {},
507-
lockFlags.recreateLockFile ? nullptr : oldLockFile.root);
523+
lockFlags.recreateLockFile ? nullptr : oldLockFile.root, false, 0);
508524

509525
for (auto & i : lockFlags.inputOverrides)
510526
if (!overridesUsed.count(i.first))

0 commit comments

Comments
 (0)