aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr
diff options
context:
space:
mode:
Diffstat (limited to 'src/libexpr')
-rw-r--r--src/libexpr/eval.cc12
-rw-r--r--src/libexpr/eval.hh3
-rw-r--r--src/libexpr/get-drvs.cc33
-rw-r--r--src/libexpr/get-drvs.hh16
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; };