@@ -25,8 +25,7 @@ namespace nix {
2525
2626DerivationGoal::DerivationGoal (const StorePath & drvPath,
2727 const OutputsSpec & wantedOutputs, Worker & worker, BuildMode buildMode)
28- : Goal(worker)
29- , useDerivation(true )
28+ : Goal(worker, loadDerivation())
3029 , drvPath(drvPath)
3130 , wantedOutputs(wantedOutputs)
3231 , buildMode(buildMode)
@@ -43,8 +42,7 @@ DerivationGoal::DerivationGoal(const StorePath & drvPath,
4342
4443DerivationGoal::DerivationGoal (const StorePath & drvPath, const BasicDerivation & drv,
4544 const OutputsSpec & wantedOutputs, Worker & worker, BuildMode buildMode)
46- : Goal(worker)
47- , useDerivation(false )
45+ : Goal(worker, haveDerivation())
4846 , drvPath(drvPath)
4947 , wantedOutputs(wantedOutputs)
5048 , buildMode(buildMode)
@@ -143,10 +141,10 @@ void DerivationGoal::addWantedOutputs(const OutputsSpec & outputs)
143141}
144142
145143
146- Goal::Co DerivationGoal::init () {
147- trace (" init " );
144+ Goal::Co DerivationGoal::loadDerivation () {
145+ trace (" local derivation " );
148146
149- if (useDerivation) {
147+ {
150148 /* The first thing to do is to make sure that the derivation
151149 exists. If it doesn't, it may be created through a
152150 substitute. */
@@ -355,7 +353,7 @@ Goal::Co DerivationGoal::gaveUpOnSubstitution()
355353
356354 std::map<ref<const SingleDerivedPath>, GoalPtr, value_comparison> inputGoals;
357355
358- if (useDerivation) {
356+ {
359357 std::function<void (ref<const SingleDerivedPath>, const DerivedPathMap<StringSet>::ChildNode &)> addWaiteeDerivedPath;
360358
361359 addWaiteeDerivedPath = [&](ref<const SingleDerivedPath> inputDrv, const DerivedPathMap<StringSet>::ChildNode & inputNode) {
@@ -375,7 +373,7 @@ Goal::Co DerivationGoal::gaveUpOnSubstitution()
375373 childNode);
376374 };
377375
378- for (const auto & [inputDrvPath, inputNode] : dynamic_cast <Derivation *>( drv. get ()) ->inputDrvs .map ) {
376+ for (const auto & [inputDrvPath, inputNode] : drv->inputDrvs .map ) {
379377 /* Ensure that pure, non-fixed-output derivations don't
380378 depend on impure derivations. */
381379 if (experimentalFeatureSettings.isEnabled (Xp::ImpureDerivations) && !drv->type ().isImpure () && !drv->type ().isFixed ()) {
@@ -417,8 +415,6 @@ Goal::Co DerivationGoal::gaveUpOnSubstitution()
417415 trace (" all inputs realised" );
418416
419417 if (nrFailed != 0 ) {
420- if (!useDerivation)
421- throw Error (" some dependencies of '%s' are missing" , worker.store .printStorePath (drvPath));
422418 auto msg = fmt (
423419 " Cannot build '%s'.\n "
424420 " Reason: " ANSI_RED " %d %s failed" ANSI_NORMAL " ." ,
@@ -435,8 +431,8 @@ Goal::Co DerivationGoal::gaveUpOnSubstitution()
435431 /* Determine the full set of input paths. */
436432
437433 /* First, the input derivations. */
438- if (useDerivation) {
439- auto & fullDrv = *dynamic_cast <Derivation *>( drv. get ()) ;
434+ {
435+ auto & fullDrv = *drv;
440436
441437 auto drvType = fullDrv.type ();
442438 bool resolveDrv = std::visit (overloaded {
@@ -918,7 +914,12 @@ Goal::Co DerivationGoal::repairClosure()
918914 derivation is responsible for which path in the output
919915 closure. */
920916 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+
922923 std::map<StorePath, StorePath> outputsToDrv;
923924 for (auto & i : inputClosure)
924925 if (i.isDerivation ()) {
@@ -1133,7 +1134,9 @@ HookReply DerivationGoal::tryBuildHook()
11331134#ifdef _WIN32 // TODO enable build hook on Windows
11341135 return rpDecline;
11351136#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;
11371140
11381141 if (!worker.hook )
11391142 worker.hook = std::make_unique<HookInstance>();
@@ -1399,33 +1402,32 @@ void DerivationGoal::flushLine()
13991402std::map<std::string, std::optional<StorePath>> DerivationGoal::queryPartialDerivationOutputMap ()
14001403{
14011404 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;
14131416}
14141417
14151418OutputPathMap DerivationGoal::queryDerivationOutputMap ()
14161419{
14171420 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;
14291431}
14301432
14311433
0 commit comments