Merge pull request #6311 from edolstra/return-wanted-paths

Make buildPathsWithResults() only return info on wanted outputs
This commit is contained in:
Eelco Dolstra 2022-03-25 15:44:39 +01:00 committed by GitHub
commit 16cf1e6089
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 30 additions and 20 deletions

View file

@ -207,8 +207,6 @@ void DerivationGoal::haveDerivation()
if (!drv->type().hasKnownOutputPaths()) if (!drv->type().hasKnownOutputPaths())
settings.requireExperimentalFeature(Xp::CaDerivations); settings.requireExperimentalFeature(Xp::CaDerivations);
retrySubstitution = false;
for (auto & i : drv->outputsAndOptPaths(worker.store)) for (auto & i : drv->outputsAndOptPaths(worker.store))
if (i.second.second) if (i.second.second)
worker.store.addTempRoot(*i.second.second); worker.store.addTempRoot(*i.second.second);
@ -311,14 +309,11 @@ void DerivationGoal::outputsSubstitutionTried()
gaveUpOnSubstitution(); gaveUpOnSubstitution();
} }
/* At least one of the output paths could not be /* At least one of the output paths could not be
produced using a substitute. So we have to build instead. */ produced using a substitute. So we have to build instead. */
void DerivationGoal::gaveUpOnSubstitution() void DerivationGoal::gaveUpOnSubstitution()
{ {
/* Make sure checkPathValidity() from now on checks all
outputs. */
wantedOutputs.clear();
/* The inputs must be built before we can build this goal. */ /* The inputs must be built before we can build this goal. */
if (useDerivation) if (useDerivation)
for (auto & i : dynamic_cast<Derivation *>(drv.get())->inputDrvs) for (auto & i : dynamic_cast<Derivation *>(drv.get())->inputDrvs)
@ -426,7 +421,8 @@ void DerivationGoal::inputsRealised()
return; return;
} }
if (retrySubstitution) { if (retrySubstitution && !retriedSubstitution) {
retriedSubstitution = true;
haveDerivation(); haveDerivation();
return; return;
} }

View file

@ -61,8 +61,12 @@ struct DerivationGoal : public Goal
bool needRestart = false; bool needRestart = false;
/* Whether to retry substituting the outputs after building the /* Whether to retry substituting the outputs after building the
inputs. */ inputs. This is done in case of an incomplete closure. */
bool retrySubstitution; bool retrySubstitution = false;
/* Whether we've retried substitution, in which case we won't try
again. */
bool retriedSubstitution = false;
/* The derivation stored at drvPath. */ /* The derivation stored at drvPath. */
std::unique_ptr<Derivation> drv; std::unique_ptr<Derivation> drv;

View file

@ -28,7 +28,7 @@ void Goal::addWaitee(GoalPtr waitee)
void Goal::waiteeDone(GoalPtr waitee, ExitCode result) void Goal::waiteeDone(GoalPtr waitee, ExitCode result)
{ {
assert(waitees.find(waitee) != waitees.end()); assert(waitees.count(waitee));
waitees.erase(waitee); waitees.erase(waitee);
trace(fmt("waitee '%s' done; %d left", waitee->name, waitees.size())); trace(fmt("waitee '%s' done; %d left", waitee->name, waitees.size()));

View file

@ -40,21 +40,21 @@ struct Goal : public std::enable_shared_from_this<Goal>
WeakGoals waiters; WeakGoals waiters;
/* Number of goals we are/were waiting for that have failed. */ /* Number of goals we are/were waiting for that have failed. */
unsigned int nrFailed; size_t nrFailed = 0;
/* Number of substitution goals we are/were waiting for that /* Number of substitution goals we are/were waiting for that
failed because there are no substituters. */ failed because there are no substituters. */
unsigned int nrNoSubstituters; size_t nrNoSubstituters = 0;
/* Number of substitution goals we are/were waiting for that /* Number of substitution goals we are/were waiting for that
failed because they had unsubstitutable references. */ failed because they had unsubstitutable references. */
unsigned int nrIncompleteClosure; size_t nrIncompleteClosure = 0;
/* Name of this goal for debugging purposes. */ /* Name of this goal for debugging purposes. */
std::string name; std::string name;
/* Whether the goal is finished. */ /* Whether the goal is finished. */
ExitCode exitCode; ExitCode exitCode = ecBusy;
/* Build result. */ /* Build result. */
BuildResult buildResult; BuildResult buildResult;
@ -65,10 +65,7 @@ struct Goal : public std::enable_shared_from_this<Goal>
Goal(Worker & worker, DerivedPath path) Goal(Worker & worker, DerivedPath path)
: worker(worker) : worker(worker)
, buildResult { .path = std::move(path) } , buildResult { .path = std::move(path) }
{ { }
nrFailed = nrNoSubstituters = nrIncompleteClosure = 0;
exitCode = ecBusy;
}
virtual ~Goal() virtual ~Goal()
{ {

View file

@ -2613,6 +2613,7 @@ DrvOutputs LocalDerivationGoal::registerOutputs()
signRealisation(thisRealisation); signRealisation(thisRealisation);
worker.store.registerDrvOutput(thisRealisation); worker.store.registerDrvOutput(thisRealisation);
} }
if (wantOutput(outputName, wantedOutputs))
builtOutputs.emplace(thisRealisation.id, thisRealisation); builtOutputs.emplace(thisRealisation.id, thisRealisation);
} }

View file

@ -1,15 +1,27 @@
source common.sh source common.sh
expectedJSONRegex='\[\{"drvPath":".*multiple-outputs-a.drv","outputs":\{"first":".*multiple-outputs-a-first","second":".*multiple-outputs-a-second"}},\{"drvPath":".*multiple-outputs-b.drv","outputs":\{"out":".*multiple-outputs-b"}}]' clearStore
# Make sure that 'nix build' only returns the outputs we asked for.
nix build -f multiple-outputs.nix --json a --no-link | jq --exit-status '
(.[0] |
(.drvPath | match(".*multiple-outputs-a.drv")) and
(.outputs | keys | length == 1) and
(.outputs.first | match(".*multiple-outputs-a-first")))
'
nix build -f multiple-outputs.nix --json a.all b.all --no-link | jq --exit-status ' nix build -f multiple-outputs.nix --json a.all b.all --no-link | jq --exit-status '
(.[0] | (.[0] |
(.drvPath | match(".*multiple-outputs-a.drv")) and (.drvPath | match(".*multiple-outputs-a.drv")) and
(.outputs | keys | length == 2) and
(.outputs.first | match(".*multiple-outputs-a-first")) and (.outputs.first | match(".*multiple-outputs-a-first")) and
(.outputs.second | match(".*multiple-outputs-a-second"))) (.outputs.second | match(".*multiple-outputs-a-second")))
and (.[1] | and (.[1] |
(.drvPath | match(".*multiple-outputs-b.drv")) and (.drvPath | match(".*multiple-outputs-b.drv")) and
(.outputs | keys | length == 1) and
(.outputs.out | match(".*multiple-outputs-b"))) (.outputs.out | match(".*multiple-outputs-b")))
' '
testNormalization () { testNormalization () {
clearStore clearStore
outPath=$(nix-build ./simple.nix --no-out-link) outPath=$(nix-build ./simple.nix --no-out-link)