* 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. */ |     /* Otherwise, evaluate and memoize. */ | ||||||
|     state.normalForms.set(e, state.blackHole); |     state.normalForms.set(e, state.blackHole); | ||||||
|  |     try { | ||||||
|         nf = evalExpr2(state, e); |         nf = evalExpr2(state, e); | ||||||
|  |     } catch (Error & err) { | ||||||
|  |         debug("removing black hole"); | ||||||
|  |         state.normalForms.remove(e); | ||||||
|  |         throw; | ||||||
|  |     } | ||||||
|     state.normalForms.set(e, nf); |     state.normalForms.set(e, nf); | ||||||
|     return nf; |     return nf; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -5,22 +5,29 @@ | ||||||
| typedef set<Expr> Exprs; | 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, | static bool getDerivation(EvalState & state, Expr e, | ||||||
|     DrvInfos & drvs, Exprs & doneExprs) |     DrvInfos & drvs, Exprs & doneExprs) | ||||||
| { | { | ||||||
|  |     try { | ||||||
|  |          | ||||||
|         ATermList es; |         ATermList es; | ||||||
|         e = evalExpr(state, e); |         e = evalExpr(state, e); | ||||||
|     if (!matchAttrs(e, es)) return false; |         if (!matchAttrs(e, es)) return true; | ||||||
| 
 | 
 | ||||||
|         ATermMap attrs; |         ATermMap attrs; | ||||||
|         queryAllAttrs(e, attrs, false); |         queryAllAttrs(e, attrs, false); | ||||||
|      |      | ||||||
|         Expr a = attrs.get("type"); |         Expr a = attrs.get("type"); | ||||||
|     if (!a || evalString(state, a) != "derivation") return false; |         if (!a || evalString(state, a) != "derivation") return true; | ||||||
| 
 | 
 | ||||||
|     /* Remove spurious duplicates (e.g., an attribute set like `rec {
 |         /* Remove spurious duplicates (e.g., an attribute set like
 | ||||||
|        x = derivation {...}; y = x;}'. */ |            `rec { x = derivation {...}; y = x;}'. */ | ||||||
|     if (doneExprs.find(e) != doneExprs.end()) return true; |         if (doneExprs.find(e) != doneExprs.end()) return false; | ||||||
|         doneExprs.insert(e); |         doneExprs.insert(e); | ||||||
| 
 | 
 | ||||||
|         DrvInfo drv; |         DrvInfo drv; | ||||||
|  | @ -38,7 +45,11 @@ static bool getDerivation(EvalState & state, Expr e, | ||||||
|         drv.attrs = attrs; |         drv.attrs = attrs; | ||||||
| 
 | 
 | ||||||
|         drvs.push_back(drv); |         drvs.push_back(drv); | ||||||
|     return true; |         return false; | ||||||
|  |      | ||||||
|  |     } catch (AssertionError & e) { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -46,9 +57,10 @@ bool getDerivation(EvalState & state, Expr e, DrvInfo & drv) | ||||||
| { | { | ||||||
|     Exprs doneExprs; |     Exprs doneExprs; | ||||||
|     DrvInfos drvs; |     DrvInfos drvs; | ||||||
|     bool result = getDerivation(state, e, drvs, doneExprs); |     getDerivation(state, e, drvs, doneExprs); | ||||||
|     if (result) drv = drvs.front(); |     if (drvs.size() != 1) return false; | ||||||
|     return result; |     drv = drvs.front(); | ||||||
|  |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -101,26 +113,28 @@ static void getDerivations(EvalState & state, Expr e, | ||||||
|     ATermList es; |     ATermList es; | ||||||
|     DrvInfo drv; |     DrvInfo drv; | ||||||
| 
 | 
 | ||||||
|     e = evalExpr(state, e); |     if (!getDerivation(state, e, drvs, doneExprs)) { | ||||||
| 
 |  | ||||||
|     if (getDerivation(state, e, drvs, doneExprs)) { |  | ||||||
|         if (apType != apNone) throw attrError; |         if (apType != apNone) throw attrError; | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     e = evalExpr(state, e); | ||||||
|  | 
 | ||||||
|     if (matchAttrs(e, es)) { |     if (matchAttrs(e, es)) { | ||||||
|         if (apType != apNone && apType != apAttr) throw attrError; |         if (apType != apNone && apType != apAttr) throw attrError; | ||||||
|         ATermMap drvMap; |         ATermMap drvMap; | ||||||
|         queryAllAttrs(e, drvMap); |         queryAllAttrs(e, drvMap); | ||||||
|         if (apType == apNone) { |         if (apType == apNone) { | ||||||
|             for (ATermIterator i(drvMap.keys()); i; ++i) { |             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); |                 getDerivation(state, drvMap.get(*i), drvs, doneExprs); | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             Expr e2 = drvMap.get(attr); |             Expr e2 = drvMap.get(attr); | ||||||
|             if (!e2) throw Error(format("attribute `%1%' in selection path not found") % 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); |             getDerivation(state, e2, drvs, doneExprs); | ||||||
|             if (!attrPath.empty()) |             if (!attrPath.empty()) | ||||||
|                 getDerivations(state, e2, drvs, doneExprs, attrPathRest); |                 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 && apType != apIndex) throw attrError; | ||||||
|         if (apType == apNone) { |         if (apType == apNone) { | ||||||
|             for (ATermIterator i(es); i; ++i) { |             for (ATermIterator i(es); i; ++i) { | ||||||
|                 debug(format("evaluating list element")); |                 startNest(nest, lvlDebug, | ||||||
|  |                     format("evaluating list element")); | ||||||
|                 if (!getDerivation(state, *i, drvs, doneExprs)) |                 if (!getDerivation(state, *i, drvs, doneExprs)) | ||||||
|                     getDerivations(state, *i, drvs, doneExprs, attrPathRest); |                     getDerivations(state, *i, drvs, doneExprs, attrPathRest); | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             Expr e2 = ATelementAt(es, attrIndex); |             Expr e2 = ATelementAt(es, attrIndex); | ||||||
|             if (!e2) throw Error(format("list index %1% in selection path not found") % 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)) |             if (!getDerivation(state, e2, drvs, doneExprs)) | ||||||
|                 getDerivations(state, e2, drvs, doneExprs, attrPathRest); |                 getDerivations(state, e2, drvs, doneExprs, attrPathRest); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -762,6 +762,8 @@ static void opQuery(Globals & globals, | ||||||
|     for (vector<DrvInfo>::iterator i = elems2.begin(); |     for (vector<DrvInfo>::iterator i = elems2.begin(); | ||||||
|          i != elems2.end(); ++i) |          i != elems2.end(); ++i) | ||||||
|     { |     { | ||||||
|  |         try { | ||||||
|  |              | ||||||
|             Strings columns; |             Strings columns; | ||||||
|          |          | ||||||
|             if (printStatus) { |             if (printStatus) { | ||||||
|  | @ -776,10 +778,10 @@ static void opQuery(Globals & globals, | ||||||
|             if (printName) columns.push_back(i->name); |             if (printName) columns.push_back(i->name); | ||||||
| 
 | 
 | ||||||
|             if (compareVersions) { |             if (compareVersions) { | ||||||
|             /* Compare this element against the versions of the same
 |                 /* Compare this element against the versions of the
 | ||||||
|                named packages in either the set of available elements, |                    same named packages in either the set of available | ||||||
|                or the set of installed elements.  !!! This is O(N * |                    elements, or the set of installed elements.  !!! | ||||||
|                M), should be O(N * lg M). */ |                    This is O(N * M), should be O(N * lg M). */ | ||||||
|                 string version; |                 string version; | ||||||
|                 VersionDiff diff = compareVersionAgainstSet(*i, otherElems, version); |                 VersionDiff diff = compareVersionAgainstSet(*i, otherElems, version); | ||||||
|                 char ch; |                 char ch; | ||||||
|  | @ -802,8 +804,12 @@ static void opQuery(Globals & globals, | ||||||
|                 ? "-" : i->queryDrvPath(globals.state)); |                 ? "-" : i->queryDrvPath(globals.state)); | ||||||
|          |          | ||||||
|             if (printOutPath) columns.push_back(i->queryOutPath(globals.state)); |             if (printOutPath) columns.push_back(i->queryOutPath(globals.state)); | ||||||
|  |              | ||||||
|             table.push_back(columns); |             table.push_back(columns); | ||||||
|         } |         } | ||||||
|  |         catch (AssertionError & e) { | ||||||
|  |         } | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     printTable(table); |     printTable(table); | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue