diff --git a/src/drv.cc b/src/drv.cc new file mode 100644 index 0000000..dc91ddf --- /dev/null +++ b/src/drv.cc @@ -0,0 +1,95 @@ +#include "drvs.hh" +#include +#include +#include +#include +#include +#include + + +static bool queryIsCached(nix::Store &store, + std::map &outputs) { + uint64_t downloadSize, narSize; + nix::StorePathSet willBuild, willSubstitute, unknown; + + std::vector paths; + for (auto const &[key, val] : outputs) { + paths.push_back(followLinksToStorePathWithOutputs(store, val)); + } + + store.queryMissing(toDerivedPaths(paths), willBuild, willSubstitute, + unknown, downloadSize, narSize); + return willBuild.empty() && unknown.empty(); +} + +/* The fields of a derivation that are printed in json form */ +Drv::Drv(std::string &attrPath, nix::EvalState &state, nix::DrvInfo &drvInfo, MyArgs &args) { + + auto localStore = state.store.dynamic_pointer_cast(); + + try { + for (auto out : drvInfo.queryOutputs(true)) { + if (out.second) + outputs[out.first] = localStore->printStorePath(*out.second); + } + } catch (const std::exception &e) { + throw nix::EvalError("derivation '%s' does not have valid outputs: %s", + attrPath, e.what()); + } + + if (args.meta) { + nlohmann::json meta_; + for (auto &metaName : drvInfo.queryMetaNames()) { + nix::NixStringContext context; + std::stringstream ss; + + auto metaValue = drvInfo.queryMeta(metaName); + // Skip non-serialisable types + // TODO: Fix serialisation of derivations to store paths + if (metaValue == 0) { + continue; + } + + nix::printValueAsJSON(state, true, *metaValue, nix::noPos, ss, + context); + + meta_[metaName] = nlohmann::json::parse(ss.str()); + } + meta = meta_; + } + if (args.checkCacheStatus) { + cacheStatus = queryIsCached(*localStore, outputs) ? Drv::CacheStatus::Cached + : Drv::CacheStatus::Uncached; + } else { + cacheStatus = Drv::CacheStatus::Unknown; + } + + drvPath = localStore->printStorePath(drvInfo.requireDrvPath()); + + auto drv = localStore->readDerivation(drvInfo.requireDrvPath()); + for (const auto &[inputDrvPath, inputNode] : drv.inputDrvs.map) { + std::set inputDrvOutputs; + for (auto &outputName : inputNode.value) { + inputDrvOutputs.insert(outputName); + } + inputDrvs[localStore->printStorePath(inputDrvPath)] = inputDrvOutputs; + } + name = drvInfo.queryName(); + system = drv.platform; +} + +void to_json(nlohmann::json &json, const Drv &drv) { + json = nlohmann::json{{"name", drv.name}, + {"system", drv.system}, + {"drvPath", drv.drvPath}, + {"outputs", drv.outputs}, + {"inputDrvs", drv.inputDrvs}}; + + if (drv.meta.has_value()) { + json["meta"] = drv.meta.value(); + } + + if (drv.cacheStatus != Drv::CacheStatus::Unknown) { + json["isCached"] = drv.cacheStatus == Drv::CacheStatus::Cached; + } +} diff --git a/src/drv.hh b/src/drv.hh new file mode 100644 index 0000000..4f1fbd0 --- /dev/null +++ b/src/drv.hh @@ -0,0 +1,27 @@ +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "eval-args.hh" + +/* The fields of a derivation that are printed in json form */ +struct Drv { + std::string name; + std::string system; + std::string drvPath; + + enum class CacheStatus { Cached, Uncached, Unknown } cacheStatus; + std::map outputs; + std::map> inputDrvs; + std::optional meta; + + Drv(std::string &attrPath, nix::EvalState &state, nix::DrvInfo &drvInfo, MyArgs &args); +}; +void to_json(nlohmann::json &json, const Drv &drv); diff --git a/src/meson.build b/src/meson.build index d2a145c..6b8d6dc 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,6 +1,7 @@ src = [ 'nix-eval-jobs.cc', - 'eval-args.cc' + 'eval-args.cc', + 'drv.cc' ] executable('nix-eval-jobs', src, diff --git a/src/nix-eval-jobs.cc b/src/nix-eval-jobs.cc index 271a16e..670bd48 100644 --- a/src/nix-eval-jobs.cc +++ b/src/nix-eval-jobs.cc @@ -11,18 +11,17 @@ #include #include #include -#include #include #include #include #include #include #include -#include #include #include #include "eval-args.hh" +#include "drv.hh" #include @@ -55,99 +54,6 @@ static Value *releaseExprTopLevelValue(EvalState &state, Bindings &autoArgs) { return vRoot; } -bool queryIsCached(Store &store, std::map &outputs) { - uint64_t downloadSize, narSize; - StorePathSet willBuild, willSubstitute, unknown; - - std::vector paths; - for (auto const &[key, val] : outputs) { - paths.push_back(followLinksToStorePathWithOutputs(store, val)); - } - - store.queryMissing(toDerivedPaths(paths), willBuild, willSubstitute, - unknown, downloadSize, narSize); - return willBuild.empty() && unknown.empty(); -} - -/* The fields of a derivation that are printed in json form */ -struct Drv { - std::string name; - std::string system; - std::string drvPath; - bool isCached; - std::map outputs; - std::map> inputDrvs; - std::optional meta; - - Drv(std::string &attrPath, EvalState &state, DrvInfo &drvInfo) { - - auto localStore = state.store.dynamic_pointer_cast(); - - try { - for (auto out : drvInfo.queryOutputs(true)) { - if (out.second) - outputs[out.first] = - localStore->printStorePath(*out.second); - } - } catch (const std::exception &e) { - throw EvalError("derivation '%s' does not have valid outputs: %s", - attrPath, e.what()); - } - - if (myArgs.meta) { - nlohmann::json meta_; - for (auto &metaName : drvInfo.queryMetaNames()) { - NixStringContext context; - std::stringstream ss; - - auto metaValue = drvInfo.queryMeta(metaName); - // Skip non-serialisable types - // TODO: Fix serialisation of derivations to store paths - if (metaValue == 0) { - continue; - } - - printValueAsJSON(state, true, *metaValue, noPos, ss, context); - - meta_[metaName] = nlohmann::json::parse(ss.str()); - } - meta = meta_; - } - if (myArgs.checkCacheStatus) { - isCached = queryIsCached(*localStore, outputs); - } - - drvPath = localStore->printStorePath(drvInfo.requireDrvPath()); - - auto drv = localStore->readDerivation(drvInfo.requireDrvPath()); - for (const auto &[inputDrvPath, inputNode] : drv.inputDrvs.map) { - std::set inputDrvOutputs; - for (auto &outputName : inputNode.value) { - inputDrvOutputs.insert(outputName); - } - inputDrvs[localStore->printStorePath(inputDrvPath)] = - inputDrvOutputs; - } - name = drvInfo.queryName(); - system = drv.platform; - } -}; - -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}, - {"inputDrvs", drv.inputDrvs}}; - - if (drv.meta.has_value()) { - json["meta"] = drv.meta.value(); - } - - if (myArgs.checkCacheStatus) { - json["isCached"] = drv.isCached; - } -} std::string attrPathJoin(json input) { return std::accumulate(input.begin(), input.end(), std::string(), @@ -267,7 +173,7 @@ static void worker(ref state, Bindings &autoArgs, AutoCloseFD &to, if (v->type() == nAttrs) { if (auto drvInfo = getDerivation(*state, *v, false)) { - auto drv = Drv(attrPathS, *state, *drvInfo); + auto drv = Drv(attrPathS, *state, *drvInfo, myArgs); reply.update(drv); /* Register the derivation as a GC root. !!! This