diff --git a/src/libstore/realisation.cc b/src/libstore/realisation.cc index 27ad6c150..fab10f68c 100644 --- a/src/libstore/realisation.cc +++ b/src/libstore/realisation.cc @@ -1,5 +1,6 @@ #include "realisation.hh" #include "store-api.hh" +#include "closure.hh" #include namespace nix { @@ -21,6 +22,43 @@ std::string DrvOutput::to_string() const { return strHash() + "!" + outputName; } +std::set Realisation::closure(Store & store, std::set startOutputs) +{ + std::set res; + Realisation::closure(store, startOutputs, res); + return res; +} + +void Realisation::closure(Store & store, std::set startOutputs, std::set & res) +{ + auto getDeps = [&](const Realisation& current) -> std::set { + std::set 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( + startOutputs, res, + [&](const Realisation& current, + std::function>&)> + processEdges) { + std::promise> 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) diff --git a/src/libstore/realisation.hh b/src/libstore/realisation.hh index 1e2808ce3..776ab606c 100644 --- a/src/libstore/realisation.hh +++ b/src/libstore/realisation.hh @@ -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 closure(Store &, std::set); + static void closure(Store &, std::set, std::set& res); + StorePath getPath() const { return outPath; } GENERATE_CMP(Realisation, me->id, me->outPath);