refactor: Impure derivation type isPure -> isImpure

To quote the method doc:

Non-impure derivations can still behave impurely, to the degree permitted
by the sandbox. Hence why this method isn't `isPure`: impure derivations
are not the negation of pure derivations. Purity can not be ascertained
except by rather heavy tools.
This commit is contained in:
Robert Hensing 2024-01-15 08:17:42 +01:00
parent f1b0304153
commit 49b25ea85c
4 changed files with 24 additions and 19 deletions

View file

@ -223,7 +223,7 @@ void DerivationGoal::haveDerivation()
if (!drv->type().hasKnownOutputPaths()) if (!drv->type().hasKnownOutputPaths())
experimentalFeatureSettings.require(Xp::CaDerivations); experimentalFeatureSettings.require(Xp::CaDerivations);
if (!drv->type().isPure()) { if (drv->type().isImpure()) {
experimentalFeatureSettings.require(Xp::ImpureDerivations); experimentalFeatureSettings.require(Xp::ImpureDerivations);
for (auto & [outputName, output] : drv->outputs) { for (auto & [outputName, output] : drv->outputs) {
@ -304,7 +304,7 @@ void DerivationGoal::outputsSubstitutionTried()
{ {
trace("all outputs substituted (maybe)"); trace("all outputs substituted (maybe)");
assert(drv->type().isPure()); assert(!drv->type().isImpure());
if (nrFailed > 0 && nrFailed > nrNoSubstituters + nrIncompleteClosure && !settings.tryFallback) { if (nrFailed > 0 && nrFailed > nrNoSubstituters + nrIncompleteClosure && !settings.tryFallback) {
done(BuildResult::TransientFailure, {}, done(BuildResult::TransientFailure, {},
@ -397,9 +397,9 @@ void DerivationGoal::gaveUpOnSubstitution()
for (const auto & [inputDrvPath, inputNode] : dynamic_cast<Derivation *>(drv.get())->inputDrvs.map) { for (const auto & [inputDrvPath, inputNode] : dynamic_cast<Derivation *>(drv.get())->inputDrvs.map) {
/* Ensure that pure, non-fixed-output derivations don't /* Ensure that pure, non-fixed-output derivations don't
depend on impure derivations. */ depend on impure derivations. */
if (experimentalFeatureSettings.isEnabled(Xp::ImpureDerivations) && drv->type().isPure() && !drv->type().isFixed()) { if (experimentalFeatureSettings.isEnabled(Xp::ImpureDerivations) && !drv->type().isImpure() && !drv->type().isFixed()) {
auto inputDrv = worker.evalStore.readDerivation(inputDrvPath); auto inputDrv = worker.evalStore.readDerivation(inputDrvPath);
if (!inputDrv.type().isPure()) if (inputDrv.type().isImpure())
throw Error("pure derivation '%s' depends on impure derivation '%s'", throw Error("pure derivation '%s' depends on impure derivation '%s'",
worker.store.printStorePath(drvPath), worker.store.printStorePath(drvPath),
worker.store.printStorePath(inputDrvPath)); worker.store.printStorePath(inputDrvPath));
@ -439,7 +439,7 @@ void DerivationGoal::gaveUpOnSubstitution()
void DerivationGoal::repairClosure() void DerivationGoal::repairClosure()
{ {
assert(drv->type().isPure()); assert(!drv->type().isImpure());
/* If we're repairing, we now know that our own outputs are valid. /* If we're repairing, we now know that our own outputs are valid.
Now check whether the other paths in the outputs closure are Now check whether the other paths in the outputs closure are
@ -1100,7 +1100,7 @@ void DerivationGoal::resolvedFinished()
worker.store.printStorePath(resolvedDrvGoal->drvPath), outputName); worker.store.printStorePath(resolvedDrvGoal->drvPath), outputName);
}(); }();
if (drv->type().isPure()) { if (!drv->type().isImpure()) {
auto newRealisation = realisation; auto newRealisation = realisation;
newRealisation.id = DrvOutput { initialOutput->outputHash, outputName }; newRealisation.id = DrvOutput { initialOutput->outputHash, outputName };
newRealisation.signatures.clear(); newRealisation.signatures.clear();
@ -1395,7 +1395,7 @@ void DerivationGoal::flushLine()
std::map<std::string, std::optional<StorePath>> DerivationGoal::queryPartialDerivationOutputMap() std::map<std::string, std::optional<StorePath>> DerivationGoal::queryPartialDerivationOutputMap()
{ {
assert(drv->type().isPure()); assert(!drv->type().isImpure());
if (!useDerivation || drv->type().hasKnownOutputPaths()) { if (!useDerivation || drv->type().hasKnownOutputPaths()) {
std::map<std::string, std::optional<StorePath>> res; std::map<std::string, std::optional<StorePath>> res;
for (auto & [name, output] : drv->outputs) for (auto & [name, output] : drv->outputs)
@ -1411,7 +1411,7 @@ std::map<std::string, std::optional<StorePath>> DerivationGoal::queryPartialDeri
OutputPathMap DerivationGoal::queryDerivationOutputMap() OutputPathMap DerivationGoal::queryDerivationOutputMap()
{ {
assert(drv->type().isPure()); assert(!drv->type().isImpure());
if (!useDerivation || drv->type().hasKnownOutputPaths()) { if (!useDerivation || drv->type().hasKnownOutputPaths()) {
OutputPathMap res; OutputPathMap res;
for (auto & [name, output] : drv->outputsAndOptPaths(worker.store)) for (auto & [name, output] : drv->outputsAndOptPaths(worker.store))
@ -1428,7 +1428,7 @@ OutputPathMap DerivationGoal::queryDerivationOutputMap()
std::pair<bool, SingleDrvOutputs> DerivationGoal::checkPathValidity() std::pair<bool, SingleDrvOutputs> DerivationGoal::checkPathValidity()
{ {
if (!drv->type().isPure()) return { false, {} }; if (drv->type().isImpure()) return { false, {} };
bool checkHash = buildMode == bmRepair; bool checkHash = buildMode == bmRepair;
auto wantedOutputsLeft = std::visit(overloaded { auto wantedOutputsLeft = std::visit(overloaded {

View file

@ -2724,7 +2724,7 @@ SingleDrvOutputs LocalDerivationGoal::registerOutputs()
.outPath = newInfo.path .outPath = newInfo.path
}; };
if (experimentalFeatureSettings.isEnabled(Xp::CaDerivations) if (experimentalFeatureSettings.isEnabled(Xp::CaDerivations)
&& drv->type().isPure()) && !drv->type().isImpure())
{ {
signRealisation(thisRealisation); signRealisation(thisRealisation);
worker.store.registerDrvOutput(thisRealisation); worker.store.registerDrvOutput(thisRealisation);

View file

@ -110,17 +110,17 @@ bool DerivationType::isSandboxed() const
} }
bool DerivationType::isPure() const bool DerivationType::isImpure() const
{ {
return std::visit(overloaded { return std::visit(overloaded {
[](const InputAddressed & ia) { [](const InputAddressed & ia) {
return true; return false;
}, },
[](const ContentAddressed & ca) { [](const ContentAddressed & ca) {
return true; return false;
}, },
[](const Impure &) { [](const Impure &) {
return false; return true;
}, },
}, raw); }, raw);
} }
@ -840,7 +840,7 @@ DrvHash hashDerivationModulo(Store & store, const Derivation & drv, bool maskOut
}; };
} }
if (!type.isPure()) { if (type.isImpure()) {
std::map<std::string, Hash> outputHashes; std::map<std::string, Hash> outputHashes;
for (const auto & [outputName, _] : drv.outputs) for (const auto & [outputName, _] : drv.outputs)
outputHashes.insert_or_assign(outputName, impureOutputHash); outputHashes.insert_or_assign(outputName, impureOutputHash);

View file

@ -253,12 +253,17 @@ struct DerivationType {
bool isSandboxed() const; bool isSandboxed() const;
/** /**
* Whether the derivation is expected to produce the same result * Whether the derivation is expected to produce a different result
* every time, and therefore it only needs to be built once. This is * every time, and therefore it needs to be rebuilt every time. This is
* only false for derivations that have the attribute '__impure = * only true for derivations that have the attribute '__impure =
* true'. * true'.
*
* Non-impure derivations can still behave impurely, to the degree permitted
* by the sandbox. Hence why this method isn't `isPure`: impure derivations
* are not the negation of pure derivations. Purity can not be ascertained
* except by rather heavy tools.
*/ */
bool isPure() const; bool isImpure() const;
/** /**
* Does the derivation knows its own output paths? * Does the derivation knows its own output paths?