Skip to content

Commit 01207fd

Browse files
committed
Remove useDerivation
Try to make `DerivationGoal` care less whether we're working from an in-memory derivation or not. It's a clean-up in its own right, but it will also help with other cleanups under the umbrella of NixOS#12628.
1 parent c1085ce commit 01207fd

2 files changed

Lines changed: 40 additions & 43 deletions

File tree

src/libstore/build/derivation-goal.cc

Lines changed: 39 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@ namespace nix {
2525

2626
DerivationGoal::DerivationGoal(const StorePath & drvPath,
2727
const OutputsSpec & wantedOutputs, Worker & worker, BuildMode buildMode)
28-
: Goal(worker, init())
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

4443
DerivationGoal::DerivationGoal(const StorePath & drvPath, const BasicDerivation & drv,
4544
const OutputsSpec & wantedOutputs, Worker & worker, BuildMode buildMode)
46-
: Goal(worker, init())
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()
13991402
std::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

14151418
OutputPathMap 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

src/libstore/include/nix/store/build/derivation-goal.hh

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,6 @@ void runPostBuildHook(
3333
*/
3434
struct DerivationGoal : public Goal
3535
{
36-
/**
37-
* Whether to use an on-disk .drv file.
38-
*/
39-
bool useDerivation;
40-
4136
/** The path of the derivation. */
4237
StorePath drvPath;
4338

@@ -166,7 +161,7 @@ struct DerivationGoal : public Goal
166161
/**
167162
* The states.
168163
*/
169-
Co init();
164+
Co loadDerivation();
170165
Co haveDerivation();
171166
Co gaveUpOnSubstitution();
172167
Co tryToBuild();

0 commit comments

Comments
 (0)