From 8dd6426d15cc4787c9c6766fcf9771e8698d7e0b Mon Sep 17 00:00:00 2001 From: John Soo Date: Wed, 13 Apr 2022 15:41:51 -0700 Subject: [PATCH] Make Drv struct. To facilitate collecting and jsonifying derivations in different contexts --- src/nix-eval-jobs.cc | 101 ++++++++++++++++++++++++++++--------------- 1 file changed, 65 insertions(+), 36 deletions(-) diff --git a/src/nix-eval-jobs.cc b/src/nix-eval-jobs.cc index 7c0ff50..6eb2751 100644 --- a/src/nix-eval-jobs.cc +++ b/src/nix-eval-jobs.cc @@ -173,6 +173,65 @@ Value * topLevelValue(EvalState & state, Bindings & autoArgs) { : releaseExprTopLevelValue(state, autoArgs); } +/* The fields of a derivation that are printed in json form */ +struct Drv { + std::string name; + std::string system; + std::string drvPath; + std::map outputs; + std::optional meta; + + Drv (EvalState & state, DrvInfo & drvInfo) { + if (drvInfo.querySystem() == "unknown") + throw EvalError("derivation must have a 'system' attribute"); + + auto localStore = state.store.dynamic_pointer_cast(); + + for (auto out : drvInfo.queryOutputs(true)) { + if (out.second) + outputs[out.first] = localStore->printStorePath(*out.second); + + } + + if (myArgs.meta) { + nlohmann::json meta_; + for (auto & name : drvInfo.queryMetaNames()) { + PathSet context; + std::stringstream ss; + + auto metaValue = drvInfo.queryMeta(name); + // Skip non-serialisable types + // TODO: Fix serialisation of derivations to store paths + if (metaValue == 0) { + continue; + } + + printValueAsJSON(state, true, *metaValue, noPos, ss, context); + + meta_[name] = nlohmann::json::parse(ss.str()); + } + meta = meta_; + } + + name = drvInfo.queryName(); + system = drvInfo.querySystem(); + drvPath = localStore->printStorePath(drvInfo.requireDrvPath()); + } +}; + +static void to_json(nlohmann::json & json, const Drv & drv) { + json = nlohmann::json{ + { "name", drv.name }, + { "system", drv.system }, + { "drvPath", drv.drvPath }, + { "outputs", drv.outputs }, + }; + + if (drv.meta.has_value()) + json["meta"] = drv.meta.value(); + +} + static void worker( EvalState & state, Bindings & autoArgs, @@ -202,50 +261,20 @@ static void worker( auto v = state.allocValue(); state.autoCallFunction(autoArgs, *vTmp, *v); - if (auto drv = getDerivation(state, *v, false)) { - - if (drv->querySystem() == "unknown") - throw EvalError("derivation must have a 'system' attribute"); + if (auto drvInfo = getDerivation(state, *v, false)) { + auto drv = Drv(state, *drvInfo); auto localStore = state.store.dynamic_pointer_cast(); - auto drvPath = localStore->printStorePath(drv->requireDrvPath()); - auto storePath = localStore->parseStorePath(drvPath); - auto outputs = drv->queryOutputs(); + auto storePath = localStore->parseStorePath(drv.drvPath); - reply["name"] = drv->queryName(); - reply["system"] = drv->querySystem(); - reply["drvPath"] = drvPath; - for (auto out : outputs){ - if (out.second) { - reply["outputs"][out.first] = localStore->printStorePath(*out.second); - } - } - - if (myArgs.meta) { - nlohmann::json meta; - for (auto & name : drv->queryMetaNames()) { - PathSet context; - std::stringstream ss; - - auto metaValue = drv->queryMeta(name); - // Skip non-serialisable types - // TODO: Fix serialisation of derivations to store paths - if (metaValue == 0) { - continue; - } - - printValueAsJSON(state, true, *metaValue, noPos, ss, context); - nlohmann::json field = nlohmann::json::parse(ss.str()); - meta[name] = field; - } - reply["meta"] = meta; - } + reply = drv; + reply["attr"] = attrPath; /* Register the derivation as a GC root. !!! This registers roots for jobs that we may have already done. */ if (myArgs.gcRootsDir != "") { - Path root = myArgs.gcRootsDir + "/" + std::string(baseNameOf(drvPath)); + Path root = myArgs.gcRootsDir + "/" + std::string(baseNameOf(drv.drvPath)); if (!pathExists(root)) localStore->addPermRoot(storePath, root); }