* 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:
Eelco Dolstra 2006-03-08 16:03:58 +00:00
parent 9088dee9e2
commit 6dca5c9099
3 changed files with 98 additions and 70 deletions

View file

@ -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;
} }

View file

@ -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);
} }

View file

@ -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);
} }