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:
parent
b6ca60cb82
commit
2324fe3515
1 changed files with 34 additions and 42 deletions
|
|
@ -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};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue