@@ -317,20 +317,24 @@ LockedFlake lockFlake(
317
317
318
318
std::vector<FlakeRef> parents;
319
319
320
+ // subordinate = 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 subordinate, 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 subordinate, 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 = ...'). */
@@ -366,11 +370,21 @@ LockedFlake lockFlake(
366
370
path we haven't processed yet. */
367
371
if (input.follows ) {
368
372
InputPath target;
369
- if (hasOverride || input.absolute )
373
+ if (hasOverride || input.absolute ) {
370
374
/* '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 {
374
388
/* Otherwise, it's relative to the current flake. */
375
389
target = inputPathPrefix;
376
390
for (auto & i : *input.follows ) target.push_back (i);
@@ -420,7 +434,7 @@ LockedFlake lockFlake(
420
434
if (hasChildUpdate) {
421
435
auto inputFlake = getFlake (
422
436
state, oldLock->lockedRef , false , flakeCache);
423
- computeLocks (inputFlake.inputs , childNode, inputPath, oldLock);
437
+ computeLocks (inputFlake.inputs , childNode, inputPath, oldLock, subordinate, inputDepth + 1 );
424
438
} else {
425
439
/* No need to fetch this flake, we can be
426
440
lazy. However there may be new overrides on the
@@ -442,7 +456,7 @@ LockedFlake lockFlake(
442
456
}
443
457
}
444
458
445
- computeLocks (fakeInputs, childNode, inputPath, oldLock);
459
+ computeLocks (fakeInputs, childNode, inputPath, oldLock, subordinate, inputDepth + 1 );
446
460
}
447
461
448
462
} else {
@@ -484,7 +498,9 @@ LockedFlake lockFlake(
484
498
oldLock
485
499
? std::dynamic_pointer_cast<const Node>(oldLock)
486
500
: 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);
488
504
}
489
505
490
506
else {
@@ -504,7 +520,7 @@ LockedFlake lockFlake(
504
520
505
521
computeLocks (
506
522
flake.inputs , newLockFile.root , {},
507
- lockFlags.recreateLockFile ? nullptr : oldLockFile.root );
523
+ lockFlags.recreateLockFile ? nullptr : oldLockFile.root , false , 0 );
508
524
509
525
for (auto & i : lockFlags.inputOverrides )
510
526
if (!overridesUsed.count (i.first ))
0 commit comments