From 6dca5c9099b92b6a93071197aa606a31ccd83a37 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 8 Mar 2006 16:03:58 +0000 Subject: [PATCH] * 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! --- src/libexpr/eval.cc | 8 +++- src/libexpr/get-drvs.cc | 82 ++++++++++++++++++++++++----------------- src/nix-env/main.cc | 78 +++++++++++++++++++++------------------ 3 files changed, 98 insertions(+), 70 deletions(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 045e5f632f..eac13c3fd9 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -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; } diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc index fbcbb90140..d3ec6bf6cf 100644 --- a/src/libexpr/get-drvs.cc +++ b/src/libexpr/get-drvs.cc @@ -5,40 +5,51 @@ typedef set 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); } diff --git a/src/nix-env/main.cc b/src/nix-env/main.cc index 8648e4f0f8..1266c50117 100644 --- a/src/nix-env/main.cc +++ b/src/nix-env/main.cc @@ -762,47 +762,53 @@ static void opQuery(Globals & globals, for (vector::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);