Merge pull request #9770 from hercules-ci/refactor-rename-derivation-isPure

Refactor rename derivation type `isPure`
This commit is contained in:
Robert Hensing 2024-01-27 11:24:20 +01:00 committed by GitHub
commit 40254092dd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 29 additions and 19 deletions

View file

@ -156,6 +156,11 @@
builder can rely on external inputs such as the network or the builder can rely on external inputs such as the network or the
system time) but the Nix model assumes it. system time) but the Nix model assumes it.
- [impure derivation]{#gloss-impure-derivation}
[An experimental feature](#@docroot@/contributing/experimental-features.md#xp-feature-impure-derivations) that allows derivations to be explicitly marked as impure,
so that they are always rebuilt, and their outputs not reused by subsequent calls to realise them.
- [Nix database]{#gloss-nix-database} - [Nix database]{#gloss-nix-database}
An SQlite database to track [reference]s between [store object]s. An SQlite database to track [reference]s between [store object]s.

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?