@@ -317,20 +317,24 @@ LockedFlake lockFlake(
317
317
318
318
std::vector<FlakeRef> parents;
319
319
320
+ // isFlake = whether we are currently inside a subordinate flake
321
+ // inputDepth = inputs deep we are relative to the current root or subordinate flake
320
322
std::function<void (
321
323
const FlakeInputs & flakeInputs,
322
324
std::shared_ptr<Node> node,
323
325
const InputPath & inputPathPrefix,
324
- std::shared_ptr<const Node> oldNode)>
326
+ std::shared_ptr<const Node> oldNode,
327
+ const bool isFlake, const int inputDepth)>
325
328
computeLocks;
326
329
327
330
computeLocks = [&](
328
331
const FlakeInputs & flakeInputs,
329
332
std::shared_ptr<Node> node,
330
333
const InputPath & inputPathPrefix,
331
- std::shared_ptr<const Node> oldNode)
334
+ std::shared_ptr<const Node> oldNode,
335
+ const bool isFlake, const int inputDepth)
332
336
{
333
- debug (" computing lock file node '%s'" , printInputPath (inputPathPrefix));
337
+ debug (" computing lock file node '%s' (depth %i) " , printInputPath (inputPathPrefix), inputDepth );
334
338
335
339
/* Get the overrides (i.e. attributes of the form
336
340
'inputs.nixops.inputs.nixpkgs.url = ...'). */
@@ -371,11 +375,21 @@ LockedFlake lockFlake(
371
375
path we haven't processed yet. */
372
376
if (input.follows ) {
373
377
InputPath target;
374
- if (hasOverride || input.absolute )
378
+ if (hasOverride || input.absolute ) {
375
379
/* '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 {
379
393
/* Otherwise, it's relative to the current flake. */
380
394
target = inputPathPrefix;
381
395
for (auto & i : *input.follows ) target.push_back (i);
@@ -425,7 +439,7 @@ LockedFlake lockFlake(
425
439
if (hasChildUpdate) {
426
440
auto inputFlake = getFlake (
427
441
state, oldLock->lockedRef , false , flakeCache);
428
- computeLocks (inputFlake.inputs , childNode, inputPath, oldLock);
442
+ computeLocks (inputFlake.inputs , childNode, inputPath, oldLock, isFlake, inputDepth + 1 );
429
443
} else {
430
444
/* No need to fetch this flake, we can be
431
445
lazy. However there may be new overrides on the
@@ -447,7 +461,7 @@ LockedFlake lockFlake(
447
461
}
448
462
}
449
463
450
- computeLocks (fakeInputs, childNode, inputPath, oldLock);
464
+ computeLocks (fakeInputs, childNode, inputPath, oldLock, isFlake, inputDepth + 1 );
451
465
}
452
466
453
467
} else {
@@ -489,7 +503,9 @@ LockedFlake lockFlake(
489
503
oldLock
490
504
? std::dynamic_pointer_cast<const Node>(oldLock)
491
505
: 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);
493
509
}
494
510
495
511
else {
@@ -509,7 +525,7 @@ LockedFlake lockFlake(
509
525
510
526
computeLocks (
511
527
flake.inputs , newLockFile.root , {},
512
- lockFlags.recreateLockFile ? nullptr : oldLockFile.root );
528
+ lockFlags.recreateLockFile ? nullptr : oldLockFile.root , false , 0 );
513
529
514
530
for (auto & i : lockFlags.inputOverrides )
515
531
if (!overridesUsed.count (i.first ))
0 commit comments