1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-15 15:02:42 +01:00

DerivationBuilder::checkPathValidity: Big simplify

`Store::queryPartialDerivationOutputMap` is nothing but checking
statically-known output paths, and then `Store::queryRealisation`, and
we were doing both of those things already. Inline that and simplify,
again taking advantage of the fact that we only care about one output.
This commit is contained in:
John Ericson 2025-08-13 23:19:46 -04:00
parent b6ca60cb82
commit 2324fe3515

View file

@ -308,59 +308,51 @@ std::pair<bool, SingleDrvOutputs> DerivationGoal::checkPathValidity()
if (drv->type().isImpure()) if (drv->type().isImpure())
return {false, {}}; return {false, {}};
bool checkHash = buildMode == bmRepair;
SingleDrvOutputs validOutputs; SingleDrvOutputs validOutputs;
auto partialDerivationOutputMap = [&] { auto drvOutput = DrvOutput{outputHash, wantedOutput};
for (auto * drvStore : {&worker.evalStore, &worker.store})
if (drvStore->isValidPath(drvPath))
return worker.store.queryPartialDerivationOutputMap(drvPath, drvStore);
/* In-memory derivation will naturally fall back on this case, where std::optional<Realisation> mRealisation;
we do best-effort with static information. */
std::map<std::string, std::optional<StorePath>> res;
for (auto & [name, output] : drv->outputs)
res.insert_or_assign(name, output.path(worker.store, drv->name, name));
return res;
}();
if (auto * mpath = get(partialDerivationOutputMap, wantedOutput)) { if (auto * mOutput = get(drv->outputs, wantedOutput)) {
if (*mpath) { if (auto mPath = mOutput->path(worker.store, drv->name, wantedOutput)) {
auto & outputPath = **mpath; mRealisation = Realisation{drvOutput, std::move(*mPath)};
}
} else {
throw Error(
"derivation '%s' does not have wanted outputs '%s'", worker.store.printStorePath(drvPath), wantedOutput);
}
if (experimentalFeatureSettings.isEnabled(Xp::CaDerivations)) {
for (auto * drvStore : {&worker.evalStore, &worker.store}) {
if (auto real = drvStore->queryRealisation(drvOutput)) {
mRealisation = *real;
break;
}
}
}
if (mRealisation) {
auto & outputPath = mRealisation->outPath;
bool checkHash = buildMode == bmRepair;
outputKnown = { outputKnown = {
.path = outputPath, .path = outputPath,
.status = !worker.store.isValidPath(outputPath) ? PathStatus::Absent .status = !worker.store.isValidPath(outputPath) ? PathStatus::Absent
: !checkHash || worker.pathContentsGood(outputPath) ? PathStatus::Valid : !checkHash || worker.pathContentsGood(outputPath) ? PathStatus::Valid
: PathStatus::Corrupt, : PathStatus::Corrupt,
}; };
}
auto drvOutput = DrvOutput{outputHash, wantedOutput}; if (outputKnown->isValid()) {
if (experimentalFeatureSettings.isEnabled(Xp::CaDerivations)) { if (experimentalFeatureSettings.isEnabled(Xp::CaDerivations)) {
if (auto real = worker.store.queryRealisation(drvOutput)) {
outputKnown = {
.path = real->outPath,
.status = PathStatus::Valid,
};
} else if (outputKnown && outputKnown->isValid()) {
// We know the output because it's a static output of the // We know the output because it's a static output of the
// derivation, and the output path is valid, but we don't have // derivation, and the output path is valid, but we don't have
// its realisation stored (probably because it has been built // its realisation stored (probably because it has been built
// without the `ca-derivations` experimental flag). // without the `ca-derivations` experimental flag).
worker.store.registerDrvOutput( worker.store.registerDrvOutput(*mRealisation);
Realisation{
drvOutput,
outputKnown->path,
});
} }
validOutputs.emplace(wantedOutput, *mRealisation);
} }
if (outputKnown && outputKnown->isValid())
validOutputs.emplace(wantedOutput, Realisation{drvOutput, outputKnown->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);
} }
return {outputKnown && outputKnown->isValid(), validOutputs}; return {outputKnown && outputKnown->isValid(), validOutputs};