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->cpuUser,
me->cpuSystem); 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 { namespace nix {
struct KeyedBuildResult;
struct BuildResult struct BuildResult
{ {
/** /**
@ -112,6 +114,18 @@ struct BuildResult
{ {
throw Error("%s", errorMsg); 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; auto & outputs = nodeP->value;
for (auto & outputName : outputs) { for (auto & outputName : outputs) {
auto buildResult = dg->getBuildResult(DerivedPath::Built { auto buildResult = dg->buildResult.restrictTo(DerivedPath::Built {
.drvPath = makeConstantStorePathRef(dg->drvPath), .drvPath = makeConstantStorePathRef(dg->drvPath),
.outputs = OutputsSpec::Names { outputName }, .outputs = OutputsSpec::Names { outputName },
}); });

View file

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

View file

@ -98,7 +98,6 @@ struct Goal : public std::enable_shared_from_this<Goal>
*/ */
std::optional<ExitCode> exitCode; std::optional<ExitCode> exitCode;
protected:
/** /**
* Build result. * Build result.
*/ */
@ -106,18 +105,6 @@ protected:
public: 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. * Exception containing an error message, if any.
*/ */