diff options
author | Eelco Dolstra <e.dolstra@tudelft.nl> | 2006-02-10 17:25:59 +0000 |
---|---|---|
committer | Eelco Dolstra <e.dolstra@tudelft.nl> | 2006-02-10 17:25:59 +0000 |
commit | c6120352b3fd25380ff21726982e22b97ee43e0b (patch) | |
tree | 5d8ac14dd44ef25ea0bf3a53490dbe9f31969793 /src/libexpr/get-drvs.cc | |
parent | b505f9eaf57c7badeacb176a1946b5f5f145f816 (diff) |
* In nix-instantiate, allow us to specify a "path" to the
derivation(s) we're interested, e.g.,
$ nix-instantiate ./all-packages.nix --attr xlibs.libX11
List elements can also be selected:
$ nix-instantiate ./build-for-release.nix --attr 0.subversion
This allows a non-ambiguous specification of a derivation. Of
course, this should also be added to nix-env and nix-build.
Diffstat (limited to 'src/libexpr/get-drvs.cc')
-rw-r--r-- | src/libexpr/get-drvs.cc | 100 |
1 files changed, 74 insertions, 26 deletions
diff --git a/src/libexpr/get-drvs.cc b/src/libexpr/get-drvs.cc index eaab867a6..fbcbb9014 100644 --- a/src/libexpr/get-drvs.cc +++ b/src/libexpr/get-drvs.cc @@ -53,49 +53,96 @@ bool getDerivation(EvalState & state, Expr e, DrvInfo & drv) static void getDerivations(EvalState & state, Expr e, - DrvInfos & drvs, Exprs & doneExprs) + DrvInfos & drvs, Exprs & doneExprs, const string & attrPath) { + /* Automatically call functions that have defaults for all + arguments. */ + ATermList formals; + ATerm body, pos; + if (matchFunction(e, formals, body, pos)) { + for (ATermIterator i(formals); i; ++i) { + Expr name, def; + if (matchNoDefFormal(*i, name)) + throw Error(format("expression evaluates to a function with no-default arguments (`%1%')") + % aterm2String(name)); + else if (!matchDefFormal(*i, name, def)) + abort(); /* can't happen */ + } + getDerivations(state, + makeCall(e, makeAttrs(ATermMap())), + drvs, doneExprs, attrPath); + return; + } + + /* Parse the start of attrPath. */ + enum { apNone, apAttr, apIndex } apType; + string attrPathRest; + string attr; + int attrIndex; + Error attrError = + Error(format("attribute selection path `%1%' does not match expression") % attrPath); + + if (attrPath.empty()) + apType = apNone; + else { + string::size_type dot = attrPath.find("."); + if (dot == string::npos) { + attrPathRest = ""; + attr = attrPath; + } else { + attrPathRest = string(attrPath, dot + 1); + attr = string(attrPath, 0, dot); + } + apType = apAttr; + if (string2Int(attr, attrIndex)) apType = apIndex; + } + + /* Process the expression. */ ATermList es; DrvInfo drv; e = evalExpr(state, e); - if (getDerivation(state, e, drv)) { - drvs.push_back(drv); + if (getDerivation(state, e, drvs, doneExprs)) { + if (apType != apNone) throw attrError; return; } if (matchAttrs(e, es)) { + if (apType != apNone && apType != apAttr) throw attrError; ATermMap drvMap; queryAllAttrs(e, drvMap); - for (ATermIterator i(drvMap.keys()); i; ++i) { - debug(format("evaluating attribute `%1%'") % aterm2String(*i)); - getDerivation(state, drvMap.get(*i), drvs, doneExprs); + if (apType == apNone) { + for (ATermIterator i(drvMap.keys()); i; ++i) { + debug(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); + getDerivation(state, e2, drvs, doneExprs); + if (!attrPath.empty()) + getDerivations(state, e2, drvs, doneExprs, attrPathRest); } return; } if (matchList(e, es)) { - for (ATermIterator i(es); i; ++i) { + if (apType != apNone && apType != apIndex) throw attrError; + if (apType == apNone) { + for (ATermIterator i(es); i; ++i) { + debug(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")); - if (!getDerivation(state, *i, drvs, doneExprs)) - getDerivations(state, *i, drvs, doneExprs); - } - return; - } - - ATermList formals; - ATerm body, pos; - if (matchFunction(e, formals, body, pos)) { - for (ATermIterator i(formals); i; ++i) { - Expr name, def; - if (matchNoDefFormal(*i, name)) - throw Error(format("expression evaluates to a function with no-default arguments (`%1%')") - % aterm2String(name)); - else if (!matchDefFormal(*i, name, def)) - abort(); /* can't happen */ + if (!getDerivation(state, e2, drvs, doneExprs)) + getDerivations(state, e2, drvs, doneExprs, attrPathRest); } - getDerivations(state, makeCall(e, makeAttrs(ATermMap())), drvs, doneExprs); return; } @@ -103,8 +150,9 @@ static void getDerivations(EvalState & state, Expr e, } -void getDerivations(EvalState & state, Expr e, DrvInfos & drvs) +void getDerivations(EvalState & state, Expr e, DrvInfos & drvs, + const string & attrPath) { Exprs doneExprs; - getDerivations(state, e, drvs, doneExprs); + getDerivations(state, e, drvs, doneExprs, attrPath); } |