aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorregnat <rg@regnat.ovh>2021-05-19 10:26:58 +0200
committerregnat <rg@regnat.ovh>2021-05-26 16:59:09 +0200
commitaf3afd25eafb7866406aee04ef049121a3e3ffb0 (patch)
tree6557e026889b90fb3f076fd6ad7ed25d1d420e49
parenteca6ff06d611ef005e80d419e1b6050393fc056d (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.cc38
-rw-r--r--src/libstore/realisation.hh3
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);