diff options
Diffstat (limited to 'src/libexpr/get-drvs.cc')
-rw-r--r-- | src/libexpr/get-drvs.cc | 86 |
1 files changed, 58 insertions, 28 deletions
diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc index 1c9fa02a366a..b06c539de0fb 100644 --- a/src/libexpr/get-drvs.cc +++ b/src/libexpr/get-drvs.cc @@ -30,7 +30,7 @@ string DrvInfo::queryOutPath() } -DrvInfo::Outputs DrvInfo::queryOutputs() +DrvInfo::Outputs DrvInfo::queryOutputs(bool onlyOutputsToInstall) { if (outputs.empty()) { /* Get the ‘outputs’ list. */ @@ -39,9 +39,9 @@ DrvInfo::Outputs DrvInfo::queryOutputs() state->forceList(*i->value, *i->pos); /* For each output... */ - for (unsigned int j = 0; j < i->value->list.length; ++j) { + for (unsigned int j = 0; j < i->value->listSize(); ++j) { /* Evaluate the corresponding set. */ - string name = state->forceStringNoCtx(*i->value->list.elems[j], *i->pos); + string name = state->forceStringNoCtx(*i->value->listElems()[j], *i->pos); Bindings::iterator out = attrs->find(state->symbols.create(name)); if (out == attrs->end()) continue; // FIXME: throw error? state->forceAttrs(*out->value); @@ -55,7 +55,23 @@ DrvInfo::Outputs DrvInfo::queryOutputs() } else outputs["out"] = queryOutPath(); } - return outputs; + if (!onlyOutputsToInstall || !attrs) + return outputs; + + /* Check for `meta.outputsToInstall` and return `outputs` reduced to that. */ + const Value * outTI = queryMeta("outputsToInstall"); + if (!outTI) return outputs; + const auto errMsg = Error("this derivation has bad ‘meta.outputsToInstall’"); + /* ^ 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 != tString) throw errMsg; + auto out = outputs.find((*i)->string.s); + if (out == outputs.end()) throw errMsg; + result.insert(*out); + } + return result; } @@ -85,8 +101,8 @@ StringSet DrvInfo::queryMetaNames() { StringSet res; if (!getMeta()) return res; - foreach (Bindings::iterator, i, *meta) - res.insert(i->name); + for (auto & i : *meta) + res.insert(i.name); return res; } @@ -94,19 +110,20 @@ StringSet DrvInfo::queryMetaNames() bool DrvInfo::checkMeta(Value & v) { state->forceValue(v); - if (v.type == tList) { - for (unsigned int n = 0; n < v.list.length; ++n) - if (!checkMeta(*v.list.elems[n])) return false; + if (v.isList()) { + for (unsigned int n = 0; n < v.listSize(); ++n) + if (!checkMeta(*v.listElems()[n])) return false; return true; } else if (v.type == tAttrs) { Bindings::iterator i = v.attrs->find(state->sOutPath); if (i != v.attrs->end()) return false; - foreach (Bindings::iterator, i, *v.attrs) - if (!checkMeta(*i->value)) return false; + for (auto & i : *v.attrs) + if (!checkMeta(*i.value)) return false; return true; } - else return v.type == tInt || v.type == tBool || v.type == tString; + else return v.type == tInt || v.type == tBool || v.type == tString || + v.type == tFloat; } @@ -127,7 +144,7 @@ string DrvInfo::queryMetaString(const string & name) } -int DrvInfo::queryMetaInt(const string & name, int def) +NixInt DrvInfo::queryMetaInt(const string & name, NixInt def) { Value * v = queryMeta(name); if (!v) return def; @@ -135,12 +152,26 @@ int DrvInfo::queryMetaInt(const string & name, int def) if (v->type == tString) { /* Backwards compatibility with before we had support for integer meta fields. */ - int n; + NixInt n; if (string2Int(v->string.s, n)) return n; } return def; } +NixFloat DrvInfo::queryMetaFloat(const string & name, NixFloat def) +{ + Value * v = queryMeta(name); + if (!v) return def; + if (v->type == tFloat) return v->fpoint; + if (v->type == tString) { + /* Backwards compatibility with before we had support for + float meta fields. */ + NixFloat n; + if (string2Float(v->string.s, n)) return n; + } + return def; +} + bool DrvInfo::queryMetaBool(const string & name, bool def) { @@ -177,8 +208,8 @@ typedef set<Bindings *> Done; /* Evaluate value `v'. If it evaluates to a set of type `derivation', - then put information about it in `drvs' (unless it's already in - `doneExprs'). The result boolean indicates whether it makes sense + then put information about it in `drvs' (unless it's already in `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, @@ -255,13 +286,13 @@ static void getDerivations(EvalState & state, Value & vIn, precedence). */ typedef std::map<string, Symbol> SortedSymbols; SortedSymbols attrs; - foreach (Bindings::iterator, i, *v.attrs) - attrs.insert(std::pair<string, Symbol>(i->name, i->name)); + for (auto & i : *v.attrs) + attrs.insert(std::pair<string, Symbol>(i.name, i.name)); - foreach (SortedSymbols::iterator, i, attrs) { - startNest(nest, lvlDebug, format("evaluating attribute ‘%1%’") % i->first); - string pathPrefix2 = addToPath(pathPrefix, i->first); - Value & v2(*v.attrs->find(i->second)->value); + for (auto & i : attrs) { + Activity act(*logger, lvlDebug, format("evaluating attribute ‘%1%’") % i.first); + string pathPrefix2 = addToPath(pathPrefix, i.first); + Value & v2(*v.attrs->find(i.second)->value); if (combineChannels) getDerivations(state, v2, pathPrefix2, autoArgs, drvs, done, ignoreAssertionFailures); else if (getDerivation(state, v2, pathPrefix2, drvs, done, ignoreAssertionFailures)) { @@ -277,13 +308,12 @@ static void getDerivations(EvalState & state, Value & vIn, } } - else if (v.type == tList) { - for (unsigned int n = 0; n < v.list.length; ++n) { - startNest(nest, lvlDebug, - format("evaluating list element")); + else if (v.isList()) { + for (unsigned int n = 0; n < v.listSize(); ++n) { + Activity act(*logger, lvlDebug, "evaluating list element"); string pathPrefix2 = addToPath(pathPrefix, (format("%1%") % n).str()); - if (getDerivation(state, *v.list.elems[n], pathPrefix2, drvs, done, ignoreAssertionFailures)) - getDerivations(state, *v.list.elems[n], pathPrefix2, autoArgs, drvs, done, ignoreAssertionFailures); + if (getDerivation(state, *v.listElems()[n], pathPrefix2, drvs, done, ignoreAssertionFailures)) + getDerivations(state, *v.listElems()[n], pathPrefix2, autoArgs, drvs, done, ignoreAssertionFailures); } } |