* 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.
This commit is contained in:
parent
b505f9eaf5
commit
c6120352b3
3 changed files with 94 additions and 38 deletions
|
@ -53,37 +53,10 @@ bool getDerivation(EvalState & state, Expr e, DrvInfo & drv)
|
||||||
|
|
||||||
|
|
||||||
static void getDerivations(EvalState & state, Expr e,
|
static void getDerivations(EvalState & state, Expr e,
|
||||||
DrvInfos & drvs, Exprs & doneExprs)
|
DrvInfos & drvs, Exprs & doneExprs, const string & attrPath)
|
||||||
{
|
{
|
||||||
ATermList es;
|
/* Automatically call functions that have defaults for all
|
||||||
DrvInfo drv;
|
arguments. */
|
||||||
|
|
||||||
e = evalExpr(state, e);
|
|
||||||
|
|
||||||
if (getDerivation(state, e, drv)) {
|
|
||||||
drvs.push_back(drv);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (matchAttrs(e, es)) {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (matchList(e, es)) {
|
|
||||||
for (ATermIterator i(es); i; ++i) {
|
|
||||||
debug(format("evaluating list element"));
|
|
||||||
if (!getDerivation(state, *i, drvs, doneExprs))
|
|
||||||
getDerivations(state, *i, drvs, doneExprs);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ATermList formals;
|
ATermList formals;
|
||||||
ATerm body, pos;
|
ATerm body, pos;
|
||||||
if (matchFunction(e, formals, body, pos)) {
|
if (matchFunction(e, formals, body, pos)) {
|
||||||
|
@ -95,7 +68,81 @@ static void getDerivations(EvalState & state, Expr e,
|
||||||
else if (!matchDefFormal(*i, name, def))
|
else if (!matchDefFormal(*i, name, def))
|
||||||
abort(); /* can't happen */
|
abort(); /* can't happen */
|
||||||
}
|
}
|
||||||
getDerivations(state, makeCall(e, makeAttrs(ATermMap())), drvs, doneExprs);
|
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, drvs, doneExprs)) {
|
||||||
|
if (apType != apNone) throw attrError;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
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)) {
|
||||||
|
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, e2, drvs, doneExprs))
|
||||||
|
getDerivations(state, e2, drvs, doneExprs, attrPathRest);
|
||||||
|
}
|
||||||
return;
|
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;
|
Exprs doneExprs;
|
||||||
getDerivations(state, e, drvs, doneExprs);
|
getDerivations(state, e, drvs, doneExprs, attrPath);
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,8 @@ typedef list<DrvInfo> DrvInfos;
|
||||||
Otherwise, return false. */
|
Otherwise, return false. */
|
||||||
bool getDerivation(EvalState & state, Expr e, DrvInfo & drv);
|
bool getDerivation(EvalState & state, Expr e, DrvInfo & drv);
|
||||||
|
|
||||||
void getDerivations(EvalState & state, Expr e, DrvInfos & drvs);
|
void getDerivations(EvalState & state, Expr e, DrvInfos & drvs,
|
||||||
|
const string & attrPath = "");
|
||||||
|
|
||||||
|
|
||||||
#endif /* !__GET_DRVS_H */
|
#endif /* !__GET_DRVS_H */
|
||||||
|
|
|
@ -33,13 +33,14 @@ static int rootNr = 0;
|
||||||
static bool indirectRoot = false;
|
static bool indirectRoot = false;
|
||||||
|
|
||||||
|
|
||||||
static void printResult(EvalState & state, Expr e, bool evalOnly)
|
static void printResult(EvalState & state, Expr e, bool evalOnly,
|
||||||
|
const string & attrPath)
|
||||||
{
|
{
|
||||||
if (evalOnly)
|
if (evalOnly)
|
||||||
cout << format("%1%\n") % e;
|
cout << format("%1%\n") % e;
|
||||||
else {
|
else {
|
||||||
DrvInfos drvs;
|
DrvInfos drvs;
|
||||||
getDerivations(state, e, drvs);
|
getDerivations(state, e, drvs, attrPath);
|
||||||
for (DrvInfos::iterator i = drvs.begin(); i != drvs.end(); ++i) {
|
for (DrvInfos::iterator i = drvs.begin(); i != drvs.end(); ++i) {
|
||||||
Path drvPath = i->queryDrvPath(state);
|
Path drvPath = i->queryDrvPath(state);
|
||||||
if (gcRoot == "")
|
if (gcRoot == "")
|
||||||
|
@ -61,6 +62,7 @@ void run(Strings args)
|
||||||
bool readStdin = false;
|
bool readStdin = false;
|
||||||
bool evalOnly = false;
|
bool evalOnly = false;
|
||||||
bool parseOnly = false;
|
bool parseOnly = false;
|
||||||
|
string attrPath;
|
||||||
|
|
||||||
for (Strings::iterator i = args.begin();
|
for (Strings::iterator i = args.begin();
|
||||||
i != args.end(); )
|
i != args.end(); )
|
||||||
|
@ -82,6 +84,11 @@ void run(Strings args)
|
||||||
throw UsageError("`--add-root requires an argument");
|
throw UsageError("`--add-root requires an argument");
|
||||||
gcRoot = absPath(*i++);
|
gcRoot = absPath(*i++);
|
||||||
}
|
}
|
||||||
|
else if (arg == "--attr") {
|
||||||
|
if (i == args.end())
|
||||||
|
throw UsageError("`--attr requires an argument");
|
||||||
|
attrPath = *i++;
|
||||||
|
}
|
||||||
else if (arg == "--indirect")
|
else if (arg == "--indirect")
|
||||||
indirectRoot = true;
|
indirectRoot = true;
|
||||||
else if (arg[0] == '-')
|
else if (arg[0] == '-')
|
||||||
|
@ -94,7 +101,7 @@ void run(Strings args)
|
||||||
|
|
||||||
if (readStdin) {
|
if (readStdin) {
|
||||||
Expr e = evalStdin(state, parseOnly);
|
Expr e = evalStdin(state, parseOnly);
|
||||||
printResult(state, e, evalOnly);
|
printResult(state, e, evalOnly, attrPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Strings::iterator i = files.begin();
|
for (Strings::iterator i = files.begin();
|
||||||
|
@ -104,7 +111,7 @@ void run(Strings args)
|
||||||
Expr e = parseOnly
|
Expr e = parseOnly
|
||||||
? parseExprFromFile(state, path)
|
? parseExprFromFile(state, path)
|
||||||
: evalFile(state, path);
|
: evalFile(state, path);
|
||||||
printResult(state, e, evalOnly);
|
printResult(state, e, evalOnly, attrPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
printEvalStats(state);
|
printEvalStats(state);
|
||||||
|
|
Loading…
Reference in a new issue