diff options
Diffstat (limited to 'src/libexpr')
-rw-r--r-- | src/libexpr/eval.cc | 1 | ||||
-rw-r--r-- | src/libexpr/eval.hh | 2 | ||||
-rw-r--r-- | src/libexpr/get-drvs.cc | 46 | ||||
-rw-r--r-- | src/libexpr/get-drvs.hh | 11 |
4 files changed, 48 insertions, 12 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 9eb5fc758..676dd3ac4 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -138,6 +138,7 @@ EvalState::EvalState() , sName(symbols.create("name")) , sSystem(symbols.create("system")) , sOverrides(symbols.create("__overrides")) + , sOutputs(symbols.create("outputs")) , sOutputName(symbols.create("outputName")) , sIgnoreNulls(symbols.create("__ignoreNulls")) , baseEnv(allocEnv(128)) diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 1d3baaab8..a57efa08f 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -93,7 +93,7 @@ public: SymbolTable symbols; const Symbol sWith, sOutPath, sDrvPath, sType, sMeta, sName, - sSystem, sOverrides, sOutputName, sIgnoreNulls; + sSystem, sOverrides, sOutputs, sOutputName, sIgnoreNulls; /* If set, force copying files to the Nix store even if they already exist there. */ diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc index 2ee55bdca..f1cbc0bab 100644 --- a/src/libexpr/get-drvs.cc +++ b/src/libexpr/get-drvs.cc @@ -28,12 +28,42 @@ string DrvInfo::queryOutPath(EvalState & state) const } +DrvInfo::Outputs DrvInfo::queryOutputs(EvalState & state) +{ + if (outputs.empty()) { + /* Get the ‘outputs’ list. */ + Bindings::iterator i = attrs->find(state.sOutputs); + + if (i == attrs->end()) + outputs["out"] = queryOutPath(state); + else { + state.forceList(*i->value); + + /* For each output... */ + for (unsigned int j = 0; j < i->value->list.length; ++j) { + /* Evaluate the corresponding attribute set. */ + string name = state.forceStringNoCtx(*i->value->list.elems[j]); + Bindings::iterator out = attrs->find(state.symbols.create(name)); + if (out == attrs->end()) continue; // FIXME: throw error? + state.forceAttrs(*out->value); + + /* 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->value, context); + } + } + } + return outputs; +} + + string DrvInfo::queryOutputName(EvalState & state) const { if (outputName == "" && attrs) { Bindings::iterator i = attrs->find(state.sOutputName); - PathSet context; - (string &) outputName = i != attrs->end() ? state.coerceToString(*i->value, context) : ""; + (string &) outputName = i != attrs->end() ? state.forceStringNoCtx(*i->value) : ""; } return outputName; } @@ -42,9 +72,9 @@ string DrvInfo::queryOutputName(EvalState & state) const MetaInfo DrvInfo::queryMetaInfo(EvalState & state) const { if (metaInfoRead) return meta; - + (bool &) metaInfoRead = true; - + Bindings::iterator a = attrs->find(state.sMeta); if (a == attrs->end()) return meta; /* fine, empty meta information */ @@ -108,7 +138,7 @@ static bool getDerivation(EvalState & state, Value & v, done.insert(v.attrs); DrvInfo drv; - + Bindings::iterator i = v.attrs->find(state.sName); /* !!! We really would like to have a decent back trace here. */ if (i == v.attrs->end()) throw TypeError("derivation name missing"); @@ -126,7 +156,7 @@ static bool getDerivation(EvalState & state, Value & v, drvs.push_back(drv); return false; - + } catch (AssertionError & e) { if (ignoreAssertionFailures) return false; throw; @@ -159,7 +189,7 @@ static void getDerivations(EvalState & state, Value & vIn, { Value v; state.autoCallFunction(autoArgs, vIn, v); - + /* Process the expression. */ DrvInfo drv; @@ -222,5 +252,5 @@ void getDerivations(EvalState & state, Value & v, const string & pathPrefix, getDerivations(state, v, pathPrefix, autoArgs, drvs, done, ignoreAssertionFailures); } - + } diff --git a/src/libexpr/get-drvs.hh b/src/libexpr/get-drvs.hh index f84636a1a..af3998e40 100644 --- a/src/libexpr/get-drvs.hh +++ b/src/libexpr/get-drvs.hh @@ -25,16 +25,20 @@ typedef std::map<string, MetaValue> MetaInfo; struct DrvInfo { +public: + typedef std::map<string, Path> Outputs; + private: string drvPath; string outPath; string outputName; + Outputs outputs; bool metaInfoRead; MetaInfo meta; bool failed; // set if we get an AssertionError - + public: string name; string attrPath; /* path towards the derivation */ @@ -48,6 +52,7 @@ public: string queryDrvPath(EvalState & state) const; string queryOutPath(EvalState & state) const; string queryOutputName(EvalState & state) const; + Outputs queryOutputs(EvalState & state); MetaInfo queryMetaInfo(EvalState & state) const; MetaValue queryMetaInfo(EvalState & state, const string & name) const; @@ -55,7 +60,7 @@ public: { drvPath = s; } - + void setOutPath(const string & s) { outPath = s; @@ -84,5 +89,5 @@ void getDerivations(EvalState & state, Value & v, const string & pathPrefix, Bindings & autoArgs, DrvInfos & drvs, bool ignoreAssertionFailures); - + } |