Generalise meta attributes
This commit is contained in:
		
							parent
							
								
									990126cde0
								
							
						
					
					
						commit
						0f24400d90
					
				
					 5 changed files with 208 additions and 208 deletions
				
			
		|  | @ -2,116 +2,155 @@ | ||||||
| #include "util.hh" | #include "util.hh" | ||||||
| #include "eval-inline.hh" | #include "eval-inline.hh" | ||||||
| 
 | 
 | ||||||
|  | #include <cstring> | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| namespace nix { | namespace nix { | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| string DrvInfo::queryDrvPath(EvalState & state) const | string DrvInfo::queryDrvPath() | ||||||
| { | { | ||||||
|     if (drvPath == "" && attrs) { |     if (drvPath == "" && attrs) { | ||||||
|         Bindings::iterator i = attrs->find(state.sDrvPath); |         Bindings::iterator i = attrs->find(state->sDrvPath); | ||||||
|         PathSet context; |         PathSet context; | ||||||
|         (string &) drvPath = i != attrs->end() ? state.coerceToPath(*i->value, context) : ""; |         drvPath = i != attrs->end() ? state->coerceToPath(*i->value, context) : ""; | ||||||
|     } |     } | ||||||
|     return drvPath; |     return drvPath; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| string DrvInfo::queryOutPath(EvalState & state) const | string DrvInfo::queryOutPath() | ||||||
| { | { | ||||||
|     if (outPath == "" && attrs) { |     if (outPath == "" && attrs) { | ||||||
|         Bindings::iterator i = attrs->find(state.sOutPath); |         Bindings::iterator i = attrs->find(state->sOutPath); | ||||||
|         PathSet context; |         PathSet context; | ||||||
|         (string &) outPath = i != attrs->end() ? state.coerceToPath(*i->value, context) : ""; |         outPath = i != attrs->end() ? state->coerceToPath(*i->value, context) : ""; | ||||||
|     } |     } | ||||||
|     return outPath; |     return outPath; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| DrvInfo::Outputs DrvInfo::queryOutputs(EvalState & state) | DrvInfo::Outputs DrvInfo::queryOutputs() | ||||||
| { | { | ||||||
|     if (outputs.empty()) { |     if (outputs.empty()) { | ||||||
|         /* Get the ‘outputs’ list. */ |         /* Get the ‘outputs’ list. */ | ||||||
|         Bindings::iterator i = attrs->find(state.sOutputs); |         Bindings::iterator i; | ||||||
| 
 |         if (attrs && (i = attrs->find(state->sOutputs)) != attrs->end()) { | ||||||
|         if (i == attrs->end()) |             state->forceList(*i->value); | ||||||
|             outputs["out"] = queryOutPath(state); |  | ||||||
|         else { |  | ||||||
|             state.forceList(*i->value); |  | ||||||
| 
 | 
 | ||||||
|             /* For each output... */ |             /* For each output... */ | ||||||
|             for (unsigned int j = 0; j < i->value->list.length; ++j) { |             for (unsigned int j = 0; j < i->value->list.length; ++j) { | ||||||
|                 /* Evaluate the corresponding set. */ |                 /* Evaluate the corresponding set. */ | ||||||
|                 string name = state.forceStringNoCtx(*i->value->list.elems[j]); |                 string name = state->forceStringNoCtx(*i->value->list.elems[j]); | ||||||
|                 Bindings::iterator out = attrs->find(state.symbols.create(name)); |                 Bindings::iterator out = attrs->find(state->symbols.create(name)); | ||||||
|                 if (out == attrs->end()) continue; // FIXME: throw error?
 |                 if (out == attrs->end()) continue; // FIXME: throw error?
 | ||||||
|                 state.forceAttrs(*out->value); |                 state->forceAttrs(*out->value); | ||||||
| 
 | 
 | ||||||
|                 /* And evaluate its ‘outPath’ attribute. */ |                 /* And evaluate its ‘outPath’ attribute. */ | ||||||
|                 Bindings::iterator outPath = out->value->attrs->find(state.sOutPath); |                 Bindings::iterator outPath = out->value->attrs->find(state->sOutPath); | ||||||
|                 if (outPath == out->value->attrs->end()) continue; // FIXME: throw error?
 |                 if (outPath == out->value->attrs->end()) continue; // FIXME: throw error?
 | ||||||
|                 PathSet context; |                 PathSet context; | ||||||
|                 outputs[name] = state.coerceToPath(*outPath->value, context); |                 outputs[name] = state->coerceToPath(*outPath->value, context); | ||||||
|             } |             } | ||||||
|         } |         } else | ||||||
|  |             outputs["out"] = queryOutPath(); | ||||||
|     } |     } | ||||||
|     return outputs; |     return outputs; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| string DrvInfo::queryOutputName(EvalState & state) const | string DrvInfo::queryOutputName() | ||||||
| { | { | ||||||
|     if (outputName == "" && attrs) { |     if (outputName == "" && attrs) { | ||||||
|         Bindings::iterator i = attrs->find(state.sOutputName); |         Bindings::iterator i = attrs->find(state->sOutputName); | ||||||
|         (string &) outputName = i != attrs->end() ? state.forceStringNoCtx(*i->value) : ""; |         outputName = i != attrs->end() ? state->forceStringNoCtx(*i->value) : ""; | ||||||
|     } |     } | ||||||
|     return outputName; |     return outputName; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| MetaInfo DrvInfo::queryMetaInfo(EvalState & state) const | Bindings * DrvInfo::getMeta() | ||||||
| { | { | ||||||
|     if (metaInfoRead) return meta; |     if (meta) return meta; | ||||||
| 
 |     if (!attrs) return 0; | ||||||
|     (bool &) metaInfoRead = true; |     Bindings::iterator a = attrs->find(state->sMeta); | ||||||
| 
 |     if (a == attrs->end()) return 0; | ||||||
|     Bindings::iterator a = attrs->find(state.sMeta); |     state->forceAttrs(*a->value); | ||||||
|     if (a == attrs->end()) return meta; /* fine, empty meta information */ |     meta = a->value->attrs; | ||||||
| 
 |  | ||||||
|     state.forceAttrs(*a->value); |  | ||||||
| 
 |  | ||||||
|     foreach (Bindings::iterator, i, *a->value->attrs) { |  | ||||||
|         MetaValue value; |  | ||||||
|         state.forceValue(*i->value); |  | ||||||
|         if (i->value->type == tString) { |  | ||||||
|             value.type = MetaValue::tpString; |  | ||||||
|             value.stringValue = i->value->string.s; |  | ||||||
|         } else if (i->value->type == tInt) { |  | ||||||
|             value.type = MetaValue::tpInt; |  | ||||||
|             value.intValue = i->value->integer; |  | ||||||
|         } else if (i->value->type == tList) { |  | ||||||
|             value.type = MetaValue::tpStrings; |  | ||||||
|             for (unsigned int j = 0; j < i->value->list.length; ++j) |  | ||||||
|                 value.stringValues.push_back(state.forceStringNoCtx(*i->value->list.elems[j])); |  | ||||||
|         } else continue; |  | ||||||
|         ((MetaInfo &) meta)[i->name] = value; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return meta; |     return meta; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| MetaValue DrvInfo::queryMetaInfo(EvalState & state, const string & name) const | StringSet DrvInfo::queryMetaNames() | ||||||
| { | { | ||||||
|     /* !!! evaluates all meta attributes => inefficient */ |     StringSet res; | ||||||
|     return queryMetaInfo(state)[name]; |     if (!getMeta()) return res; | ||||||
|  |     foreach (Bindings::iterator, i, *meta) | ||||||
|  |         res.insert(i->name); | ||||||
|  |     return res; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| void DrvInfo::setMetaInfo(const MetaInfo & meta) | Value * DrvInfo::queryMeta(const string & name) | ||||||
| { | { | ||||||
|     metaInfoRead = true; |     if (!getMeta()) return 0; | ||||||
|     this->meta = meta; |     Bindings::iterator a = meta->find(state->symbols.create(name)); | ||||||
|  |     if (a == meta->end()) return 0; | ||||||
|  |     state->forceValue(*a->value); | ||||||
|  |     return a->value; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | string DrvInfo::queryMetaString(const string & name) | ||||||
|  | { | ||||||
|  |     Value * v = queryMeta(name); | ||||||
|  |     if (!v || v->type != tString) return ""; | ||||||
|  |     return v->string.s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | int DrvInfo::queryMetaInt(const string & name, int def) | ||||||
|  | { | ||||||
|  |     Value * v = queryMeta(name); | ||||||
|  |     if (!v) return def; | ||||||
|  |     if (v->type == tInt) return v->integer; | ||||||
|  |     if (v->type == tString) { | ||||||
|  |         /* Backwards compatibility with before we had support for
 | ||||||
|  |            integer meta fields. */ | ||||||
|  |         int n; | ||||||
|  |         if (string2Int(v->string.s, n)) return n; | ||||||
|  |     } | ||||||
|  |     return def; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | bool DrvInfo::queryMetaBool(const string & name, bool def) | ||||||
|  | { | ||||||
|  |     Value * v = queryMeta(name); | ||||||
|  |     if (!v) return def; | ||||||
|  |     if (v->type == tBool) return v->boolean; | ||||||
|  |     if (v->type == tString) { | ||||||
|  |         /* Backwards compatibility with before we had support for
 | ||||||
|  |            Boolean meta fields. */ | ||||||
|  |         if (strcmp(v->string.s, "true") == 0) return true; | ||||||
|  |         if (strcmp(v->string.s, "false") == 0) return false; | ||||||
|  |     } | ||||||
|  |     return def; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void DrvInfo::setMeta(const string & name, Value * v) | ||||||
|  | { | ||||||
|  |     getMeta(); | ||||||
|  |     Bindings * old = meta; | ||||||
|  |     meta = new Bindings(); | ||||||
|  |     Symbol sym = state->symbols.create(name); | ||||||
|  |     if (old) | ||||||
|  |         foreach (Bindings::iterator, i, *old) | ||||||
|  |             if (i->name != sym) | ||||||
|  |                 meta->push_back(*i); | ||||||
|  |     if (v) meta->push_back(Attr(sym, v)); | ||||||
|  |     meta->sort(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -136,22 +175,18 @@ static bool getDerivation(EvalState & state, Value & v, | ||||||
|         if (done.find(v.attrs) != done.end()) return false; |         if (done.find(v.attrs) != done.end()) return false; | ||||||
|         done.insert(v.attrs); |         done.insert(v.attrs); | ||||||
| 
 | 
 | ||||||
|         DrvInfo drv; |  | ||||||
| 
 |  | ||||||
|         Bindings::iterator i = v.attrs->find(state.sName); |         Bindings::iterator i = v.attrs->find(state.sName); | ||||||
|         /* !!! We really would like to have a decent back trace here. */ |         /* !!! We really would like to have a decent back trace here. */ | ||||||
|         if (i == v.attrs->end()) throw TypeError("derivation name missing"); |         if (i == v.attrs->end()) throw TypeError("derivation name missing"); | ||||||
|         drv.name = state.forceStringNoCtx(*i->value); |  | ||||||
| 
 | 
 | ||||||
|         Bindings::iterator i2 = v.attrs->find(state.sSystem); |         Bindings::iterator i2 = v.attrs->find(state.sSystem); | ||||||
|         if (i2 == v.attrs->end()) |  | ||||||
|             drv.system = "unknown"; |  | ||||||
|         else |  | ||||||
|             drv.system = state.forceStringNoCtx(*i2->value); |  | ||||||
| 
 | 
 | ||||||
|         drv.attrs = v.attrs; |         DrvInfo drv( | ||||||
| 
 |             state, | ||||||
|         drv.attrPath = attrPath; |             state.forceStringNoCtx(*i->value), | ||||||
|  |             attrPath, | ||||||
|  |             i2 == v.attrs->end() ? "unknown" : state.forceStringNoCtx(*i2->value), | ||||||
|  |             v.attrs); | ||||||
| 
 | 
 | ||||||
|         drvs.push_back(drv); |         drvs.push_back(drv); | ||||||
|         return false; |         return false; | ||||||
|  | @ -190,8 +225,6 @@ static void getDerivations(EvalState & state, Value & vIn, | ||||||
|     state.autoCallFunction(autoArgs, vIn, v); |     state.autoCallFunction(autoArgs, vIn, v); | ||||||
| 
 | 
 | ||||||
|     /* Process the expression. */ |     /* Process the expression. */ | ||||||
|     DrvInfo drv; |  | ||||||
| 
 |  | ||||||
|     if (!getDerivation(state, v, pathPrefix, drvs, done, ignoreAssertionFailures)) ; |     if (!getDerivation(state, v, pathPrefix, drvs, done, ignoreAssertionFailures)) ; | ||||||
| 
 | 
 | ||||||
|     else if (v.type == tAttrs) { |     else if (v.type == tAttrs) { | ||||||
|  |  | ||||||
|  | @ -11,50 +11,50 @@ | ||||||
| namespace nix { | namespace nix { | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| struct MetaValue |  | ||||||
| { |  | ||||||
|     enum { tpNone, tpString, tpStrings, tpInt } type; |  | ||||||
|     string stringValue; |  | ||||||
|     Strings stringValues; |  | ||||||
|     int intValue; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| typedef std::map<string, MetaValue> MetaInfo; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| struct DrvInfo | struct DrvInfo | ||||||
| { | { | ||||||
| public: | public: | ||||||
|     typedef std::map<string, Path> Outputs; |     typedef std::map<string, Path> Outputs; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  |     EvalState * state; | ||||||
|  | 
 | ||||||
|     string drvPath; |     string drvPath; | ||||||
|     string outPath; |     string outPath; | ||||||
|     string outputName; |     string outputName; | ||||||
|     Outputs outputs; |     Outputs outputs; | ||||||
| 
 | 
 | ||||||
|     bool metaInfoRead; |  | ||||||
|     MetaInfo meta; |  | ||||||
| 
 |  | ||||||
|     bool failed; // set if we get an AssertionError
 |     bool failed; // set if we get an AssertionError
 | ||||||
| 
 | 
 | ||||||
|  |     Bindings * attrs, * meta; | ||||||
|  | 
 | ||||||
|  |     Bindings * getMeta(); | ||||||
|  | 
 | ||||||
| public: | public: | ||||||
|     string name; |     string name; | ||||||
|     string attrPath; /* path towards the derivation */ |     string attrPath; /* path towards the derivation */ | ||||||
|     string system; |     string system; | ||||||
| 
 | 
 | ||||||
|     /* !!! make this private */ |     DrvInfo(EvalState & state) : state(&state), failed(false), attrs(0), meta(0) { }; | ||||||
|     Bindings * attrs; |     DrvInfo(EvalState & state, const string & name, const string & attrPath, const string & system, Bindings * attrs) | ||||||
|  |         : state(&state), failed(false), attrs(attrs), meta(0), name(name), attrPath(attrPath), system(system) { }; | ||||||
| 
 | 
 | ||||||
|     DrvInfo() : metaInfoRead(false), failed(false), attrs(0) { }; |     string queryDrvPath(); | ||||||
|  |     string queryOutPath(); | ||||||
|  |     string queryOutputName(); | ||||||
|  |     Outputs queryOutputs(); | ||||||
| 
 | 
 | ||||||
|     string queryDrvPath(EvalState & state) const; |     StringSet queryMetaNames(); | ||||||
|     string queryOutPath(EvalState & state) const; |     Value * queryMeta(const string & name); | ||||||
|     string queryOutputName(EvalState & state) const; |     string queryMetaString(const string & name); | ||||||
|     Outputs queryOutputs(EvalState & state); |     int queryMetaInt(const string & name, int def); | ||||||
|  |     bool queryMetaBool(const string & name, bool def); | ||||||
|  |     void setMeta(const string & name, Value * v); | ||||||
|  | 
 | ||||||
|  |     /*
 | ||||||
|     MetaInfo queryMetaInfo(EvalState & state) const; |     MetaInfo queryMetaInfo(EvalState & state) const; | ||||||
|     MetaValue queryMetaInfo(EvalState & state, const string & name) const; |     MetaValue queryMetaInfo(EvalState & state, const string & name) const; | ||||||
|  |     */ | ||||||
| 
 | 
 | ||||||
|     void setDrvPath(const string & s) |     void setDrvPath(const string & s) | ||||||
|     { |     { | ||||||
|  | @ -66,8 +66,6 @@ public: | ||||||
|         outPath = s; |         outPath = s; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void setMetaInfo(const MetaInfo & meta); |  | ||||||
| 
 |  | ||||||
|     void setFailed() { failed = true; }; |     void setFailed() { failed = true; }; | ||||||
|     bool hasFailed() { return failed; }; |     bool hasFailed() { return failed; }; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -210,21 +210,13 @@ static Path getDefNixExprPath() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static int getPriority(EvalState & state, const DrvInfo & drv) | static int getPriority(EvalState & state, DrvInfo & drv) | ||||||
| { | { | ||||||
|     MetaValue value = drv.queryMetaInfo(state, "priority"); |     return drv.queryMetaInt("priority", 0); | ||||||
|     int prio = 0; |  | ||||||
|     if (value.type == MetaValue::tpInt) prio = value.intValue; |  | ||||||
|     else if (value.type == MetaValue::tpString) |  | ||||||
|         /* Backwards compatibility.  Priorities used to be strings
 |  | ||||||
|            before we had support for integer meta field. */ |  | ||||||
|         string2Int(value.stringValue, prio); |  | ||||||
|     return prio; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static int comparePriorities(EvalState & state, | static int comparePriorities(EvalState & state, DrvInfo & drv1, DrvInfo & drv2) | ||||||
|     const DrvInfo & drv1, const DrvInfo & drv2) |  | ||||||
| { | { | ||||||
|     return getPriority(state, drv2) - getPriority(state, drv1); |     return getPriority(state, drv2) - getPriority(state, drv1); | ||||||
| } | } | ||||||
|  | @ -232,9 +224,9 @@ static int comparePriorities(EvalState & state, | ||||||
| 
 | 
 | ||||||
| // FIXME: this function is rather slow since it checks a single path
 | // FIXME: this function is rather slow since it checks a single path
 | ||||||
| // at a time.
 | // at a time.
 | ||||||
| static bool isPrebuilt(EvalState & state, const DrvInfo & elem) | static bool isPrebuilt(EvalState & state, DrvInfo & elem) | ||||||
| { | { | ||||||
|     Path path = elem.queryOutPath(state); |     Path path = elem.queryOutPath(); | ||||||
|     if (store->isValidPath(path)) return true; |     if (store->isValidPath(path)) return true; | ||||||
|     PathSet ps = store->querySubstitutablePaths(singleton<PathSet>(path)); |     PathSet ps = store->querySubstitutablePaths(singleton<PathSet>(path)); | ||||||
|     return ps.find(path) != ps.end(); |     return ps.find(path) != ps.end(); | ||||||
|  | @ -296,7 +288,8 @@ static DrvInfos filterBySelector(EvalState & state, const DrvInfos & allElems, | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 if (d > 0) { |                 if (d > 0) { | ||||||
|                     newest[drvName.name] = *j; |                     newest.erase(drvName.name); | ||||||
|  |                     newest.insert(Newest::value_type(drvName.name, *j)); | ||||||
|                     multiple.erase(j->first.name); |                     multiple.erase(j->first.name); | ||||||
|                 } else if (d == 0) { |                 } else if (d == 0) { | ||||||
|                     multiple.insert(j->first.name); |                     multiple.insert(j->first.name); | ||||||
|  | @ -392,18 +385,16 @@ static void queryInstSources(EvalState & state, | ||||||
|            derivations). */ |            derivations). */ | ||||||
|         case srcStorePaths: { |         case srcStorePaths: { | ||||||
| 
 | 
 | ||||||
|             for (Strings::const_iterator i = args.begin(); |             foreach (Strings::const_iterator, i, args) { | ||||||
|                  i != args.end(); ++i) |  | ||||||
|             { |  | ||||||
|                 Path path = followLinksToStorePath(*i); |                 Path path = followLinksToStorePath(*i); | ||||||
| 
 | 
 | ||||||
|                 DrvInfo elem; |  | ||||||
|                 elem.attrs = new Bindings; |  | ||||||
|                 string name = baseNameOf(path); |                 string name = baseNameOf(path); | ||||||
|                 string::size_type dash = name.find('-'); |                 string::size_type dash = name.find('-'); | ||||||
|                 if (dash != string::npos) |                 if (dash != string::npos) | ||||||
|                     name = string(name, dash + 1); |                     name = string(name, dash + 1); | ||||||
| 
 | 
 | ||||||
|  |                 DrvInfo elem(state, name, "", "", 0); | ||||||
|  | 
 | ||||||
|                 if (isDerivation(path)) { |                 if (isDerivation(path)) { | ||||||
|                     elem.setDrvPath(path); |                     elem.setDrvPath(path); | ||||||
|                     elem.setOutPath(findOutput(derivationFromPath(*store, path), "out")); |                     elem.setOutPath(findOutput(derivationFromPath(*store, path), "out")); | ||||||
|  | @ -413,8 +404,6 @@ static void queryInstSources(EvalState & state, | ||||||
|                 } |                 } | ||||||
|                 else elem.setOutPath(path); |                 else elem.setOutPath(path); | ||||||
| 
 | 
 | ||||||
|                 elem.name = name; |  | ||||||
| 
 |  | ||||||
|                 elems.push_back(elem); |                 elems.push_back(elem); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  | @ -444,25 +433,24 @@ static void queryInstSources(EvalState & state, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static void printMissing(EvalState & state, const DrvInfos & elems) | static void printMissing(EvalState & state, DrvInfos & elems) | ||||||
| { | { | ||||||
|     PathSet targets; |     PathSet targets; | ||||||
|     foreach (DrvInfos::const_iterator, i, elems) { |     foreach (DrvInfos::iterator, i, elems) { | ||||||
|         Path drvPath = i->queryDrvPath(state); |         Path drvPath = i->queryDrvPath(); | ||||||
|         if (drvPath != "") |         if (drvPath != "") | ||||||
|             targets.insert(drvPath); |             targets.insert(drvPath); | ||||||
|         else |         else | ||||||
|             targets.insert(i->queryOutPath(state)); |             targets.insert(i->queryOutPath()); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     printMissing(*store, targets); |     printMissing(*store, targets); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static bool keep(MetaInfo & meta) | static bool keep(DrvInfo & drv) | ||||||
| { | { | ||||||
|     MetaValue value = meta["keep"]; |     return drv.queryMetaBool("keep", false); | ||||||
|     return value.type == MetaValue::tpString && value.stringValue == "true"; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -504,10 +492,9 @@ static void installDerivations(Globals & globals, | ||||||
| 
 | 
 | ||||||
|             foreach (DrvInfos::iterator, i, installedElems) { |             foreach (DrvInfos::iterator, i, installedElems) { | ||||||
|                 DrvName drvName(i->name); |                 DrvName drvName(i->name); | ||||||
|                 MetaInfo meta = i->queryMetaInfo(globals.state); |  | ||||||
|                 if (!globals.preserveInstalled && |                 if (!globals.preserveInstalled && | ||||||
|                     newNames.find(drvName.name) != newNames.end() && |                     newNames.find(drvName.name) != newNames.end() && | ||||||
|                     !keep(meta)) |                     !keep(*i)) | ||||||
|                     printMsg(lvlInfo, format("replacing old `%1%'") % i->name); |                     printMsg(lvlInfo, format("replacing old `%1%'") % i->name); | ||||||
|                 else |                 else | ||||||
|                     allElems.push_back(*i); |                     allElems.push_back(*i); | ||||||
|  | @ -573,8 +560,7 @@ static void upgradeDerivations(Globals & globals, | ||||||
| 
 | 
 | ||||||
|             try { |             try { | ||||||
| 
 | 
 | ||||||
|                 MetaInfo meta = i->queryMetaInfo(globals.state); |                 if (keep(*i)) { | ||||||
|                 if (keep(meta)) { |  | ||||||
|                     newElems.push_back(*i); |                     newElems.push_back(*i); | ||||||
|                     continue; |                     continue; | ||||||
|                 } |                 } | ||||||
|  | @ -611,8 +597,8 @@ static void upgradeDerivations(Globals & globals, | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 if (bestElem != availElems.end() && |                 if (bestElem != availElems.end() && | ||||||
|                     i->queryOutPath(globals.state) != |                     i->queryOutPath() != | ||||||
|                     bestElem->queryOutPath(globals.state)) |                     bestElem->queryOutPath()) | ||||||
|                 { |                 { | ||||||
|                     printMsg(lvlInfo, |                     printMsg(lvlInfo, | ||||||
|                         format("upgrading `%1%' to `%2%'") |                         format("upgrading `%1%' to `%2%'") | ||||||
|  | @ -657,12 +643,9 @@ static void opUpgrade(Globals & globals, | ||||||
| static void setMetaFlag(EvalState & state, DrvInfo & drv, | static void setMetaFlag(EvalState & state, DrvInfo & drv, | ||||||
|     const string & name, const string & value) |     const string & name, const string & value) | ||||||
| { | { | ||||||
|     MetaInfo meta = drv.queryMetaInfo(state); |     Value * v = state.allocValue(); | ||||||
|     MetaValue v; |     mkString(*v, value.c_str()); | ||||||
|     v.type = MetaValue::tpString; |     drv.setMeta(name, v); | ||||||
|     v.stringValue = value; |  | ||||||
|     meta[name] = v; |  | ||||||
|     drv.setMetaInfo(meta); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -689,8 +672,7 @@ static void opSetFlag(Globals & globals, | ||||||
|             DrvName drvName(i->name); |             DrvName drvName(i->name); | ||||||
|             foreach (DrvNames::iterator, j, selectors) |             foreach (DrvNames::iterator, j, selectors) | ||||||
|                 if (j->matches(drvName)) { |                 if (j->matches(drvName)) { | ||||||
|                     printMsg(lvlInfo, |                     printMsg(lvlInfo, format("setting flag on `%1%'") % i->name); | ||||||
|                         format("setting flag on `%1%'") % i->name); |  | ||||||
|                     setMetaFlag(globals.state, *i, flagName, flagValue); |                     setMetaFlag(globals.state, *i, flagName, flagValue); | ||||||
|                     break; |                     break; | ||||||
|                 } |                 } | ||||||
|  | @ -720,20 +702,20 @@ static void opSet(Globals & globals, | ||||||
| 
 | 
 | ||||||
|     DrvInfo & drv(elems.front()); |     DrvInfo & drv(elems.front()); | ||||||
| 
 | 
 | ||||||
|     if (drv.queryDrvPath(globals.state) != "") { |     if (drv.queryDrvPath() != "") { | ||||||
|         PathSet paths = singleton<PathSet>(drv.queryDrvPath(globals.state)); |         PathSet paths = singleton<PathSet>(drv.queryDrvPath()); | ||||||
|         printMissing(*store, paths); |         printMissing(*store, paths); | ||||||
|         if (globals.dryRun) return; |         if (globals.dryRun) return; | ||||||
|         store->buildPaths(paths, globals.state.repair); |         store->buildPaths(paths, globals.state.repair); | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|         printMissing(*store, singleton<PathSet>(drv.queryOutPath(globals.state))); |         printMissing(*store, singleton<PathSet>(drv.queryOutPath())); | ||||||
|         if (globals.dryRun) return; |         if (globals.dryRun) return; | ||||||
|         store->ensurePath(drv.queryOutPath(globals.state)); |         store->ensurePath(drv.queryOutPath()); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     debug(format("switching to new user environment")); |     debug(format("switching to new user environment")); | ||||||
|     Path generation = createGeneration(globals.profile, drv.queryOutPath(globals.state)); |     Path generation = createGeneration(globals.profile, drv.queryOutPath()); | ||||||
|     switchLink(globals.profile, generation); |     switchLink(globals.profile, generation); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -753,7 +735,7 @@ static void uninstallDerivations(Globals & globals, Strings & selectors, | ||||||
|             foreach (Strings::iterator, j, selectors) |             foreach (Strings::iterator, j, selectors) | ||||||
|                 /* !!! the repeated calls to followLinksToStorePath()
 |                 /* !!! the repeated calls to followLinksToStorePath()
 | ||||||
|                    are expensive, should pre-compute them. */ |                    are expensive, should pre-compute them. */ | ||||||
|                 if ((isPath(*j) && i->queryOutPath(globals.state) == followLinksToStorePath(*j)) |                 if ((isPath(*j) && i->queryOutPath() == followLinksToStorePath(*j)) | ||||||
|                     || DrvName(*j).matches(drvName)) |                     || DrvName(*j).matches(drvName)) | ||||||
|                 { |                 { | ||||||
|                     printMsg(lvlInfo, format("uninstalling `%1%'") % i->name); |                     printMsg(lvlInfo, format("uninstalling `%1%'") % i->name); | ||||||
|  | @ -887,18 +869,12 @@ static void queryJSON(Globals & globals, vector<DrvInfo> & elems) | ||||||
| 
 | 
 | ||||||
|         pkgObj.attr("meta"); |         pkgObj.attr("meta"); | ||||||
|         JSONObject metaObj(cout); |         JSONObject metaObj(cout); | ||||||
|         MetaInfo meta = i->queryMetaInfo(globals.state); |         StringSet metaNames = i->queryMetaNames(); | ||||||
|         foreach (MetaInfo::iterator, j, meta) { |         foreach (StringSet::iterator, j, metaNames) { | ||||||
|             metaObj.attr(j->first); |             metaObj.attr(*j); | ||||||
|             if (j->second.type == MetaValue::tpString) { |             Value * v = i->queryMeta(*j); | ||||||
|                 escapeJSON(cout, j->second.stringValue); |             PathSet context; | ||||||
|             } else if (j->second.type == MetaValue::tpInt) { |             printValueAsJSON(globals.state, true, *v, cout, context); | ||||||
|                 cout << j->second.intValue; |  | ||||||
|             } else if (j->second.type == MetaValue::tpStrings) { |  | ||||||
|                 JSONList l(cout); |  | ||||||
|                 foreach (Strings::iterator, k, j->second.stringValues) |  | ||||||
|                     l.elem(*k); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | @ -983,7 +959,7 @@ static void opQuery(Globals & globals, | ||||||
|     if (printStatus) { |     if (printStatus) { | ||||||
|         for (DrvInfos::iterator i = installedElems.begin(); |         for (DrvInfos::iterator i = installedElems.begin(); | ||||||
|              i != installedElems.end(); ++i) |              i != installedElems.end(); ++i) | ||||||
|             installed.insert(i->queryOutPath(globals.state)); |             installed.insert(i->queryOutPath()); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -993,7 +969,7 @@ static void opQuery(Globals & globals, | ||||||
|         PathSet paths; |         PathSet paths; | ||||||
|         foreach (vector<DrvInfo>::iterator, i, elems) |         foreach (vector<DrvInfo>::iterator, i, elems) | ||||||
|             try { |             try { | ||||||
|                 paths.insert(i->queryOutPath(globals.state)); |                 paths.insert(i->queryOutPath()); | ||||||
|             } catch (AssertionError & e) { |             } catch (AssertionError & e) { | ||||||
|                 printMsg(lvlTalkative, format("skipping derivation named `%1%' which gives an assertion failure") % i->name); |                 printMsg(lvlTalkative, format("skipping derivation named `%1%' which gives an assertion failure") % i->name); | ||||||
|                 i->setFailed(); |                 i->setFailed(); | ||||||
|  | @ -1021,8 +997,8 @@ static void opQuery(Globals & globals, | ||||||
|             startNest(nest, lvlDebug, format("outputting query result `%1%'") % i->attrPath); |             startNest(nest, lvlDebug, format("outputting query result `%1%'") % i->attrPath); | ||||||
| 
 | 
 | ||||||
|             if (globals.prebuiltOnly && |             if (globals.prebuiltOnly && | ||||||
|                 validPaths.find(i->queryOutPath(globals.state)) == validPaths.end() && |                 validPaths.find(i->queryOutPath()) == validPaths.end() && | ||||||
|                 substitutablePaths.find(i->queryOutPath(globals.state)) == substitutablePaths.end()) |                 substitutablePaths.find(i->queryOutPath()) == substitutablePaths.end()) | ||||||
|                 continue; |                 continue; | ||||||
| 
 | 
 | ||||||
|             /* For table output. */ |             /* For table output. */ | ||||||
|  | @ -1032,7 +1008,7 @@ static void opQuery(Globals & globals, | ||||||
|             XMLAttrs attrs; |             XMLAttrs attrs; | ||||||
| 
 | 
 | ||||||
|             if (printStatus) { |             if (printStatus) { | ||||||
|                 Path outPath = i->queryOutPath(globals.state); |                 Path outPath = i->queryOutPath(); | ||||||
|                 bool hasSubs = substitutablePaths.find(outPath) != substitutablePaths.end(); |                 bool hasSubs = substitutablePaths.find(outPath) != substitutablePaths.end(); | ||||||
|                 bool isInstalled = installed.find(outPath) != installed.end(); |                 bool isInstalled = installed.find(outPath) != installed.end(); | ||||||
|                 bool isValid = validPaths.find(outPath) != validPaths.end(); |                 bool isValid = validPaths.find(outPath) != validPaths.end(); | ||||||
|  | @ -1093,7 +1069,7 @@ static void opQuery(Globals & globals, | ||||||
|                 columns.push_back(i->system); |                 columns.push_back(i->system); | ||||||
| 
 | 
 | ||||||
|             if (printDrvPath) { |             if (printDrvPath) { | ||||||
|                 string drvPath = i->queryDrvPath(globals.state); |                 string drvPath = i->queryDrvPath(); | ||||||
|                 if (xmlOutput) { |                 if (xmlOutput) { | ||||||
|                     if (drvPath != "") attrs["drvPath"] = drvPath; |                     if (drvPath != "") attrs["drvPath"] = drvPath; | ||||||
|                 } else |                 } else | ||||||
|  | @ -1101,7 +1077,7 @@ static void opQuery(Globals & globals, | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if (printOutPath && !xmlOutput) { |             if (printOutPath && !xmlOutput) { | ||||||
|                 DrvInfo::Outputs outputs = i->queryOutputs(globals.state); |                 DrvInfo::Outputs outputs = i->queryOutputs(); | ||||||
|                 string s; |                 string s; | ||||||
|                 foreach (DrvInfo::Outputs::iterator, j, outputs) { |                 foreach (DrvInfo::Outputs::iterator, j, outputs) { | ||||||
|                     if (!s.empty()) s += ';'; |                     if (!s.empty()) s += ';'; | ||||||
|  | @ -1112,9 +1088,7 @@ static void opQuery(Globals & globals, | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if (printDescription) { |             if (printDescription) { | ||||||
|                 MetaInfo meta = i->queryMetaInfo(globals.state); |                 string descr = i->queryMetaString("description"); | ||||||
|                 MetaValue value = meta["description"]; |  | ||||||
|                 string descr = value.type == MetaValue::tpString ? value.stringValue : ""; |  | ||||||
|                 if (xmlOutput) { |                 if (xmlOutput) { | ||||||
|                     if (descr != "") attrs["description"] = descr; |                     if (descr != "") attrs["description"] = descr; | ||||||
|                 } else |                 } else | ||||||
|  | @ -1125,7 +1099,7 @@ static void opQuery(Globals & globals, | ||||||
|                 if (printOutPath || printMeta) { |                 if (printOutPath || printMeta) { | ||||||
|                     XMLOpenElement item(xml, "item", attrs); |                     XMLOpenElement item(xml, "item", attrs); | ||||||
|                     if (printOutPath) { |                     if (printOutPath) { | ||||||
|                         DrvInfo::Outputs outputs = i->queryOutputs(globals.state); |                         DrvInfo::Outputs outputs = i->queryOutputs(); | ||||||
|                         foreach (DrvInfo::Outputs::iterator, j, outputs) { |                         foreach (DrvInfo::Outputs::iterator, j, outputs) { | ||||||
|                             XMLAttrs attrs2; |                             XMLAttrs attrs2; | ||||||
|                             attrs2["name"] = j->first; |                             attrs2["name"] = j->first; | ||||||
|  | @ -1134,26 +1108,32 @@ static void opQuery(Globals & globals, | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                     if (printMeta) { |                     if (printMeta) { | ||||||
|                         MetaInfo meta = i->queryMetaInfo(globals.state); |                         StringSet metaNames = i->queryMetaNames(); | ||||||
|                         foreach (MetaInfo::iterator, j, meta) { |                         foreach (StringSet::iterator, j, metaNames) { | ||||||
|                             XMLAttrs attrs2; |                             XMLAttrs attrs2; | ||||||
|                             attrs2["name"] = j->first; |                             attrs2["name"] = *j; | ||||||
|                             if (j->second.type == MetaValue::tpString) { |                             Value & v(*i->queryMeta(*j)); | ||||||
|  |                             if (v.type == tString) { | ||||||
|                                 attrs2["type"] = "string"; |                                 attrs2["type"] = "string"; | ||||||
|                                 attrs2["value"] = j->second.stringValue; |                                 attrs2["value"] = v.string.s; | ||||||
|                                 xml.writeEmptyElement("meta", attrs2); |                                 xml.writeEmptyElement("meta", attrs2); | ||||||
|                             } else if (j->second.type == MetaValue::tpInt) { |                             } else if (v.type == tInt) { | ||||||
|                                 attrs2["type"] = "int"; |                                 attrs2["type"] = "int"; | ||||||
|                                 attrs2["value"] = (format("%1%") % j->second.intValue).str(); |                                 attrs2["value"] = (format("%1%") % v.integer).str(); | ||||||
|                                 xml.writeEmptyElement("meta", attrs2); |                                 xml.writeEmptyElement("meta", attrs2); | ||||||
|                             } else if (j->second.type == MetaValue::tpStrings) { |                             } else if (v.type == tBool) { | ||||||
|  |                                 attrs2["type"] = "bool"; | ||||||
|  |                                 attrs2["value"] = v.boolean ? "true" : "false"; | ||||||
|  |                                 xml.writeEmptyElement("meta", attrs2); | ||||||
|  |                             } else if (v.type == tList) { | ||||||
|                                 attrs2["type"] = "strings"; |                                 attrs2["type"] = "strings"; | ||||||
|                                 XMLOpenElement m(xml, "meta", attrs2); |                                 XMLOpenElement m(xml, "meta", attrs2); | ||||||
|                                 foreach (Strings::iterator, k, j->second.stringValues) { |                                 for (unsigned int j = 0; j < v.list.length; ++j) { | ||||||
|  |                                     string s = globals.state.forceStringNoCtx(*v.list.elems[j]); | ||||||
|                                     XMLAttrs attrs3; |                                     XMLAttrs attrs3; | ||||||
|                                     attrs3["value"] = *k; |                                     attrs3["value"] = s; | ||||||
|                                     xml.writeEmptyElement("string", attrs3); |                                     xml.writeEmptyElement("string", attrs3); | ||||||
|                                } |                                 } | ||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|  | @ -1166,6 +1146,9 @@ static void opQuery(Globals & globals, | ||||||
| 
 | 
 | ||||||
|         } catch (AssertionError & e) { |         } catch (AssertionError & e) { | ||||||
|             printMsg(lvlTalkative, format("skipping derivation named `%1%' which gives an assertion failure") % i->name); |             printMsg(lvlTalkative, format("skipping derivation named `%1%' which gives an assertion failure") % i->name); | ||||||
|  |         } catch (Error & e) { | ||||||
|  |             e.addPrefix(format("while querying the derivation named `%1%':\n") % i->name); | ||||||
|  |             throw; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -5,6 +5,7 @@ | ||||||
| #include "globals.hh" | #include "globals.hh" | ||||||
| #include "shared.hh" | #include "shared.hh" | ||||||
| #include "eval.hh" | #include "eval.hh" | ||||||
|  | #include "eval-inline.hh" | ||||||
| #include "profiles.hh" | #include "profiles.hh" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -32,9 +33,9 @@ bool createUserEnv(EvalState & state, DrvInfos & elems, | ||||||
|     /* Build the components in the user environment, if they don't
 |     /* Build the components in the user environment, if they don't
 | ||||||
|        exist already. */ |        exist already. */ | ||||||
|     PathSet drvsToBuild; |     PathSet drvsToBuild; | ||||||
|     foreach (DrvInfos::const_iterator, i, elems) |     foreach (DrvInfos::iterator, i, elems) | ||||||
|         if (i->queryDrvPath(state) != "") |         if (i->queryDrvPath() != "") | ||||||
|             drvsToBuild.insert(i->queryDrvPath(state)); |             drvsToBuild.insert(i->queryDrvPath()); | ||||||
| 
 | 
 | ||||||
|     debug(format("building user environment dependencies")); |     debug(format("building user environment dependencies")); | ||||||
|     store->buildPaths(drvsToBuild, state.repair); |     store->buildPaths(drvsToBuild, state.repair); | ||||||
|  | @ -48,7 +49,7 @@ bool createUserEnv(EvalState & state, DrvInfos & elems, | ||||||
|         /* Create a pseudo-derivation containing the name, system,
 |         /* Create a pseudo-derivation containing the name, system,
 | ||||||
|            output paths, and optionally the derivation path, as well |            output paths, and optionally the derivation path, as well | ||||||
|            as the meta attributes. */ |            as the meta attributes. */ | ||||||
|         Path drvPath = keepDerivations ? i->queryDrvPath(state) : ""; |         Path drvPath = keepDerivations ? i->queryDrvPath() : ""; | ||||||
| 
 | 
 | ||||||
|         Value & v(*state.allocValue()); |         Value & v(*state.allocValue()); | ||||||
|         manifest.list.elems[n++] = &v; |         manifest.list.elems[n++] = &v; | ||||||
|  | @ -58,12 +59,12 @@ bool createUserEnv(EvalState & state, DrvInfos & elems, | ||||||
|         mkString(*state.allocAttr(v, state.sName), i->name); |         mkString(*state.allocAttr(v, state.sName), i->name); | ||||||
|         if (!i->system.empty()) |         if (!i->system.empty()) | ||||||
|             mkString(*state.allocAttr(v, state.sSystem), i->system); |             mkString(*state.allocAttr(v, state.sSystem), i->system); | ||||||
|         mkString(*state.allocAttr(v, state.sOutPath), i->queryOutPath(state)); |         mkString(*state.allocAttr(v, state.sOutPath), i->queryOutPath()); | ||||||
|         if (drvPath != "") |         if (drvPath != "") | ||||||
|             mkString(*state.allocAttr(v, state.sDrvPath), i->queryDrvPath(state)); |             mkString(*state.allocAttr(v, state.sDrvPath), i->queryDrvPath()); | ||||||
| 
 | 
 | ||||||
|         // Copy each output.
 |         // Copy each output.
 | ||||||
|         DrvInfo::Outputs outputs = i->queryOutputs(state); |         DrvInfo::Outputs outputs = i->queryOutputs(); | ||||||
|         Value & vOutputs = *state.allocAttr(v, state.sOutputs); |         Value & vOutputs = *state.allocAttr(v, state.sOutputs); | ||||||
|         state.mkList(vOutputs, outputs.size()); |         state.mkList(vOutputs, outputs.size()); | ||||||
|         unsigned int m = 0; |         unsigned int m = 0; | ||||||
|  | @ -84,28 +85,12 @@ bool createUserEnv(EvalState & state, DrvInfos & elems, | ||||||
|         // Copy the meta attributes.
 |         // Copy the meta attributes.
 | ||||||
|         Value & vMeta = *state.allocAttr(v, state.sMeta); |         Value & vMeta = *state.allocAttr(v, state.sMeta); | ||||||
|         state.mkAttrs(vMeta, 16); |         state.mkAttrs(vMeta, 16); | ||||||
| 
 |         StringSet metaNames = i->queryMetaNames(); | ||||||
|         MetaInfo meta = i->queryMetaInfo(state); |         foreach (StringSet::iterator, j, metaNames) { | ||||||
| 
 |             Value * v = i->queryMeta(*j); | ||||||
|         foreach (MetaInfo::const_iterator, j, meta) { |             state.strictForceValue(*v); // FIXME
 | ||||||
|             Value & v2(*state.allocAttr(vMeta, state.symbols.create(j->first))); |             vMeta.attrs->push_back(Attr(state.symbols.create(*j), v)); | ||||||
|             switch (j->second.type) { |  | ||||||
|                 case MetaValue::tpInt: mkInt(v2, j->second.intValue); break; |  | ||||||
|                 case MetaValue::tpString: mkString(v2, j->second.stringValue); break; |  | ||||||
|                 case MetaValue::tpStrings: { |  | ||||||
|                     state.mkList(v2, j->second.stringValues.size()); |  | ||||||
|                     unsigned int m = 0; |  | ||||||
|                     foreach (Strings::const_iterator, k, j->second.stringValues) { |  | ||||||
|                         v2.list.elems[m] = state.allocValue(); |  | ||||||
|                         mkString(*v2.list.elems[m++], *k); |  | ||||||
|                     } |  | ||||||
|                     break; |  | ||||||
|                 } |  | ||||||
|                 default: abort(); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
| 
 |  | ||||||
|         vMeta.attrs->sort(); |  | ||||||
|         v.attrs->sort(); |         v.attrs->sort(); | ||||||
| 
 | 
 | ||||||
|         if (drvPath != "") references.insert(drvPath); |         if (drvPath != "") references.insert(drvPath); | ||||||
|  | @ -133,13 +118,14 @@ bool createUserEnv(EvalState & state, DrvInfos & elems, | ||||||
| 
 | 
 | ||||||
|     /* Evaluate it. */ |     /* Evaluate it. */ | ||||||
|     debug("evaluating user environment builder"); |     debug("evaluating user environment builder"); | ||||||
|     DrvInfo topLevelDrv; |     state.forceValue(topLevel); | ||||||
|     if (!getDerivation(state, topLevel, topLevelDrv, false)) |     PathSet context; | ||||||
|         abort(); |     Path topLevelDrv = state.coerceToPath(*topLevel.attrs->find(state.sDrvPath)->value, context); | ||||||
|  |     Path topLevelOut = state.coerceToPath(*topLevel.attrs->find(state.sOutPath)->value, context); | ||||||
| 
 | 
 | ||||||
|     /* Realise the resulting store expression. */ |     /* Realise the resulting store expression. */ | ||||||
|     debug("building user environment"); |     debug("building user environment"); | ||||||
|     store->buildPaths(singleton<PathSet>(topLevelDrv.queryDrvPath(state)), state.repair); |     store->buildPaths(singleton<PathSet>(topLevelDrv), state.repair); | ||||||
| 
 | 
 | ||||||
|     /* Switch the current user environment to the output path. */ |     /* Switch the current user environment to the output path. */ | ||||||
|     PathLocks lock; |     PathLocks lock; | ||||||
|  | @ -152,7 +138,7 @@ bool createUserEnv(EvalState & state, DrvInfos & elems, | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     debug(format("switching to new user environment")); |     debug(format("switching to new user environment")); | ||||||
|     Path generation = createGeneration(profile, topLevelDrv.queryOutPath(state)); |     Path generation = createGeneration(profile, topLevelOut); | ||||||
|     switchLink(profile, generation); |     switchLink(profile, generation); | ||||||
| 
 | 
 | ||||||
|     return true; |     return true; | ||||||
|  |  | ||||||
|  | @ -63,10 +63,10 @@ void processExpr(EvalState & state, const Strings & attrPaths, | ||||||
|             DrvInfos drvs; |             DrvInfos drvs; | ||||||
|             getDerivations(state, v, "", autoArgs, drvs, false); |             getDerivations(state, v, "", autoArgs, drvs, false); | ||||||
|             foreach (DrvInfos::iterator, i, drvs) { |             foreach (DrvInfos::iterator, i, drvs) { | ||||||
|                 Path drvPath = i->queryDrvPath(state); |                 Path drvPath = i->queryDrvPath(); | ||||||
| 
 | 
 | ||||||
|                 /* What output do we want? */ |                 /* What output do we want? */ | ||||||
|                 string outputName = i->queryOutputName(state); |                 string outputName = i->queryOutputName(); | ||||||
|                 if (outputName == "") |                 if (outputName == "") | ||||||
|                     throw Error(format("derivation `%1%' lacks an `outputName' attribute ") % drvPath); |                     throw Error(format("derivation `%1%' lacks an `outputName' attribute ") % drvPath); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue