Add a method to compute the closure of a realisation

Only considers the closure in term of `Realisation`, ignores all the
opaque inputs.

Dunno whether that’s the nicest solution, need to think it through a bit
This commit is contained in:
regnat 2021-05-19 10:26:58 +02:00
parent eca6ff06d6
commit af3afd25ea
2 changed files with 41 additions and 0 deletions

View file

@ -1,5 +1,6 @@
#include "realisation.hh"
#include "store-api.hh"
#include "closure.hh"
#include <nlohmann/json.hpp>
namespace nix {
@ -21,6 +22,43 @@ std::string DrvOutput::to_string() const {
return strHash() + "!" + outputName;
}
std::set<Realisation> Realisation::closure(Store & store, std::set<Realisation> startOutputs)
{
std::set<Realisation> res;
Realisation::closure(store, startOutputs, res);
return res;
}
void Realisation::closure(Store & store, std::set<Realisation> startOutputs, std::set<Realisation> & res)
{
auto getDeps = [&](const Realisation& current) -> std::set<Realisation> {
std::set<Realisation> res;
for (auto& currentDep : current.drvOutputDeps) {
if (auto currentRealisation = store.queryRealisation(currentDep))
res.insert(*currentRealisation);
else
throw Error(
"Unrealised derivation '%s'", currentDep.to_string());
}
return res;
};
computeClosure<Realisation>(
startOutputs, res,
[&](const Realisation& current,
std::function<void(std::promise<std::set<Realisation>>&)>
processEdges) {
std::promise<std::set<Realisation>> promise;
try {
auto res = getDeps(current);
promise.set_value(res);
} catch (...) {
promise.set_exception(std::current_exception());
}
return processEdges(promise);
});
}
nlohmann::json Realisation::toJSON() const {
nlohmann::json jsonDrvOutputDeps;
for (auto & dep : drvOutputDeps)

View file

@ -38,6 +38,9 @@ struct Realisation {
bool checkSignature(const PublicKeys & publicKeys, const std::string & sig) const;
size_t checkSignatures(const PublicKeys & publicKeys) const;
static std::set<Realisation> closure(Store &, std::set<Realisation>);
static void closure(Store &, std::set<Realisation>, std::set<Realisation>& res);
StorePath getPath() const { return outPath; }
GENERATE_CMP(Realisation, me->id, me->outPath);