* Refactoring: move derivation evaluation to libexpr.
This commit is contained in:
parent
4db4b61380
commit
39f50db731
|
@ -3,7 +3,8 @@ lib_LTLIBRARIES = libexpr.la
|
||||||
libexpr_la_SOURCES = nixexpr.cc nixexpr.hh parser.cc parser.hh \
|
libexpr_la_SOURCES = nixexpr.cc nixexpr.hh parser.cc parser.hh \
|
||||||
eval.cc eval.hh primops.cc \
|
eval.cc eval.hh primops.cc \
|
||||||
lexer-tab.c lexer-tab.h parser-tab.c parser-tab.h \
|
lexer-tab.c lexer-tab.h parser-tab.c parser-tab.h \
|
||||||
nixexpr-ast.hh
|
nixexpr-ast.hh \
|
||||||
|
get-drvs.cc get-drvs.hh
|
||||||
|
|
||||||
EXTRA_DIST = lexer.l parser.y nixexpr-ast.def nixexpr-ast.cc
|
EXTRA_DIST = lexer.l parser.y nixexpr-ast.def nixexpr-ast.cc
|
||||||
|
|
||||||
|
|
67
src/libexpr/get-drvs.cc
Normal file
67
src/libexpr/get-drvs.cc
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
#include "get-drvs.hh"
|
||||||
|
#include "nixexpr-ast.hh"
|
||||||
|
|
||||||
|
|
||||||
|
bool getDerivation(EvalState & state, Expr e, DrvInfo & drv)
|
||||||
|
{
|
||||||
|
ATermList es;
|
||||||
|
e = evalExpr(state, e);
|
||||||
|
if (!matchAttrs(e, es)) return false;
|
||||||
|
|
||||||
|
ATermMap attrs;
|
||||||
|
queryAllAttrs(e, attrs, false);
|
||||||
|
|
||||||
|
Expr a = attrs.get("type");
|
||||||
|
if (!a || evalString(state, a) != "derivation") return false;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
drv.attrs = attrs;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void getDerivations(EvalState & state, Expr e, DrvInfos & drvs)
|
||||||
|
{
|
||||||
|
ATermList es;
|
||||||
|
DrvInfo drv;
|
||||||
|
|
||||||
|
e = evalExpr(state, e);
|
||||||
|
|
||||||
|
if (getDerivation(state, e, drv))
|
||||||
|
drvs.push_back(drv);
|
||||||
|
|
||||||
|
else if (matchAttrs(e, es)) {
|
||||||
|
ATermMap drvMap;
|
||||||
|
queryAllAttrs(e, drvMap);
|
||||||
|
for (ATermIterator i(drvMap.keys()); i; ++i) {
|
||||||
|
debug(format("evaluating attribute `%1%'") % aterm2String(*i));
|
||||||
|
if (getDerivation(state, drvMap.get(*i), drv))
|
||||||
|
drvs.push_back(drv);
|
||||||
|
else
|
||||||
|
;
|
||||||
|
// parseDerivations(state, drvMap.get(*i), drvs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (matchList(e, es)) {
|
||||||
|
for (ATermIterator i(es); i; ++i) {
|
||||||
|
debug(format("evaluating list element"));
|
||||||
|
if (getDerivation(state, *i, drv))
|
||||||
|
drvs.push_back(drv);
|
||||||
|
else
|
||||||
|
getDerivations(state, *i, drvs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
64
src/libexpr/get-drvs.hh
Normal file
64
src/libexpr/get-drvs.hh
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
#ifndef __GET_DRVS_H
|
||||||
|
#define __GET_DRVS_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include "eval.hh"
|
||||||
|
|
||||||
|
|
||||||
|
struct DrvInfo
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
string drvPath;
|
||||||
|
string outPath;
|
||||||
|
|
||||||
|
public:
|
||||||
|
string name;
|
||||||
|
string system;
|
||||||
|
|
||||||
|
ATermMap attrs;
|
||||||
|
|
||||||
|
string queryDrvPath(EvalState & state) const
|
||||||
|
{
|
||||||
|
if (drvPath == "") {
|
||||||
|
Expr a = attrs.get("drvPath");
|
||||||
|
(string &) drvPath = a ? evalPath(state, a) : "";
|
||||||
|
}
|
||||||
|
return drvPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
string queryOutPath(EvalState & state) const
|
||||||
|
{
|
||||||
|
if (outPath == "") {
|
||||||
|
Expr a = attrs.get("outPath");
|
||||||
|
if (!a) throw Error("output path missing");
|
||||||
|
(string &) outPath = evalPath(state, a);
|
||||||
|
}
|
||||||
|
return outPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDrvPath(const string & s)
|
||||||
|
{
|
||||||
|
drvPath = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setOutPath(const string & s)
|
||||||
|
{
|
||||||
|
outPath = s;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef list<DrvInfo> DrvInfos;
|
||||||
|
|
||||||
|
|
||||||
|
/* Evaluate expression `e'. If it evaluates to a derivation, store
|
||||||
|
information about the derivation in `drv' and return true.
|
||||||
|
Otherwise, return false. */
|
||||||
|
bool getDerivation(EvalState & state, Expr e, DrvInfo & drv);
|
||||||
|
|
||||||
|
void getDerivations(EvalState & state, Expr e, DrvInfos & drvs);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* !__GET_DRVS_H */
|
|
@ -8,6 +8,7 @@
|
||||||
#include "eval.hh"
|
#include "eval.hh"
|
||||||
#include "help.txt.hh"
|
#include "help.txt.hh"
|
||||||
#include "nixexpr-ast.hh"
|
#include "nixexpr-ast.hh"
|
||||||
|
#include "get-drvs.hh"
|
||||||
|
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
@ -49,133 +50,23 @@ typedef void (* Operation) (Globals & globals,
|
||||||
Strings opFlags, Strings opArgs);
|
Strings opFlags, Strings opArgs);
|
||||||
|
|
||||||
|
|
||||||
struct UserEnvElem
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
string drvPath;
|
|
||||||
string outPath;
|
|
||||||
|
|
||||||
public:
|
|
||||||
string name;
|
|
||||||
string system;
|
|
||||||
|
|
||||||
ATermMap attrs;
|
|
||||||
|
|
||||||
string queryDrvPath(EvalState & state) const
|
|
||||||
{
|
|
||||||
if (drvPath == "") {
|
|
||||||
Expr a = attrs.get("drvPath");
|
|
||||||
(string &) drvPath = a ? evalPath(state, a) : "";
|
|
||||||
}
|
|
||||||
return drvPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
string queryOutPath(EvalState & state) const
|
|
||||||
{
|
|
||||||
if (outPath == "") {
|
|
||||||
Expr a = attrs.get("outPath");
|
|
||||||
if (!a) throw Error("output path missing");
|
|
||||||
(string &) outPath = evalPath(state, a);
|
|
||||||
}
|
|
||||||
return outPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setDrvPath(const string & s)
|
|
||||||
{
|
|
||||||
drvPath = s;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setOutPath(const string & s)
|
|
||||||
{
|
|
||||||
outPath = s;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef map<unsigned int, UserEnvElem> UserEnvElems;
|
|
||||||
|
|
||||||
|
|
||||||
void printHelp()
|
void printHelp()
|
||||||
{
|
{
|
||||||
cout << string((char *) helpText, sizeof helpText);
|
cout << string((char *) helpText, sizeof helpText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool parseDerivation(EvalState & state, Expr e, UserEnvElem & elem)
|
|
||||||
{
|
|
||||||
ATermList es;
|
|
||||||
e = evalExpr(state, e);
|
|
||||||
if (!matchAttrs(e, es)) return false;
|
|
||||||
|
|
||||||
ATermMap attrs;
|
|
||||||
queryAllAttrs(e, attrs, false);
|
|
||||||
|
|
||||||
Expr a = attrs.get("type");
|
|
||||||
if (!a || evalString(state, a) != "derivation") return false;
|
|
||||||
|
|
||||||
a = attrs.get("name");
|
|
||||||
if (!a) throw badTerm("derivation name missing", e);
|
|
||||||
elem.name = evalString(state, a);
|
|
||||||
|
|
||||||
a = attrs.get("system");
|
|
||||||
if (!a)
|
|
||||||
elem.system = "unknown";
|
|
||||||
else
|
|
||||||
elem.system = evalString(state, a);
|
|
||||||
|
|
||||||
elem.attrs = attrs;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned int elemCounter = 0;
|
|
||||||
|
|
||||||
|
|
||||||
static void parseDerivations(EvalState & state, Expr e, UserEnvElems & elems)
|
|
||||||
{
|
|
||||||
ATermList es;
|
|
||||||
UserEnvElem elem;
|
|
||||||
|
|
||||||
e = evalExpr(state, e);
|
|
||||||
|
|
||||||
if (parseDerivation(state, e, elem))
|
|
||||||
elems[elemCounter++] = elem;
|
|
||||||
|
|
||||||
else if (matchAttrs(e, es)) {
|
|
||||||
ATermMap drvMap;
|
|
||||||
queryAllAttrs(e, drvMap);
|
|
||||||
for (ATermIterator i(drvMap.keys()); i; ++i) {
|
|
||||||
debug(format("evaluating attribute `%1%'") % aterm2String(*i));
|
|
||||||
if (parseDerivation(state, drvMap.get(*i), elem))
|
|
||||||
elems[elemCounter++] = elem;
|
|
||||||
else
|
|
||||||
parseDerivations(state, drvMap.get(*i), elems);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (matchList(e, es)) {
|
|
||||||
for (ATermIterator i(es); i; ++i) {
|
|
||||||
debug(format("evaluating list element"));
|
|
||||||
if (parseDerivation(state, *i, elem))
|
|
||||||
elems[elemCounter++] = elem;
|
|
||||||
else
|
|
||||||
parseDerivations(state, *i, elems);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void loadDerivations(EvalState & state, Path nixExprPath,
|
static void loadDerivations(EvalState & state, Path nixExprPath,
|
||||||
string systemFilter, UserEnvElems & elems)
|
string systemFilter, DrvInfos & elems)
|
||||||
{
|
{
|
||||||
parseDerivations(state,
|
getDerivations(state,
|
||||||
parseExprFromFile(state, absPath(nixExprPath)), elems);
|
parseExprFromFile(state, absPath(nixExprPath)), elems);
|
||||||
|
|
||||||
/* Filter out all derivations not applicable to the current
|
/* Filter out all derivations not applicable to the current
|
||||||
system. */
|
system. */
|
||||||
for (UserEnvElems::iterator i = elems.begin(), j; i != elems.end(); i = j) {
|
for (DrvInfos::iterator i = elems.begin(), j; i != elems.end(); i = j) {
|
||||||
j = i; j++;
|
j = i; j++;
|
||||||
if (systemFilter != "*" && i->second.system != systemFilter)
|
if (systemFilter != "*" && i->system != systemFilter)
|
||||||
elems.erase(i);
|
elems.erase(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,12 +99,12 @@ struct AddPos : TermFun
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static UserEnvElems queryInstalled(EvalState & state, const Path & userEnv)
|
static DrvInfos queryInstalled(EvalState & state, const Path & userEnv)
|
||||||
{
|
{
|
||||||
Path path = userEnv + "/manifest";
|
Path path = userEnv + "/manifest";
|
||||||
|
|
||||||
if (!pathExists(path))
|
if (!pathExists(path))
|
||||||
return UserEnvElems(); /* not an error, assume nothing installed */
|
return DrvInfos(); /* not an error, assume nothing installed */
|
||||||
|
|
||||||
Expr e = ATreadFromNamedFile(path.c_str());
|
Expr e = ATreadFromNamedFile(path.c_str());
|
||||||
if (!e) throw Error(format("cannot read Nix expression from `%1%'") % path);
|
if (!e) throw Error(format("cannot read Nix expression from `%1%'") % path);
|
||||||
|
@ -222,25 +113,25 @@ static UserEnvElems queryInstalled(EvalState & state, const Path & userEnv)
|
||||||
AddPos addPos;
|
AddPos addPos;
|
||||||
e = bottomupRewrite(addPos, e);
|
e = bottomupRewrite(addPos, e);
|
||||||
|
|
||||||
UserEnvElems elems;
|
DrvInfos elems;
|
||||||
parseDerivations(state, e, elems);
|
getDerivations(state, e, elems);
|
||||||
return elems;
|
return elems;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void createUserEnv(EvalState & state, const UserEnvElems & elems,
|
static void createUserEnv(EvalState & state, const DrvInfos & elems,
|
||||||
const Path & profile, bool keepDerivations)
|
const Path & profile, bool keepDerivations)
|
||||||
{
|
{
|
||||||
/* Build the components in the user environment, if they don't
|
/* Build the components in the user environment, if they don't
|
||||||
exist already. */
|
exist already. */
|
||||||
PathSet drvsToBuild;
|
PathSet drvsToBuild;
|
||||||
for (UserEnvElems::const_iterator i = elems.begin();
|
for (DrvInfos::const_iterator i = elems.begin();
|
||||||
i != elems.end(); ++i)
|
i != elems.end(); ++i)
|
||||||
/* Call to `isDerivation' is for compatibility with Nix <= 0.7
|
/* Call to `isDerivation' is for compatibility with Nix <= 0.7
|
||||||
user environments. */
|
user environments. */
|
||||||
if (i->second.queryDrvPath(state) != "" &&
|
if (i->queryDrvPath(state) != "" &&
|
||||||
isDerivation(i->second.queryDrvPath(state)))
|
isDerivation(i->queryDrvPath(state)))
|
||||||
drvsToBuild.insert(i->second.queryDrvPath(state));
|
drvsToBuild.insert(i->queryDrvPath(state));
|
||||||
|
|
||||||
debug(format("building user environment dependencies"));
|
debug(format("building user environment dependencies"));
|
||||||
buildDerivations(drvsToBuild);
|
buildDerivations(drvsToBuild);
|
||||||
|
@ -253,31 +144,31 @@ static void createUserEnv(EvalState & state, const UserEnvElems & elems,
|
||||||
PathSet references;
|
PathSet references;
|
||||||
ATermList manifest = ATempty;
|
ATermList manifest = ATempty;
|
||||||
ATermList inputs = ATempty;
|
ATermList inputs = ATempty;
|
||||||
for (UserEnvElems::const_iterator i = elems.begin();
|
for (DrvInfos::const_iterator i = elems.begin();
|
||||||
i != elems.end(); ++i)
|
i != elems.end(); ++i)
|
||||||
{
|
{
|
||||||
Path drvPath = keepDerivations ? i->second.queryDrvPath(state) : "";
|
Path drvPath = keepDerivations ? i->queryDrvPath(state) : "";
|
||||||
ATerm t = makeAttrs(ATmakeList5(
|
ATerm t = makeAttrs(ATmakeList5(
|
||||||
makeBind(toATerm("type"),
|
makeBind(toATerm("type"),
|
||||||
makeStr(toATerm("derivation")), makeNoPos()),
|
makeStr(toATerm("derivation")), makeNoPos()),
|
||||||
makeBind(toATerm("name"),
|
makeBind(toATerm("name"),
|
||||||
makeStr(toATerm(i->second.name)), makeNoPos()),
|
makeStr(toATerm(i->name)), makeNoPos()),
|
||||||
makeBind(toATerm("system"),
|
makeBind(toATerm("system"),
|
||||||
makeStr(toATerm(i->second.system)), makeNoPos()),
|
makeStr(toATerm(i->system)), makeNoPos()),
|
||||||
makeBind(toATerm("drvPath"),
|
makeBind(toATerm("drvPath"),
|
||||||
makePath(toATerm(drvPath)), makeNoPos()),
|
makePath(toATerm(drvPath)), makeNoPos()),
|
||||||
makeBind(toATerm("outPath"),
|
makeBind(toATerm("outPath"),
|
||||||
makePath(toATerm(i->second.queryOutPath(state))), makeNoPos())
|
makePath(toATerm(i->queryOutPath(state))), makeNoPos())
|
||||||
));
|
));
|
||||||
manifest = ATinsert(manifest, t);
|
manifest = ATinsert(manifest, t);
|
||||||
inputs = ATinsert(inputs, makeStr(toATerm(i->second.queryOutPath(state))));
|
inputs = ATinsert(inputs, makeStr(toATerm(i->queryOutPath(state))));
|
||||||
|
|
||||||
/* This is only necessary when installing store paths, e.g.,
|
/* This is only necessary when installing store paths, e.g.,
|
||||||
`nix-env -i /nix/store/abcd...-foo'. */
|
`nix-env -i /nix/store/abcd...-foo'. */
|
||||||
addTempRoot(i->second.queryOutPath(state));
|
addTempRoot(i->queryOutPath(state));
|
||||||
ensurePath(i->second.queryOutPath(state));
|
ensurePath(i->queryOutPath(state));
|
||||||
|
|
||||||
references.insert(i->second.queryOutPath(state));
|
references.insert(i->queryOutPath(state));
|
||||||
if (drvPath != "") references.insert(drvPath);
|
if (drvPath != "") references.insert(drvPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,8 +193,8 @@ static void createUserEnv(EvalState & state, const UserEnvElems & elems,
|
||||||
|
|
||||||
/* Instantiate it. */
|
/* Instantiate it. */
|
||||||
debug(format("evaluating builder expression `%1%'") % topLevel);
|
debug(format("evaluating builder expression `%1%'") % topLevel);
|
||||||
UserEnvElem topLevelDrv;
|
DrvInfo topLevelDrv;
|
||||||
if (!parseDerivation(state, topLevel, topLevelDrv))
|
if (!getDerivation(state, topLevel, topLevelDrv))
|
||||||
abort();
|
abort();
|
||||||
|
|
||||||
/* Realise the resulting store expression. */
|
/* Realise the resulting store expression. */
|
||||||
|
@ -317,24 +208,24 @@ static void createUserEnv(EvalState & state, const UserEnvElems & elems,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static UserEnvElems filterBySelector(const UserEnvElems & allElems,
|
static DrvInfos filterBySelector(const DrvInfos & allElems,
|
||||||
const Strings & args)
|
const Strings & args)
|
||||||
{
|
{
|
||||||
DrvNames selectors = drvNamesFromArgs(args);
|
DrvNames selectors = drvNamesFromArgs(args);
|
||||||
|
|
||||||
UserEnvElems elems;
|
DrvInfos elems;
|
||||||
|
|
||||||
/* Filter out the ones we're not interested in. */
|
/* Filter out the ones we're not interested in. */
|
||||||
for (UserEnvElems::const_iterator i = allElems.begin();
|
for (DrvInfos::const_iterator i = allElems.begin();
|
||||||
i != allElems.end(); ++i)
|
i != allElems.end(); ++i)
|
||||||
{
|
{
|
||||||
DrvName drvName(i->second.name);
|
DrvName drvName(i->name);
|
||||||
for (DrvNames::iterator j = selectors.begin();
|
for (DrvNames::iterator j = selectors.begin();
|
||||||
j != selectors.end(); ++j)
|
j != selectors.end(); ++j)
|
||||||
{
|
{
|
||||||
if (j->matches(drvName)) {
|
if (j->matches(drvName)) {
|
||||||
j->hits++;
|
j->hits++;
|
||||||
elems.insert(*i);
|
elems.push_back(*i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -352,7 +243,7 @@ static UserEnvElems filterBySelector(const UserEnvElems & allElems,
|
||||||
|
|
||||||
static void queryInstSources(EvalState & state,
|
static void queryInstSources(EvalState & state,
|
||||||
const InstallSourceInfo & instSource, const Strings & args,
|
const InstallSourceInfo & instSource, const Strings & args,
|
||||||
UserEnvElems & elems)
|
DrvInfos & elems)
|
||||||
{
|
{
|
||||||
InstallSourceType type = instSource.type;
|
InstallSourceType type = instSource.type;
|
||||||
if (type == srcUnknown && args.size() > 0 && args.front()[0] == '/')
|
if (type == srcUnknown && args.size() > 0 && args.front()[0] == '/')
|
||||||
|
@ -368,7 +259,7 @@ static void queryInstSources(EvalState & state,
|
||||||
|
|
||||||
/* Load the derivations from the (default or specified)
|
/* Load the derivations from the (default or specified)
|
||||||
Nix expression. */
|
Nix expression. */
|
||||||
UserEnvElems allElems;
|
DrvInfos allElems;
|
||||||
loadDerivations(state, instSource.nixExprPath,
|
loadDerivations(state, instSource.nixExprPath,
|
||||||
instSource.systemFilter, allElems);
|
instSource.systemFilter, allElems);
|
||||||
|
|
||||||
|
@ -394,7 +285,7 @@ static void queryInstSources(EvalState & state,
|
||||||
{
|
{
|
||||||
Expr e2 = parseExprFromString(state, *i, absPath("."));
|
Expr e2 = parseExprFromString(state, *i, absPath("."));
|
||||||
Expr call = makeCall(e2, e1);
|
Expr call = makeCall(e2, e1);
|
||||||
parseDerivations(state, call, elems);
|
getDerivations(state, call, elems);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -410,7 +301,7 @@ static void queryInstSources(EvalState & state,
|
||||||
{
|
{
|
||||||
assertStorePath(*i);
|
assertStorePath(*i);
|
||||||
|
|
||||||
UserEnvElem elem;
|
DrvInfo elem;
|
||||||
string name = baseNameOf(*i);
|
string name = baseNameOf(*i);
|
||||||
unsigned int dash = name.find('-');
|
unsigned int dash = name.find('-');
|
||||||
if (dash != string::npos)
|
if (dash != string::npos)
|
||||||
|
@ -426,8 +317,6 @@ static void queryInstSources(EvalState & state,
|
||||||
else elem.setOutPath(*i);
|
else elem.setOutPath(*i);
|
||||||
|
|
||||||
elem.name = name;
|
elem.name = name;
|
||||||
|
|
||||||
elems[elemCounter++] = elem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -451,30 +340,30 @@ static void installDerivations(Globals & globals,
|
||||||
debug(format("installing derivations"));
|
debug(format("installing derivations"));
|
||||||
|
|
||||||
/* Get the set of user environment elements to be installed. */
|
/* Get the set of user environment elements to be installed. */
|
||||||
UserEnvElems newElems;
|
DrvInfos newElems;
|
||||||
queryInstSources(globals.state, globals.instSource, args, newElems);
|
queryInstSources(globals.state, globals.instSource, args, newElems);
|
||||||
|
|
||||||
StringSet newNames;
|
StringSet newNames;
|
||||||
for (UserEnvElems::iterator i = newElems.begin(); i != newElems.end(); ++i) {
|
for (DrvInfos::iterator i = newElems.begin(); i != newElems.end(); ++i) {
|
||||||
printMsg(lvlInfo,
|
printMsg(lvlInfo,
|
||||||
format("installing `%1%'") % i->second.name);
|
format("installing `%1%'") % i->name);
|
||||||
newNames.insert(DrvName(i->second.name).name);
|
newNames.insert(DrvName(i->name).name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add in the already installed derivations, unless they have the
|
/* Add in the already installed derivations, unless they have the
|
||||||
same name as a to-be-installed element. */
|
same name as a to-be-installed element. */
|
||||||
UserEnvElems installedElems = queryInstalled(globals.state, profile);
|
DrvInfos installedElems = queryInstalled(globals.state, profile);
|
||||||
|
|
||||||
for (UserEnvElems::iterator i = installedElems.begin();
|
for (DrvInfos::iterator i = installedElems.begin();
|
||||||
i != installedElems.end(); ++i)
|
i != installedElems.end(); ++i)
|
||||||
{
|
{
|
||||||
DrvName drvName(i->second.name);
|
DrvName drvName(i->name);
|
||||||
if (!globals.preserveInstalled &&
|
if (!globals.preserveInstalled &&
|
||||||
newNames.find(drvName.name) != newNames.end())
|
newNames.find(drvName.name) != newNames.end())
|
||||||
printMsg(lvlInfo,
|
printMsg(lvlInfo,
|
||||||
format("uninstalling `%1%'") % i->second.name);
|
format("uninstalling `%1%'") % i->name);
|
||||||
else
|
else
|
||||||
newElems.insert(*i);
|
newElems.push_back(*i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (globals.dryRun) return;
|
if (globals.dryRun) return;
|
||||||
|
@ -509,29 +398,29 @@ static void upgradeDerivations(Globals & globals,
|
||||||
name and a higher version number. */
|
name and a higher version number. */
|
||||||
|
|
||||||
/* Load the currently installed derivations. */
|
/* Load the currently installed derivations. */
|
||||||
UserEnvElems installedElems = queryInstalled(globals.state, profile);
|
DrvInfos installedElems = queryInstalled(globals.state, profile);
|
||||||
|
|
||||||
/* Fetch all derivations from the input file. */
|
/* Fetch all derivations from the input file. */
|
||||||
UserEnvElems availElems;
|
DrvInfos availElems;
|
||||||
queryInstSources(globals.state, globals.instSource, args, availElems);
|
queryInstSources(globals.state, globals.instSource, args, availElems);
|
||||||
|
|
||||||
/* Go through all installed derivations. */
|
/* Go through all installed derivations. */
|
||||||
UserEnvElems newElems;
|
DrvInfos newElems;
|
||||||
for (UserEnvElems::iterator i = installedElems.begin();
|
for (DrvInfos::iterator i = installedElems.begin();
|
||||||
i != installedElems.end(); ++i)
|
i != installedElems.end(); ++i)
|
||||||
{
|
{
|
||||||
DrvName drvName(i->second.name);
|
DrvName drvName(i->name);
|
||||||
|
|
||||||
/* Find the derivation in the input Nix expression with the
|
/* Find the derivation in the input Nix expression with the
|
||||||
same name and satisfying the version constraints specified
|
same name and satisfying the version constraints specified
|
||||||
by upgradeType. If there are multiple matches, take the
|
by upgradeType. If there are multiple matches, take the
|
||||||
one with highest version. */
|
one with highest version. */
|
||||||
UserEnvElems::iterator bestElem = availElems.end();
|
DrvInfos::iterator bestElem = availElems.end();
|
||||||
DrvName bestName;
|
DrvName bestName;
|
||||||
for (UserEnvElems::iterator j = availElems.begin();
|
for (DrvInfos::iterator j = availElems.begin();
|
||||||
j != availElems.end(); ++j)
|
j != availElems.end(); ++j)
|
||||||
{
|
{
|
||||||
DrvName newName(j->second.name);
|
DrvName newName(j->name);
|
||||||
if (newName.name == drvName.name) {
|
if (newName.name == drvName.name) {
|
||||||
int d = compareVersions(drvName.version, newName.version);
|
int d = compareVersions(drvName.version, newName.version);
|
||||||
if (upgradeType == utLt && d < 0 ||
|
if (upgradeType == utLt && d < 0 ||
|
||||||
|
@ -550,14 +439,14 @@ static void upgradeDerivations(Globals & globals,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bestElem != availElems.end() &&
|
if (bestElem != availElems.end() &&
|
||||||
i->second.queryOutPath(globals.state) !=
|
i->queryOutPath(globals.state) !=
|
||||||
bestElem->second.queryOutPath(globals.state))
|
bestElem->queryOutPath(globals.state))
|
||||||
{
|
{
|
||||||
printMsg(lvlInfo,
|
printMsg(lvlInfo,
|
||||||
format("upgrading `%1%' to `%2%'")
|
format("upgrading `%1%' to `%2%'")
|
||||||
% i->second.name % bestElem->second.name);
|
% i->name % bestElem->name);
|
||||||
newElems.insert(*bestElem);
|
newElems.push_back(*bestElem);
|
||||||
} else newElems.insert(*i);
|
} else newElems.push_back(*i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (globals.dryRun) return;
|
if (globals.dryRun) return;
|
||||||
|
@ -585,23 +474,23 @@ static void opUpgrade(Globals & globals,
|
||||||
static void uninstallDerivations(Globals & globals, DrvNames & selectors,
|
static void uninstallDerivations(Globals & globals, DrvNames & selectors,
|
||||||
Path & profile)
|
Path & profile)
|
||||||
{
|
{
|
||||||
UserEnvElems installedElems = queryInstalled(globals.state, profile);
|
DrvInfos installedElems = queryInstalled(globals.state, profile);
|
||||||
UserEnvElems newElems;
|
DrvInfos newElems;
|
||||||
|
|
||||||
for (UserEnvElems::iterator i = installedElems.begin();
|
for (DrvInfos::iterator i = installedElems.begin();
|
||||||
i != installedElems.end(); ++i)
|
i != installedElems.end(); ++i)
|
||||||
{
|
{
|
||||||
DrvName drvName(i->second.name);
|
DrvName drvName(i->name);
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (DrvNames::iterator j = selectors.begin();
|
for (DrvNames::iterator j = selectors.begin();
|
||||||
j != selectors.end(); ++j)
|
j != selectors.end(); ++j)
|
||||||
if (j->matches(drvName)) {
|
if (j->matches(drvName)) {
|
||||||
printMsg(lvlInfo,
|
printMsg(lvlInfo,
|
||||||
format("uninstalling `%1%'") % i->second.name);
|
format("uninstalling `%1%'") % i->name);
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!found) newElems.insert(*i);
|
if (!found) newElems.push_back(*i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (globals.dryRun) return;
|
if (globals.dryRun) return;
|
||||||
|
@ -630,7 +519,7 @@ static bool cmpChars(char a, char b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool cmpElemByName(const UserEnvElem & a, const UserEnvElem & b)
|
static bool cmpElemByName(const DrvInfo & a, const DrvInfo & b)
|
||||||
{
|
{
|
||||||
return lexicographical_compare(
|
return lexicographical_compare(
|
||||||
a.name.begin(), a.name.end(),
|
a.name.begin(), a.name.end(),
|
||||||
|
@ -680,15 +569,15 @@ void printTable(Table & table)
|
||||||
typedef enum { cvLess, cvEqual, cvGreater, cvUnavail } VersionDiff;
|
typedef enum { cvLess, cvEqual, cvGreater, cvUnavail } VersionDiff;
|
||||||
|
|
||||||
static VersionDiff compareVersionAgainstSet(
|
static VersionDiff compareVersionAgainstSet(
|
||||||
const UserEnvElem & elem, const UserEnvElems & elems, string & version)
|
const DrvInfo & elem, const DrvInfos & elems, string & version)
|
||||||
{
|
{
|
||||||
DrvName name(elem.name);
|
DrvName name(elem.name);
|
||||||
|
|
||||||
VersionDiff diff = cvUnavail;
|
VersionDiff diff = cvUnavail;
|
||||||
version = "?";
|
version = "?";
|
||||||
|
|
||||||
for (UserEnvElems::const_iterator i = elems.begin(); i != elems.end(); ++i) {
|
for (DrvInfos::const_iterator i = elems.begin(); i != elems.end(); ++i) {
|
||||||
DrvName name2(i->second.name);
|
DrvName name2(i->name);
|
||||||
if (name.name == name2.name) {
|
if (name.name == name2.name) {
|
||||||
int d = compareVersions(name.version, name2.version);
|
int d = compareVersions(name.version, name2.version);
|
||||||
if (d < 0) {
|
if (d < 0) {
|
||||||
|
@ -748,7 +637,7 @@ static void opQuery(Globals & globals,
|
||||||
|
|
||||||
|
|
||||||
/* Obtain derivation information from the specified source. */
|
/* Obtain derivation information from the specified source. */
|
||||||
UserEnvElems availElems, installedElems;
|
DrvInfos availElems, installedElems;
|
||||||
|
|
||||||
if (source == sInstalled || compareVersions || printStatus) {
|
if (source == sInstalled || compareVersions || printStatus) {
|
||||||
installedElems = queryInstalled(globals.state, globals.profile);
|
installedElems = queryInstalled(globals.state, globals.profile);
|
||||||
|
@ -759,14 +648,15 @@ static void opQuery(Globals & globals,
|
||||||
globals.instSource.systemFilter, availElems);
|
globals.instSource.systemFilter, availElems);
|
||||||
}
|
}
|
||||||
|
|
||||||
UserEnvElems & elems(source == sInstalled ? installedElems : availElems);
|
DrvInfos & elems(source == sInstalled ? installedElems : availElems);
|
||||||
UserEnvElems & otherElems(source == sInstalled ? availElems : installedElems);
|
DrvInfos & otherElems(source == sInstalled ? availElems : installedElems);
|
||||||
|
|
||||||
|
|
||||||
/* Sort them by name. */
|
/* Sort them by name. */
|
||||||
vector<UserEnvElem> elems2;
|
/* !!! */
|
||||||
for (UserEnvElems::iterator i = elems.begin(); i != elems.end(); ++i)
|
vector<DrvInfo> elems2;
|
||||||
elems2.push_back(i->second);
|
for (DrvInfos::iterator i = elems.begin(); i != elems.end(); ++i)
|
||||||
|
elems2.push_back(*i);
|
||||||
sort(elems2.begin(), elems2.end(), cmpElemByName);
|
sort(elems2.begin(), elems2.end(), cmpElemByName);
|
||||||
|
|
||||||
|
|
||||||
|
@ -775,16 +665,16 @@ static void opQuery(Globals & globals,
|
||||||
PathSet installed; /* installed paths */
|
PathSet installed; /* installed paths */
|
||||||
|
|
||||||
if (printStatus) {
|
if (printStatus) {
|
||||||
for (UserEnvElems::iterator i = installedElems.begin();
|
for (DrvInfos::iterator i = installedElems.begin();
|
||||||
i != installedElems.end(); ++i)
|
i != installedElems.end(); ++i)
|
||||||
installed.insert(i->second.queryOutPath(globals.state));
|
installed.insert(i->queryOutPath(globals.state));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Print the desired columns. */
|
/* Print the desired columns. */
|
||||||
Table table;
|
Table table;
|
||||||
|
|
||||||
for (vector<UserEnvElem>::iterator i = elems2.begin();
|
for (vector<DrvInfo>::iterator i = elems2.begin();
|
||||||
i != elems2.end(); ++i)
|
i != elems2.end(); ++i)
|
||||||
{
|
{
|
||||||
Strings columns;
|
Strings columns;
|
||||||
|
|
Loading…
Reference in a new issue