mirror of
https://github.com/NixOS/nix.git
synced 2025-11-17 07:52:43 +01:00
Simplify DerivationGoal by just storing a singular initialOutput
We know we want exactly want output in `DerivationGoal` now (since recent refactors), so we can start simplifying things to take advantage of this.
This commit is contained in:
parent
4b6edfcfc7
commit
14173d761c
2 changed files with 40 additions and 57 deletions
|
|
@ -24,15 +24,16 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
DerivationGoal::DerivationGoal(
|
DerivationGoal::DerivationGoal(const StorePath & drvPath, const Derivation & drv,
|
||||||
const StorePath & drvPath,
|
const OutputName & wantedOutput, Worker & worker, BuildMode buildMode)
|
||||||
const Derivation & drv,
|
|
||||||
const OutputName & wantedOutput,
|
|
||||||
Worker & worker,
|
|
||||||
BuildMode buildMode)
|
|
||||||
: Goal(worker, haveDerivation())
|
: Goal(worker, haveDerivation())
|
||||||
, drvPath(drvPath)
|
, drvPath(drvPath)
|
||||||
, wantedOutput(wantedOutput)
|
, wantedOutput(wantedOutput)
|
||||||
|
, initialOutput{
|
||||||
|
.wanted = true,
|
||||||
|
.outputHash = Hash::dummy, // will be updated
|
||||||
|
.known = {},
|
||||||
|
}
|
||||||
, buildMode(buildMode)
|
, buildMode(buildMode)
|
||||||
{
|
{
|
||||||
this->drv = std::make_unique<Derivation>(drv);
|
this->drv = std::make_unique<Derivation>(drv);
|
||||||
|
|
@ -125,9 +126,10 @@ Goal::Co DerivationGoal::haveDerivation()
|
||||||
|
|
||||||
auto outputHashes = staticOutputHashes(worker.evalStore, *drv);
|
auto outputHashes = staticOutputHashes(worker.evalStore, *drv);
|
||||||
for (auto & [outputName, outputHash] : outputHashes) {
|
for (auto & [outputName, outputHash] : outputHashes) {
|
||||||
InitialOutput v{
|
if (outputName != wantedOutput)
|
||||||
.wanted = true, // Will be refined later
|
continue;
|
||||||
.outputHash = outputHash};
|
|
||||||
|
InitialOutput v{.wanted = true, .outputHash = outputHash};
|
||||||
|
|
||||||
/* TODO we might want to also allow randomizing the paths
|
/* TODO we might want to also allow randomizing the paths
|
||||||
for regular CA derivations, e.g. for sake of checking
|
for regular CA derivations, e.g. for sake of checking
|
||||||
|
|
@ -139,10 +141,8 @@ Goal::Co DerivationGoal::haveDerivation()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
initialOutputs.insert({
|
initialOutput = std::move(v);
|
||||||
outputName,
|
break;
|
||||||
std::move(v),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (impure) {
|
if (impure) {
|
||||||
|
|
@ -167,21 +167,18 @@ Goal::Co DerivationGoal::haveDerivation()
|
||||||
/* We are first going to try to create the invalid output paths
|
/* We are first going to try to create the invalid output paths
|
||||||
through substitutes. If that doesn't work, we'll build
|
through substitutes. If that doesn't work, we'll build
|
||||||
them. */
|
them. */
|
||||||
if (settings.useSubstitutes && drvOptions.substitutesAllowed())
|
if (settings.useSubstitutes && drvOptions.substitutesAllowed()) {
|
||||||
for (auto & [outputName, status] : initialOutputs) {
|
if (!initialOutput.known)
|
||||||
if (!status.wanted)
|
waitees.insert(upcast_goal(worker.makeDrvOutputSubstitutionGoal(
|
||||||
continue;
|
DrvOutput{initialOutput.outputHash, wantedOutput}, buildMode == bmRepair ? Repair : NoRepair)));
|
||||||
if (!status.known)
|
else {
|
||||||
waitees.insert(upcast_goal(worker.makeDrvOutputSubstitutionGoal(
|
auto * cap = getDerivationCA(*drv);
|
||||||
DrvOutput{status.outputHash, outputName}, buildMode == bmRepair ? Repair : NoRepair)));
|
waitees.insert(upcast_goal(worker.makePathSubstitutionGoal(
|
||||||
else {
|
initialOutput.known->path,
|
||||||
auto * cap = getDerivationCA(*drv);
|
buildMode == bmRepair ? Repair : NoRepair,
|
||||||
waitees.insert(upcast_goal(worker.makePathSubstitutionGoal(
|
cap ? std::optional{*cap} : std::nullopt)));
|
||||||
status.known->path,
|
|
||||||
buildMode == bmRepair ? Repair : NoRepair,
|
|
||||||
cap ? std::optional{*cap} : std::nullopt)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
co_await await(std::move(waitees));
|
co_await await(std::move(waitees));
|
||||||
|
|
||||||
|
|
@ -317,7 +314,6 @@ std::pair<bool, SingleDrvOutputs> DerivationGoal::checkPathValidity()
|
||||||
return {false, {}};
|
return {false, {}};
|
||||||
|
|
||||||
bool checkHash = buildMode == bmRepair;
|
bool checkHash = buildMode == bmRepair;
|
||||||
StringSet wantedOutputsLeft{wantedOutput};
|
|
||||||
SingleDrvOutputs validOutputs;
|
SingleDrvOutputs validOutputs;
|
||||||
|
|
||||||
auto partialDerivationOutputMap = [&] {
|
auto partialDerivationOutputMap = [&] {
|
||||||
|
|
@ -333,17 +329,10 @@ std::pair<bool, SingleDrvOutputs> DerivationGoal::checkPathValidity()
|
||||||
return res;
|
return res;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
for (auto & i : partialDerivationOutputMap) {
|
if (auto * mpath = get(partialDerivationOutputMap, wantedOutput)) {
|
||||||
auto initialOutput = get(initialOutputs, i.first);
|
auto & info = initialOutput;
|
||||||
if (!initialOutput)
|
if (*mpath) {
|
||||||
// this is an invalid output, gets caught with (!wantedOutputsLeft.empty())
|
auto & outputPath = **mpath;
|
||||||
continue;
|
|
||||||
auto & info = *initialOutput;
|
|
||||||
info.wanted = wantedOutput == i.first;
|
|
||||||
if (info.wanted)
|
|
||||||
wantedOutputsLeft.erase(i.first);
|
|
||||||
if (i.second) {
|
|
||||||
auto outputPath = *i.second;
|
|
||||||
info.known = {
|
info.known = {
|
||||||
.path = outputPath,
|
.path = outputPath,
|
||||||
.status = !worker.store.isValidPath(outputPath) ? PathStatus::Absent
|
.status = !worker.store.isValidPath(outputPath) ? PathStatus::Absent
|
||||||
|
|
@ -351,7 +340,7 @@ std::pair<bool, SingleDrvOutputs> DerivationGoal::checkPathValidity()
|
||||||
: PathStatus::Corrupt,
|
: PathStatus::Corrupt,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
auto drvOutput = DrvOutput{info.outputHash, i.first};
|
auto drvOutput = DrvOutput{info.outputHash, wantedOutput};
|
||||||
if (experimentalFeatureSettings.isEnabled(Xp::CaDerivations)) {
|
if (experimentalFeatureSettings.isEnabled(Xp::CaDerivations)) {
|
||||||
if (auto real = worker.store.queryRealisation(drvOutput)) {
|
if (auto real = worker.store.queryRealisation(drvOutput)) {
|
||||||
info.known = {
|
info.known = {
|
||||||
|
|
@ -371,25 +360,19 @@ std::pair<bool, SingleDrvOutputs> DerivationGoal::checkPathValidity()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (info.known && info.known->isValid())
|
if (info.known && info.known->isValid())
|
||||||
validOutputs.emplace(i.first, Realisation{drvOutput, info.known->path});
|
validOutputs.emplace(wantedOutput, Realisation{drvOutput, info.known->path});
|
||||||
|
} else {
|
||||||
|
// If we requested all the outputs, we are always fine.
|
||||||
|
// If we requested specific elements, the loop above removes all the valid
|
||||||
|
// ones, so any that are left must be invalid.
|
||||||
|
throw Error(
|
||||||
|
"derivation '%s' does not have wanted outputs '%s'", worker.store.printStorePath(drvPath), wantedOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we requested all the outputs, we are always fine.
|
|
||||||
// If we requested specific elements, the loop above removes all the valid
|
|
||||||
// ones, so any that are left must be invalid.
|
|
||||||
if (!wantedOutputsLeft.empty())
|
|
||||||
throw Error(
|
|
||||||
"derivation '%s' does not have wanted outputs %s",
|
|
||||||
worker.store.printStorePath(drvPath),
|
|
||||||
concatStringsSep(", ", quoteStrings(wantedOutputsLeft)));
|
|
||||||
|
|
||||||
bool allValid = true;
|
bool allValid = true;
|
||||||
for (auto & [_, status] : initialOutputs) {
|
{
|
||||||
if (!status.wanted)
|
if (!initialOutput.known || !initialOutput.known->isValid()) {
|
||||||
continue;
|
|
||||||
if (!status.known || !status.known->isValid()) {
|
|
||||||
allValid = false;
|
allValid = false;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ private:
|
||||||
* The remainder is state held during the build.
|
* The remainder is state held during the build.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
std::map<std::string, InitialOutput> initialOutputs;
|
InitialOutput initialOutput;
|
||||||
|
|
||||||
BuildMode buildMode;
|
BuildMode buildMode;
|
||||||
|
|
||||||
|
|
@ -86,7 +86,7 @@ private:
|
||||||
Co haveDerivation();
|
Co haveDerivation();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update 'initialOutputs' to determine the current status of the
|
* Update 'initialOutput' to determine the current status of the
|
||||||
* outputs of the derivation. Also returns a Boolean denoting
|
* outputs of the derivation. Also returns a Boolean denoting
|
||||||
* whether all outputs are valid and non-corrupt, and a
|
* whether all outputs are valid and non-corrupt, and a
|
||||||
* 'SingleDrvOutputs' structure containing the valid outputs.
|
* 'SingleDrvOutputs' structure containing the valid outputs.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue