diff options
author | regnat <rg@regnat.ovh> | 2021-05-19 10:26:58 +0200 |
---|---|---|
committer | regnat <rg@regnat.ovh> | 2021-05-26 16:59:09 +0200 |
commit | af3afd25eafb7866406aee04ef049121a3e3ffb0 (patch) | |
tree | 6557e026889b90fb3f076fd6ad7ed25d1d420e49 | |
parent | eca6ff06d611ef005e80d419e1b6050393fc056d (diff) |
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
-rw-r--r-- | src/libstore/realisation.cc | 38 | ||||
-rw-r--r-- | src/libstore/realisation.hh | 3 |
2 files changed, 41 insertions, 0 deletions
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 <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) 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<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); |