aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr/get-drvs.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libexpr/get-drvs.cc')
-rw-r--r--src/libexpr/get-drvs.cc108
1 files changed, 58 insertions, 50 deletions
diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc
index f774e6493..7630c5ff4 100644
--- a/src/libexpr/get-drvs.cc
+++ b/src/libexpr/get-drvs.cc
@@ -11,8 +11,8 @@
namespace nix {
-DrvInfo::DrvInfo(EvalState & state, const string & attrPath, Bindings * attrs)
- : state(&state), attrs(attrs), attrPath(attrPath)
+DrvInfo::DrvInfo(EvalState & state, std::string attrPath, Bindings * attrs)
+ : state(&state), attrs(attrs), attrPath(std::move(attrPath))
{
}
@@ -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,13 +41,11 @@ 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)};
}
-string DrvInfo::queryName() const
+std::string DrvInfo::queryName() const
{
if (name == "" && attrs) {
auto i = attrs->find(state->sName);
@@ -58,7 +56,7 @@ string DrvInfo::queryName() const
}
-string DrvInfo::querySystem() const
+std::string DrvInfo::querySystem() const
{
if (system == "" && attrs) {
auto i = attrs->find(state->sSystem);
@@ -68,24 +66,35 @@ string DrvInfo::querySystem() const
}
-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);
}
-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");
@@ -102,21 +111,21 @@ DrvInfo::Outputs DrvInfo::queryOutputs(bool onlyOutputsToInstall)
state->forceList(*i->value, *i->pos);
/* For each output... */
- for (unsigned int j = 0; j < i->value->listSize(); ++j) {
+ for (auto elem : i->value->listItems()) {
/* Evaluate the corresponding set. */
- string name = state->forceStringNoCtx(*i->value->listElems()[j], *i->pos);
+ std::string name(state->forceStringNoCtx(*elem, *i->pos));
Bindings::iterator out = attrs->find(state->symbols.create(name));
if (out == attrs->end()) continue; // FIXME: throw error?
- state->forceAttrs(*out->value);
+ state->forceAttrs(*out->value, *i->pos);
/* And evaluate its ‘outPath’ attribute. */
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;
@@ -128,9 +137,9 @@ DrvInfo::Outputs DrvInfo::queryOutputs(bool onlyOutputsToInstall)
/* ^ this shows during `nix-env -i` right under the bad derivation */
if (!outTI->isList()) throw errMsg;
Outputs result;
- for (auto i = outTI->listElems(); i != outTI->listElems() + outTI->listSize(); ++i) {
- if ((*i)->type() != nString) throw errMsg;
- auto out = outputs.find((*i)->string.s);
+ for (auto elem : outTI->listItems()) {
+ if (elem->type() != nString) throw errMsg;
+ auto out = outputs.find(elem->string.s);
if (out == outputs.end()) throw errMsg;
result.insert(*out);
}
@@ -138,7 +147,7 @@ DrvInfo::Outputs DrvInfo::queryOutputs(bool onlyOutputsToInstall)
}
-string DrvInfo::queryOutputName() const
+std::string DrvInfo::queryOutputName() const
{
if (outputName == "" && attrs) {
Bindings::iterator i = attrs->find(state->sOutputName);
@@ -172,10 +181,10 @@ StringSet DrvInfo::queryMetaNames()
bool DrvInfo::checkMeta(Value & v)
{
- state->forceValue(v);
+ state->forceValue(v, [&]() { return v.determinePos(noPos); });
if (v.type() == nList) {
- for (unsigned int n = 0; n < v.listSize(); ++n)
- if (!checkMeta(*v.listElems()[n])) return false;
+ for (auto elem : v.listItems())
+ if (!checkMeta(*elem)) return false;
return true;
}
else if (v.type() == nAttrs) {
@@ -190,7 +199,7 @@ bool DrvInfo::checkMeta(Value & v)
}
-Value * DrvInfo::queryMeta(const string & name)
+Value * DrvInfo::queryMeta(const std::string & name)
{
if (!getMeta()) return 0;
Bindings::iterator a = meta->find(state->symbols.create(name));
@@ -199,7 +208,7 @@ Value * DrvInfo::queryMeta(const string & name)
}
-string DrvInfo::queryMetaString(const string & name)
+std::string DrvInfo::queryMetaString(const std::string & name)
{
Value * v = queryMeta(name);
if (!v || v->type() != nString) return "";
@@ -207,7 +216,7 @@ string DrvInfo::queryMetaString(const string & name)
}
-NixInt DrvInfo::queryMetaInt(const string & name, NixInt def)
+NixInt DrvInfo::queryMetaInt(const std::string & name, NixInt def)
{
Value * v = queryMeta(name);
if (!v) return def;
@@ -221,7 +230,7 @@ NixInt DrvInfo::queryMetaInt(const string & name, NixInt def)
return def;
}
-NixFloat DrvInfo::queryMetaFloat(const string & name, NixFloat def)
+NixFloat DrvInfo::queryMetaFloat(const std::string & name, NixFloat def)
{
Value * v = queryMeta(name);
if (!v) return def;
@@ -236,7 +245,7 @@ NixFloat DrvInfo::queryMetaFloat(const string & name, NixFloat def)
}
-bool DrvInfo::queryMetaBool(const string & name, bool def)
+bool DrvInfo::queryMetaBool(const std::string & name, bool def)
{
Value * v = queryMeta(name);
if (!v) return def;
@@ -251,23 +260,22 @@ bool DrvInfo::queryMetaBool(const string & name, bool def)
}
-void DrvInfo::setMeta(const string & name, Value * v)
+void DrvInfo::setMeta(const std::string & name, Value * v)
{
getMeta();
- Bindings * old = meta;
- meta = state->allocBindings(1 + (old ? old->size() : 0));
+ auto attrs = state->buildBindings(1 + (meta ? meta->size() : 0));
Symbol sym = state->symbols.create(name);
- if (old)
- for (auto i : *old)
+ if (meta)
+ for (auto i : *meta)
if (i.name != sym)
- meta->push_back(i);
- if (v) meta->push_back(Attr(sym, v));
- meta->sort();
+ attrs.insert(i);
+ if (v) attrs.insert(sym, v);
+ meta = attrs.finish();
}
/* Cache for already considered attrsets. */
-typedef set<Bindings *> Done;
+typedef std::set<Bindings *> Done;
/* Evaluate value `v'. If it evaluates to a set of type `derivation',
@@ -275,11 +283,11 @@ typedef set<Bindings *> Done;
The result boolean indicates whether it makes sense
for the caller to recursively search for derivations in `v'. */
static bool getDerivation(EvalState & state, Value & v,
- const string & attrPath, DrvInfos & drvs, Done & done,
+ const std::string & attrPath, DrvInfos & drvs, Done & done,
bool ignoreAssertionFailures)
{
try {
- state.forceValue(v);
+ state.forceValue(v, [&]() { return v.determinePos(noPos); });
if (!state.isDerivation(v)) return true;
/* Remove spurious duplicates (e.g., a set like `rec { x =
@@ -312,7 +320,7 @@ std::optional<DrvInfo> getDerivation(EvalState & state, Value & v,
}
-static string addToPath(const string & s1, const string & s2)
+static std::string addToPath(const std::string & s1, const std::string & s2)
{
return s1.empty() ? s2 : s1 + "." + s2;
}
@@ -322,7 +330,7 @@ static std::regex attrRegex("[A-Za-z_][A-Za-z0-9-_+]*");
static void getDerivations(EvalState & state, Value & vIn,
- const string & pathPrefix, Bindings & autoArgs,
+ const std::string & pathPrefix, Bindings & autoArgs,
DrvInfos & drvs, Done & done,
bool ignoreAssertionFailures)
{
@@ -347,7 +355,7 @@ static void getDerivations(EvalState & state, Value & vIn,
debug("evaluating attribute '%1%'", i->name);
if (!std::regex_match(std::string(i->name), attrRegex))
continue;
- string pathPrefix2 = addToPath(pathPrefix, i->name);
+ std::string pathPrefix2 = addToPath(pathPrefix, i->name);
if (combineChannels)
getDerivations(state, *i->value, pathPrefix2, autoArgs, drvs, done, ignoreAssertionFailures);
else if (getDerivation(state, *i->value, pathPrefix2, drvs, done, ignoreAssertionFailures)) {
@@ -364,10 +372,10 @@ static void getDerivations(EvalState & state, Value & vIn,
}
else if (v.type() == nList) {
- for (unsigned int n = 0; n < v.listSize(); ++n) {
- string pathPrefix2 = addToPath(pathPrefix, (format("%1%") % n).str());
- if (getDerivation(state, *v.listElems()[n], pathPrefix2, drvs, done, ignoreAssertionFailures))
- getDerivations(state, *v.listElems()[n], pathPrefix2, autoArgs, drvs, done, ignoreAssertionFailures);
+ for (auto [n, elem] : enumerate(v.listItems())) {
+ std::string pathPrefix2 = addToPath(pathPrefix, fmt("%d", n));
+ if (getDerivation(state, *elem, pathPrefix2, drvs, done, ignoreAssertionFailures))
+ getDerivations(state, *elem, pathPrefix2, autoArgs, drvs, done, ignoreAssertionFailures);
}
}
@@ -375,7 +383,7 @@ static void getDerivations(EvalState & state, Value & vIn,
}
-void getDerivations(EvalState & state, Value & v, const string & pathPrefix,
+void getDerivations(EvalState & state, Value & v, const std::string & pathPrefix,
Bindings & autoArgs, DrvInfos & drvs, bool ignoreAssertionFailures)
{
Done done;