From abec1c000410a1533f9c80357be6061730d8c6aa Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 25 Aug 2008 14:31:29 +0000 Subject: [PATCH] * Evaluate attributes in sorted order for better determinism. --- src/libexpr/get-drvs.cc | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc index 55092ea9b..84f8ddf9b 100644 --- a/src/libexpr/get-drvs.cc +++ b/src/libexpr/get-drvs.cc @@ -175,19 +175,28 @@ static void getDerivations(EvalState & state, Expr e, nix-env.cc. */ bool combineChannels = drvMap.get(toATerm("_combineChannels")); - for (ATermMap::const_iterator i = drvMap.begin(); i != drvMap.end(); ++i) { - startNest(nest, lvlDebug, - format("evaluating attribute `%1%'") % aterm2String(i->key)); - string pathPrefix2 = addToPath(pathPrefix, aterm2String(i->key)); + /* Consider the attributes in sorted order to get more + deterministic behaviour in nix-env operations (e.g. when + there are names clashes between derivations, the derivation + bound to the attribute with the "lower" name should take + precedence). */ + typedef std::map AttrsSorted; + AttrsSorted attrsSorted; + foreach (ATermMap::const_iterator, i, drvMap) + attrsSorted[aterm2String(i->key)] = i->value; + + foreach (AttrsSorted::iterator, i, attrsSorted) { + startNest(nest, lvlDebug, format("evaluating attribute `%1%'") % i->first); + string pathPrefix2 = addToPath(pathPrefix, i->first); if (combineChannels) - getDerivations(state, i->value, pathPrefix2, autoArgs, drvs, doneExprs); - else if (getDerivation(state, i->value, pathPrefix2, drvs, doneExprs)) { + getDerivations(state, i->second, pathPrefix2, autoArgs, drvs, doneExprs); + else if (getDerivation(state, i->second, pathPrefix2, drvs, doneExprs)) { /* If the value of this attribute is itself an attribute set, should we recurse into it? => Only if it has a `recurseForDerivations = true' attribute. */ ATermList es; - Expr e = evalExpr(state, i->value), e2; + Expr e = evalExpr(state, i->second), e2; if (matchAttrs(e, es)) { ATermMap attrs(ATgetLength(es)); queryAllAttrs(e, attrs, false);