libstore: move Goal::getBuildResult to BuildResult

there are no other uses for this yet, but asking for just a subset of
outputs does seem at least somewhat useful to have as a generic thing

Change-Id: I30ff5055a666c351b1b086b8d05b9d7c9fb1c77a
This commit is contained in:
eldritch horrors 2024-07-26 13:28:29 +02:00
parent 53bfcf2586
commit 97a389b0be
6 changed files with 40 additions and 42 deletions

View file

@ -15,4 +15,27 @@ GENERATE_CMP_EXT(
me->cpuUser,
me->cpuSystem);
KeyedBuildResult BuildResult::restrictTo(DerivedPath path) const
{
KeyedBuildResult res{*this, std::move(path)};
if (auto pbp = std::get_if<DerivedPath::Built>(&res.path)) {
auto & bp = *pbp;
/* Because goals are in general shared between derived paths
that share the same derivation, we need to filter their
results to get back just the results we care about.
*/
for (auto it = res.builtOutputs.begin(); it != res.builtOutputs.end();) {
if (bp.outputs.contains(it->first))
++it;
else
it = res.builtOutputs.erase(it);
}
}
return res;
}
}

View file

@ -11,6 +11,8 @@
namespace nix {
struct KeyedBuildResult;
struct BuildResult
{
/**
@ -112,6 +114,18 @@ struct BuildResult
{
throw Error("%s", errorMsg);
}
/**
* Project a BuildResult with just the information that pertains to
* the given path.
*
* A `BuildResult` may hold information for multiple derived paths;
* this function discards information about outputs not relevant in
* `path`. Build `Goal`s in particular may contain more outputs for
* a single build result than asked for directly, it's necessary to
* remove any such additional result to not leak other build infos.
*/
KeyedBuildResult restrictTo(DerivedPath path) const;
};
/**

View file

@ -1560,7 +1560,7 @@ void DerivationGoal::waiteeDone(GoalPtr waitee, ExitCode result)
auto & outputs = nodeP->value;
for (auto & outputName : outputs) {
auto buildResult = dg->getBuildResult(DerivedPath::Built {
auto buildResult = dg->buildResult.restrictTo(DerivedPath::Built {
.drvPath = makeConstantStorePathRef(dg->drvPath),
.outputs = OutputsSpec::Names { outputName },
});

View file

@ -62,10 +62,7 @@ std::vector<KeyedBuildResult> Store::buildPathsWithResults(
std::vector<KeyedBuildResult> results;
for (auto & [req, goalPtr] : state)
results.emplace_back(KeyedBuildResult {
goalPtr->getBuildResult(req),
/* .path = */ req,
});
results.emplace_back(goalPtr->buildResult.restrictTo(req));
return results;
}
@ -78,7 +75,7 @@ BuildResult Store::buildDerivation(const StorePath & drvPath, const BasicDerivat
try {
worker.run(Goals{goal});
return goal->getBuildResult(DerivedPath::Built {
return goal->buildResult.restrictTo(DerivedPath::Built {
.drvPath = makeConstantStorePathRef(drvPath),
.outputs = OutputsSpec::All {},
});

View file

@ -11,29 +11,6 @@ bool CompareGoalPtrs::operator() (const GoalPtr & a, const GoalPtr & b) const {
}
BuildResult Goal::getBuildResult(const DerivedPath & req) const {
BuildResult res { buildResult };
if (auto pbp = std::get_if<DerivedPath::Built>(&req)) {
auto & bp = *pbp;
/* Because goals are in general shared between derived paths
that share the same derivation, we need to filter their
results to get back just the results we care about.
*/
for (auto it = res.builtOutputs.begin(); it != res.builtOutputs.end();) {
if (bp.outputs.contains(it->first))
++it;
else
it = res.builtOutputs.erase(it);
}
}
return res;
}
void Goal::addWaitee(GoalPtr waitee)
{
waitees.insert(waitee);

View file

@ -98,7 +98,6 @@ struct Goal : public std::enable_shared_from_this<Goal>
*/
std::optional<ExitCode> exitCode;
protected:
/**
* Build result.
*/
@ -106,18 +105,6 @@ protected:
public:
/**
* Project a `BuildResult` with just the information that pertains
* to the given request.
*
* In general, goals may be aliased between multiple requests, and
* the stored `BuildResult` has information for the union of all
* requests. We don't want to leak what the other request are for
* sake of both privacy and determinism, and this "safe accessor"
* ensures we don't.
*/
BuildResult getBuildResult(const DerivedPath &) const;
/**
* Exception containing an error message, if any.
*/