@@ -321,16 +321,18 @@ LockedFlake lockFlake(
321
321
const FlakeInputs & flakeInputs,
322
322
std::shared_ptr<Node> node,
323
323
const InputPath & inputPathPrefix,
324
- std::shared_ptr<const Node> oldNode)>
324
+ std::shared_ptr<const Node> oldNode,
325
+ const bool relative, const int relativeDepth)>
325
326
computeLocks;
326
327
327
328
computeLocks = [&](
328
329
const FlakeInputs & flakeInputs,
329
330
std::shared_ptr<Node> node,
330
331
const InputPath & inputPathPrefix,
331
- std::shared_ptr<const Node> oldNode)
332
+ std::shared_ptr<const Node> oldNode,
333
+ const bool relative, const int relativeDepth)
332
334
{
333
- debug (" computing lock file node '%s'" , printInputPath (inputPathPrefix));
335
+ debug (" computing lock file node '%s' (depth %i) " , printInputPath (inputPathPrefix), relativeDepth );
334
336
335
337
/* Get the overrides (i.e. attributes of the form
336
338
'inputs.nixops.inputs.nixpkgs.url = ...'). */
@@ -366,11 +368,20 @@ LockedFlake lockFlake(
366
368
path we haven't processed yet. */
367
369
if (input.follows ) {
368
370
InputPath target;
369
- if (hasOverride || input.absolute )
371
+ if (hasOverride || input.absolute ) {
370
372
/* 'follows' from an override is relative to the
371
- root of the graph. */
372
- target = *input.follows ;
373
- else {
373
+ root of the graph, but we need to fix up the path for subordinate lockfiles */
374
+ if (relative) {
375
+ target = nix::flake::InputPath ();
376
+
377
+ // special case for the root of the subordinate - we need to pop once
378
+ if (!relativeDepth) target.pop_back ();
379
+ for (int i = 0 ; i < relativeDepth; i++) target.pop_back ();
380
+ for (auto & i : *input.follows ) target.push_back (i);
381
+ } else {
382
+ target = *input.follows ;
383
+ }
384
+ } else {
374
385
/* Otherwise, it's relative to the current flake. */
375
386
target = inputPathPrefix;
376
387
for (auto & i : *input.follows ) target.push_back (i);
@@ -420,7 +431,7 @@ LockedFlake lockFlake(
420
431
if (hasChildUpdate) {
421
432
auto inputFlake = getFlake (
422
433
state, oldLock->lockedRef , false , flakeCache);
423
- computeLocks (inputFlake.inputs , childNode, inputPath, oldLock);
434
+ computeLocks (inputFlake.inputs , childNode, inputPath, oldLock, relative, relativeDepth + 1 );
424
435
} else {
425
436
/* No need to fetch this flake, we can be
426
437
lazy. However there may be new overrides on the
@@ -442,7 +453,7 @@ LockedFlake lockFlake(
442
453
}
443
454
}
444
455
445
- computeLocks (fakeInputs, childNode, inputPath, oldLock);
456
+ computeLocks (fakeInputs, childNode, inputPath, oldLock, relative, relativeDepth + 1 );
446
457
}
447
458
448
459
} else {
@@ -484,7 +495,8 @@ LockedFlake lockFlake(
484
495
oldLock
485
496
? std::dynamic_pointer_cast<const Node>(oldLock)
486
497
: LockFile::read (
487
- inputFlake.sourceInfo ->actualPath + " /" + inputFlake.lockedRef .subdir + " /flake.lock" ).root );
498
+ inputFlake.sourceInfo ->actualPath + " /" + inputFlake.lockedRef .subdir + " /flake.lock" ).root ,
499
+ !oldLock, 0 );
488
500
}
489
501
490
502
else {
@@ -504,7 +516,7 @@ LockedFlake lockFlake(
504
516
505
517
computeLocks (
506
518
flake.inputs , newLockFile.root , {},
507
- lockFlags.recreateLockFile ? nullptr : oldLockFile.root );
519
+ lockFlags.recreateLockFile ? nullptr : oldLockFile.root , false , 0 );
508
520
509
521
for (auto & i : lockFlags.inputOverrides )
510
522
if (!overridesUsed.count (i.first ))
0 commit comments