@@ -25,8 +25,7 @@ namespace nix {
25
25
26
26
DerivationGoal::DerivationGoal (const StorePath & drvPath,
27
27
const OutputsSpec & wantedOutputs, Worker & worker, BuildMode buildMode)
28
- : Goal(worker)
29
- , useDerivation(true )
28
+ : Goal(worker, loadDerivation())
30
29
, drvPath(drvPath)
31
30
, wantedOutputs(wantedOutputs)
32
31
, buildMode(buildMode)
@@ -43,8 +42,7 @@ DerivationGoal::DerivationGoal(const StorePath & drvPath,
43
42
44
43
DerivationGoal::DerivationGoal (const StorePath & drvPath, const BasicDerivation & drv,
45
44
const OutputsSpec & wantedOutputs, Worker & worker, BuildMode buildMode)
46
- : Goal(worker)
47
- , useDerivation(false )
45
+ : Goal(worker, haveDerivation())
48
46
, drvPath(drvPath)
49
47
, wantedOutputs(wantedOutputs)
50
48
, buildMode(buildMode)
@@ -143,10 +141,10 @@ void DerivationGoal::addWantedOutputs(const OutputsSpec & outputs)
143
141
}
144
142
145
143
146
- Goal::Co DerivationGoal::init () {
147
- trace (" init " );
144
+ Goal::Co DerivationGoal::loadDerivation () {
145
+ trace (" local derivation " );
148
146
149
- if (useDerivation) {
147
+ {
150
148
/* The first thing to do is to make sure that the derivation
151
149
exists. If it doesn't, it may be created through a
152
150
substitute. */
@@ -355,7 +353,7 @@ Goal::Co DerivationGoal::gaveUpOnSubstitution()
355
353
356
354
std::map<ref<const SingleDerivedPath>, GoalPtr, value_comparison> inputGoals;
357
355
358
- if (useDerivation) {
356
+ {
359
357
std::function<void (ref<const SingleDerivedPath>, const DerivedPathMap<StringSet>::ChildNode &)> addWaiteeDerivedPath;
360
358
361
359
addWaiteeDerivedPath = [&](ref<const SingleDerivedPath> inputDrv, const DerivedPathMap<StringSet>::ChildNode & inputNode) {
@@ -375,7 +373,7 @@ Goal::Co DerivationGoal::gaveUpOnSubstitution()
375
373
childNode);
376
374
};
377
375
378
- for (const auto & [inputDrvPath, inputNode] : dynamic_cast <Derivation *>( drv. get ()) ->inputDrvs .map ) {
376
+ for (const auto & [inputDrvPath, inputNode] : drv->inputDrvs .map ) {
379
377
/* Ensure that pure, non-fixed-output derivations don't
380
378
depend on impure derivations. */
381
379
if (experimentalFeatureSettings.isEnabled (Xp::ImpureDerivations) && !drv->type ().isImpure () && !drv->type ().isFixed ()) {
@@ -417,8 +415,6 @@ Goal::Co DerivationGoal::gaveUpOnSubstitution()
417
415
trace (" all inputs realised" );
418
416
419
417
if (nrFailed != 0 ) {
420
- if (!useDerivation)
421
- throw Error (" some dependencies of '%s' are missing" , worker.store .printStorePath (drvPath));
422
418
auto msg = fmt (
423
419
" Cannot build '%s'.\n "
424
420
" Reason: " ANSI_RED " %d %s failed" ANSI_NORMAL " ." ,
@@ -435,8 +431,8 @@ Goal::Co DerivationGoal::gaveUpOnSubstitution()
435
431
/* Determine the full set of input paths. */
436
432
437
433
/* First, the input derivations. */
438
- if (useDerivation) {
439
- auto & fullDrv = *dynamic_cast <Derivation *>( drv. get ()) ;
434
+ {
435
+ auto & fullDrv = *drv;
440
436
441
437
auto drvType = fullDrv.type ();
442
438
bool resolveDrv = std::visit (overloaded {
@@ -918,7 +914,12 @@ Goal::Co DerivationGoal::repairClosure()
918
914
derivation is responsible for which path in the output
919
915
closure. */
920
916
StorePathSet inputClosure;
921
- if (useDerivation) worker.store .computeFSClosure (drvPath, inputClosure);
917
+
918
+ /* If we're working from an in-memory derivation with no in-store
919
+ `*.drv` file, we cannot do this part. */
920
+ if (worker.store .isValidPath (drvPath))
921
+ worker.store .computeFSClosure (drvPath, inputClosure);
922
+
922
923
std::map<StorePath, StorePath> outputsToDrv;
923
924
for (auto & i : inputClosure)
924
925
if (i.isDerivation ()) {
@@ -1133,7 +1134,9 @@ HookReply DerivationGoal::tryBuildHook()
1133
1134
#ifdef _WIN32 // TODO enable build hook on Windows
1134
1135
return rpDecline;
1135
1136
#else
1136
- if (settings.buildHook .get ().empty () || !worker.tryBuildHook || !useDerivation) return rpDecline;
1137
+ /* This should use `worker.evalStore`, but per #13179 the build hook
1138
+ doesn't work with eval store anyways. */
1139
+ if (settings.buildHook .get ().empty () || !worker.tryBuildHook || !worker.store .isValidPath (drvPath)) return rpDecline;
1137
1140
1138
1141
if (!worker.hook )
1139
1142
worker.hook = std::make_unique<HookInstance>();
@@ -1399,33 +1402,32 @@ void DerivationGoal::flushLine()
1399
1402
std::map<std::string, std::optional<StorePath>> DerivationGoal::queryPartialDerivationOutputMap ()
1400
1403
{
1401
1404
assert (!drv->type ().isImpure ());
1402
- if (!useDerivation || drv-> type (). hasKnownOutputPaths ()) {
1403
- std::map<std::string, std::optional<StorePath>> res;
1404
- for ( auto & [name, output] : drv-> outputs )
1405
- res. insert_or_assign (name, output. path ( worker.store , drv-> name , name) );
1406
- return res;
1407
- } else {
1408
- for ( auto * drvStore : { &worker. evalStore , &worker. store })
1409
- if (drvStore-> isValidPath (drvPath))
1410
- return worker. store . queryPartialDerivationOutputMap (drvPath, drvStore);
1411
- assert ( false );
1412
- }
1405
+
1406
+ for ( auto * drvStore : { &worker. evalStore , &worker. store })
1407
+ if (drvStore-> isValidPath (drvPath) )
1408
+ return worker.store . queryPartialDerivationOutputMap (drvPath, drvStore );
1409
+
1410
+ /* In-memory derivation will naturally fall back on this case, where
1411
+ we do best-effort with static information. */
1412
+ std::map<std::string, std::optional<StorePath>> res;
1413
+ for ( auto & [name, output] : drv-> outputs )
1414
+ res. insert_or_assign (name, output. path (worker. store , drv-> name , name) );
1415
+ return res;
1413
1416
}
1414
1417
1415
1418
OutputPathMap DerivationGoal::queryDerivationOutputMap ()
1416
1419
{
1417
1420
assert (!drv->type ().isImpure ());
1418
- if (!useDerivation || drv->type ().hasKnownOutputPaths ()) {
1419
- OutputPathMap res;
1420
- for (auto & [name, output] : drv->outputsAndOptPaths (worker.store ))
1421
- res.insert_or_assign (name, *output.second );
1422
- return res;
1423
- } else {
1424
- for (auto * drvStore : { &worker.evalStore , &worker.store })
1425
- if (drvStore->isValidPath (drvPath))
1426
- return worker.store .queryDerivationOutputMap (drvPath, drvStore);
1427
- assert (false );
1428
- }
1421
+
1422
+ for (auto * drvStore : { &worker.evalStore , &worker.store })
1423
+ if (drvStore->isValidPath (drvPath))
1424
+ return worker.store .queryDerivationOutputMap (drvPath, drvStore);
1425
+
1426
+ // See comment in `DerivationGoal::queryPartialDerivationOutputMap`.
1427
+ OutputPathMap res;
1428
+ for (auto & [name, output] : drv->outputsAndOptPaths (worker.store ))
1429
+ res.insert_or_assign (name, *output.second );
1430
+ return res;
1429
1431
}
1430
1432
1431
1433
0 commit comments