diff options
Diffstat (limited to 'src/libexpr')
-rw-r--r-- | src/libexpr/eval.cc | 12 | ||||
-rw-r--r-- | src/libexpr/eval.hh | 3 | ||||
-rw-r--r-- | src/libexpr/get-drvs.cc | 33 | ||||
-rw-r--r-- | src/libexpr/get-drvs.hh | 16 |
4 files changed, 45 insertions, 19 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 8c5888497..193358161 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -2058,6 +2058,18 @@ Path EvalState::coerceToPath(const Pos & pos, Value & v, PathSet & context) } +StorePath EvalState::coerceToStorePath(const Pos & pos, Value & v, PathSet & context) +{ + auto path = coerceToString(pos, v, context, false, false).toOwned(); + if (auto storePath = store->maybeParseStorePath(path)) + return *storePath; + throw EvalError({ + .msg = hintfmt("path '%1%' is not in the Nix store", path), + .errPos = pos + }); +} + + bool EvalState::eqValues(Value & v1, Value & v2) { forceValue(v1, noPos); diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 36a53729a..800b00eef 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -272,6 +272,9 @@ public: path. Nothing is copied to the store. */ Path coerceToPath(const Pos & pos, Value & v, PathSet & context); + /* Like coerceToPath, but the result must be a store path. */ + StorePath coerceToStorePath(const Pos & pos, Value & v, PathSet & context); + public: /* The base environment, containing the builtin functions and diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc index 8393e4225..7630c5ff4 100644 --- a/src/libexpr/get-drvs.cc +++ b/src/libexpr/get-drvs.cc @@ -22,7 +22,7 @@ DrvInfo::DrvInfo(EvalState & state, ref<Store> store, const std::string & drvPat { auto [drvPath, selectedOutputs] = parsePathWithOutputs(*store, drvPathWithOutputs); - this->drvPath = store->printStorePath(drvPath); + this->drvPath = drvPath; auto drv = store->derivationFromPath(drvPath); @@ -41,9 +41,7 @@ DrvInfo::DrvInfo(EvalState & state, ref<Store> store, const std::string & drvPat throw Error("derivation '%s' does not have output '%s'", store->printStorePath(drvPath), outputName); auto & [outputName, output] = *i; - auto optStorePath = output.path(*store, drv.name, outputName); - if (optStorePath) - outPath = store->printStorePath(*optStorePath); + outPath = {output.path(*store, drv.name, outputName)}; } @@ -68,24 +66,35 @@ std::string DrvInfo::querySystem() const } -std::string DrvInfo::queryDrvPath() const +std::optional<StorePath> DrvInfo::queryDrvPath() const { - if (drvPath == "" && attrs) { + if (!drvPath && attrs) { Bindings::iterator i = attrs->find(state->sDrvPath); PathSet context; - drvPath = i != attrs->end() ? state->coerceToPath(*i->pos, *i->value, context) : ""; + if (i == attrs->end()) + drvPath = {std::nullopt}; + else + drvPath = {state->coerceToStorePath(*i->pos, *i->value, context)}; } - return drvPath; + return drvPath.value_or(std::nullopt); } -std::string DrvInfo::queryOutPath() const +StorePath DrvInfo::requireDrvPath() const +{ + if (auto drvPath = queryDrvPath()) + return *drvPath; + throw Error("derivation does not contain a 'drvPath' attribute"); +} + + +StorePath DrvInfo::queryOutPath() const { if (!outPath && attrs) { Bindings::iterator i = attrs->find(state->sOutPath); PathSet context; if (i != attrs->end()) - outPath = state->coerceToPath(*i->pos, *i->value, context); + outPath = state->coerceToStorePath(*i->pos, *i->value, context); } if (!outPath) throw UnimplementedError("CA derivations are not yet supported"); @@ -113,10 +122,10 @@ DrvInfo::Outputs DrvInfo::queryOutputs(bool onlyOutputsToInstall) Bindings::iterator outPath = out->value->attrs->find(state->sOutPath); if (outPath == out->value->attrs->end()) continue; // FIXME: throw error? PathSet context; - outputs[name] = state->coerceToPath(*outPath->pos, *outPath->value, context); + outputs.emplace(name, state->coerceToStorePath(*outPath->pos, *outPath->value, context)); } } else - outputs["out"] = queryOutPath(); + outputs.emplace("out", queryOutPath()); } if (!onlyOutputsToInstall || !attrs) return outputs; diff --git a/src/libexpr/get-drvs.hh b/src/libexpr/get-drvs.hh index d13847785..3ca6f1fca 100644 --- a/src/libexpr/get-drvs.hh +++ b/src/libexpr/get-drvs.hh @@ -1,6 +1,7 @@ #pragma once #include "eval.hh" +#include "path.hh" #include <string> #include <map> @@ -12,15 +13,15 @@ namespace nix { struct DrvInfo { public: - typedef std::map<std::string, Path> Outputs; + typedef std::map<std::string, StorePath> Outputs; private: EvalState * state; mutable std::string name; mutable std::string system; - mutable std::string drvPath; - mutable std::optional<std::string> outPath; + mutable std::optional<std::optional<StorePath>> drvPath; + mutable std::optional<StorePath> outPath; mutable std::string outputName; Outputs outputs; @@ -41,8 +42,9 @@ public: std::string queryName() const; std::string querySystem() const; - std::string queryDrvPath() const; - std::string queryOutPath() const; + std::optional<StorePath> queryDrvPath() const; + StorePath requireDrvPath() const; + StorePath queryOutPath() const; std::string queryOutputName() const; /** Return the list of outputs. The "outputs to install" are determined by `meta.outputsToInstall`. */ Outputs queryOutputs(bool onlyOutputsToInstall = false); @@ -61,8 +63,8 @@ public: */ void setName(const std::string & s) { name = s; } - void setDrvPath(const std::string & s) { drvPath = s; } - void setOutPath(const std::string & s) { outPath = s; } + void setDrvPath(StorePath path) { drvPath = {{std::move(path)}}; } + void setOutPath(StorePath path) { outPath = {{std::move(path)}}; } void setFailed() { failed = true; }; bool hasFailed() { return failed; }; |