* When obtaining derivations from Nix expressions, ignore all
expressions that cause an assertion failure (like `assert system == "i686-linux"'). This allows all-packages.nix in Nixpkgs to be used on all platforms, even if some Nix expressions don't work on all platforms. Not sure if this is a good idea; it's a bit hacky. In particular, due to laziness some derivations might appear in `nix-env -qa' but disappear in `nix-env -qas' or `nix-env -i'. Commit 5000!
This commit is contained in:
		
							parent
							
								
									9088dee9e2
								
							
						
					
					
						commit
						6dca5c9099
					
				
					 3 changed files with 98 additions and 70 deletions
				
			
		|  | @ -383,7 +383,13 @@ Expr evalExpr(EvalState & state, Expr e) | |||
| 
 | ||||
|     /* Otherwise, evaluate and memoize. */ | ||||
|     state.normalForms.set(e, state.blackHole); | ||||
|     nf = evalExpr2(state, e); | ||||
|     try { | ||||
|         nf = evalExpr2(state, e); | ||||
|     } catch (Error & err) { | ||||
|         debug("removing black hole"); | ||||
|         state.normalForms.remove(e); | ||||
|         throw; | ||||
|     } | ||||
|     state.normalForms.set(e, nf); | ||||
|     return nf; | ||||
| } | ||||
|  |  | |||
|  | @ -5,40 +5,51 @@ | |||
| typedef set<Expr> Exprs; | ||||
| 
 | ||||
| 
 | ||||
| /* Evaluate expression `e'.  If it evaluates to an attribute 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 for the caller to recursively search for derivations | ||||
|    in `e'. */ | ||||
| static bool getDerivation(EvalState & state, Expr e, | ||||
|     DrvInfos & drvs, Exprs & doneExprs) | ||||
| { | ||||
|     ATermList es; | ||||
|     e = evalExpr(state, e); | ||||
|     if (!matchAttrs(e, es)) return false; | ||||
|     try { | ||||
|          | ||||
|         ATermList es; | ||||
|         e = evalExpr(state, e); | ||||
|         if (!matchAttrs(e, es)) return true; | ||||
| 
 | ||||
|     ATermMap attrs; | ||||
|     queryAllAttrs(e, attrs, false); | ||||
|         ATermMap attrs; | ||||
|         queryAllAttrs(e, attrs, false); | ||||
|      | ||||
|     Expr a = attrs.get("type"); | ||||
|     if (!a || evalString(state, a) != "derivation") return false; | ||||
|         Expr a = attrs.get("type"); | ||||
|         if (!a || evalString(state, a) != "derivation") return true; | ||||
| 
 | ||||
|     /* Remove spurious duplicates (e.g., an attribute set like `rec {
 | ||||
|        x = derivation {...}; y = x;}'. */ | ||||
|     if (doneExprs.find(e) != doneExprs.end()) return true; | ||||
|     doneExprs.insert(e); | ||||
|         /* Remove spurious duplicates (e.g., an attribute set like
 | ||||
|            `rec { x = derivation {...}; y = x;}'. */ | ||||
|         if (doneExprs.find(e) != doneExprs.end()) return false; | ||||
|         doneExprs.insert(e); | ||||
| 
 | ||||
|     DrvInfo drv; | ||||
|         DrvInfo drv; | ||||
|      | ||||
|     a = attrs.get("name"); | ||||
|     if (!a) throw badTerm("derivation name missing", e); | ||||
|     drv.name = evalString(state, a); | ||||
|         a = attrs.get("name"); | ||||
|         if (!a) throw badTerm("derivation name missing", e); | ||||
|         drv.name = evalString(state, a); | ||||
| 
 | ||||
|     a = attrs.get("system"); | ||||
|     if (!a) | ||||
|         drv.system = "unknown"; | ||||
|     else | ||||
|         drv.system = evalString(state, a); | ||||
|         a = attrs.get("system"); | ||||
|         if (!a) | ||||
|             drv.system = "unknown"; | ||||
|         else | ||||
|             drv.system = evalString(state, a); | ||||
| 
 | ||||
|     drv.attrs = attrs; | ||||
|         drv.attrs = attrs; | ||||
| 
 | ||||
|     drvs.push_back(drv); | ||||
|     return true; | ||||
|         drvs.push_back(drv); | ||||
|         return false; | ||||
|      | ||||
|     } catch (AssertionError & e) { | ||||
|         return false; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -46,9 +57,10 @@ bool getDerivation(EvalState & state, Expr e, DrvInfo & drv) | |||
| { | ||||
|     Exprs doneExprs; | ||||
|     DrvInfos drvs; | ||||
|     bool result = getDerivation(state, e, drvs, doneExprs); | ||||
|     if (result) drv = drvs.front(); | ||||
|     return result; | ||||
|     getDerivation(state, e, drvs, doneExprs); | ||||
|     if (drvs.size() != 1) return false; | ||||
|     drv = drvs.front(); | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -101,26 +113,28 @@ static void getDerivations(EvalState & state, Expr e, | |||
|     ATermList es; | ||||
|     DrvInfo drv; | ||||
| 
 | ||||
|     e = evalExpr(state, e); | ||||
| 
 | ||||
|     if (getDerivation(state, e, drvs, doneExprs)) { | ||||
|     if (!getDerivation(state, e, drvs, doneExprs)) { | ||||
|         if (apType != apNone) throw attrError; | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     e = evalExpr(state, e); | ||||
| 
 | ||||
|     if (matchAttrs(e, es)) { | ||||
|         if (apType != apNone && apType != apAttr) throw attrError; | ||||
|         ATermMap drvMap; | ||||
|         queryAllAttrs(e, drvMap); | ||||
|         if (apType == apNone) { | ||||
|             for (ATermIterator i(drvMap.keys()); i; ++i) { | ||||
|                 debug(format("evaluating attribute `%1%'") % aterm2String(*i)); | ||||
|                 startNest(nest, lvlDebug, | ||||
|                     format("evaluating attribute `%1%'") % aterm2String(*i)); | ||||
|                 getDerivation(state, drvMap.get(*i), drvs, doneExprs); | ||||
|             } | ||||
|         } else { | ||||
|             Expr e2 = drvMap.get(attr); | ||||
|             if (!e2) throw Error(format("attribute `%1%' in selection path not found") % attr); | ||||
|             debug(format("evaluating attribute `%1%'") % attr); | ||||
|             startNest(nest, lvlDebug, | ||||
|                 format("evaluating attribute `%1%'") % attr); | ||||
|             getDerivation(state, e2, drvs, doneExprs); | ||||
|             if (!attrPath.empty()) | ||||
|                 getDerivations(state, e2, drvs, doneExprs, attrPathRest); | ||||
|  | @ -132,14 +146,16 @@ static void getDerivations(EvalState & state, Expr e, | |||
|         if (apType != apNone && apType != apIndex) throw attrError; | ||||
|         if (apType == apNone) { | ||||
|             for (ATermIterator i(es); i; ++i) { | ||||
|                 debug(format("evaluating list element")); | ||||
|                 startNest(nest, lvlDebug, | ||||
|                     format("evaluating list element")); | ||||
|                 if (!getDerivation(state, *i, drvs, doneExprs)) | ||||
|                     getDerivations(state, *i, drvs, doneExprs, attrPathRest); | ||||
|             } | ||||
|         } else { | ||||
|             Expr e2 = ATelementAt(es, attrIndex); | ||||
|             if (!e2) throw Error(format("list index %1% in selection path not found") % attrIndex); | ||||
|             debug(format("evaluating list element")); | ||||
|             startNest(nest, lvlDebug, | ||||
|                 format("evaluating list element")); | ||||
|             if (!getDerivation(state, e2, drvs, doneExprs)) | ||||
|                 getDerivations(state, e2, drvs, doneExprs, attrPathRest); | ||||
|         } | ||||
|  |  | |||
|  | @ -762,47 +762,53 @@ static void opQuery(Globals & globals, | |||
|     for (vector<DrvInfo>::iterator i = elems2.begin(); | ||||
|          i != elems2.end(); ++i) | ||||
|     { | ||||
|         Strings columns; | ||||
|         try { | ||||
|              | ||||
|             Strings columns; | ||||
|          | ||||
|         if (printStatus) { | ||||
|             Substitutes subs = querySubstitutes(noTxn, i->queryOutPath(globals.state)); | ||||
|             columns.push_back( | ||||
|                 (string) (installed.find(i->queryOutPath(globals.state)) | ||||
|                     != installed.end() ? "I" : "-") | ||||
|                 + (isValidPath(i->queryOutPath(globals.state)) ? "P" : "-") | ||||
|                 + (subs.size() > 0 ? "S" : "-")); | ||||
|         } | ||||
| 
 | ||||
|         if (printName) columns.push_back(i->name); | ||||
| 
 | ||||
|         if (compareVersions) { | ||||
|             /* Compare this element against the versions of the same
 | ||||
|                named packages in either the set of available elements, | ||||
|                or the set of installed elements.  !!! This is O(N * | ||||
|                M), should be O(N * lg M). */ | ||||
|             string version; | ||||
|             VersionDiff diff = compareVersionAgainstSet(*i, otherElems, version); | ||||
|             char ch; | ||||
|             switch (diff) { | ||||
|                 case cvLess: ch = '>'; break; | ||||
|                 case cvEqual: ch = '='; break; | ||||
|                 case cvGreater: ch = '<'; break; | ||||
|                 case cvUnavail: ch = '-'; break; | ||||
|                 default: abort(); | ||||
|             if (printStatus) { | ||||
|                 Substitutes subs = querySubstitutes(noTxn, i->queryOutPath(globals.state)); | ||||
|                 columns.push_back( | ||||
|                     (string) (installed.find(i->queryOutPath(globals.state)) | ||||
|                         != installed.end() ? "I" : "-") | ||||
|                     + (isValidPath(i->queryOutPath(globals.state)) ? "P" : "-") | ||||
|                     + (subs.size() > 0 ? "S" : "-")); | ||||
|             } | ||||
|             string column = (string) "" + ch + " " + version; | ||||
|             if (diff == cvGreater) column = colorString(column); | ||||
|             columns.push_back(column); | ||||
|         } | ||||
| 
 | ||||
|         if (printSystem) columns.push_back(i->system); | ||||
|             if (printName) columns.push_back(i->name); | ||||
| 
 | ||||
|         if (printDrvPath) columns.push_back( | ||||
|             i->queryDrvPath(globals.state) == "" | ||||
|             ? "-" : i->queryDrvPath(globals.state)); | ||||
|             if (compareVersions) { | ||||
|                 /* Compare this element against the versions of the
 | ||||
|                    same named packages in either the set of available | ||||
|                    elements, or the set of installed elements.  !!! | ||||
|                    This is O(N * M), should be O(N * lg M). */ | ||||
|                 string version; | ||||
|                 VersionDiff diff = compareVersionAgainstSet(*i, otherElems, version); | ||||
|                 char ch; | ||||
|                 switch (diff) { | ||||
|                     case cvLess: ch = '>'; break; | ||||
|                     case cvEqual: ch = '='; break; | ||||
|                     case cvGreater: ch = '<'; break; | ||||
|                     case cvUnavail: ch = '-'; break; | ||||
|                     default: abort(); | ||||
|                 } | ||||
|                 string column = (string) "" + ch + " " + version; | ||||
|                 if (diff == cvGreater) column = colorString(column); | ||||
|                 columns.push_back(column); | ||||
|             } | ||||
| 
 | ||||
|             if (printSystem) columns.push_back(i->system); | ||||
| 
 | ||||
|             if (printDrvPath) columns.push_back( | ||||
|                 i->queryDrvPath(globals.state) == "" | ||||
|                 ? "-" : i->queryDrvPath(globals.state)); | ||||
|          | ||||
|         if (printOutPath) columns.push_back(i->queryOutPath(globals.state)); | ||||
|         table.push_back(columns); | ||||
|             if (printOutPath) columns.push_back(i->queryOutPath(globals.state)); | ||||
|              | ||||
|             table.push_back(columns); | ||||
|         } | ||||
|         catch (AssertionError & e) { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     printTable(table); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue