mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-27 00:06:16 +02:00
* Refactoring. Hope this doesn't break the semantics of `-u' ;-)
This commit is contained in:
parent
a04a5de8f7
commit
0cb016c209
3 changed files with 170 additions and 162 deletions
|
@ -45,7 +45,7 @@ typedef void (* Operation) (Globals & globals,
|
||||||
Strings opFlags, Strings opArgs);
|
Strings opFlags, Strings opArgs);
|
||||||
|
|
||||||
|
|
||||||
struct DrvInfo
|
struct UserEnvElem
|
||||||
{
|
{
|
||||||
string name;
|
string name;
|
||||||
string system;
|
string system;
|
||||||
|
@ -53,8 +53,7 @@ struct DrvInfo
|
||||||
Path outPath;
|
Path outPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef map<Path, DrvInfo> DrvInfos;
|
typedef map<Path, UserEnvElem> UserEnvElems;
|
||||||
typedef vector<DrvInfo> DrvInfoList;
|
|
||||||
|
|
||||||
|
|
||||||
void printHelp()
|
void printHelp()
|
||||||
|
@ -63,7 +62,7 @@ void printHelp()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool parseDerivation(EvalState & state, Expr e, DrvInfo & drv)
|
static bool parseDerivation(EvalState & state, Expr e, UserEnvElem & elem)
|
||||||
{
|
{
|
||||||
ATermList es;
|
ATermList es;
|
||||||
e = evalExpr(state, e);
|
e = evalExpr(state, e);
|
||||||
|
@ -73,54 +72,54 @@ bool parseDerivation(EvalState & state, Expr e, DrvInfo & drv)
|
||||||
|
|
||||||
a = queryAttr(e, "name");
|
a = queryAttr(e, "name");
|
||||||
if (!a) throw badTerm("derivation name missing", e);
|
if (!a) throw badTerm("derivation name missing", e);
|
||||||
drv.name = evalString(state, a);
|
elem.name = evalString(state, a);
|
||||||
|
|
||||||
a = queryAttr(e, "system");
|
a = queryAttr(e, "system");
|
||||||
if (!a)
|
if (!a)
|
||||||
drv.system = "unknown";
|
elem.system = "unknown";
|
||||||
else
|
else
|
||||||
drv.system = evalString(state, a);
|
elem.system = evalString(state, a);
|
||||||
|
|
||||||
a = queryAttr(e, "drvPath");
|
a = queryAttr(e, "drvPath");
|
||||||
if (a) drv.drvPath = evalPath(state, a);
|
if (a) elem.drvPath = evalPath(state, a);
|
||||||
|
|
||||||
a = queryAttr(e, "outPath");
|
a = queryAttr(e, "outPath");
|
||||||
if (!a) throw badTerm("output path missing", e);
|
if (!a) throw badTerm("output path missing", e);
|
||||||
drv.outPath = evalPath(state, a);
|
elem.outPath = evalPath(state, a);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool parseDerivations(EvalState & state, Expr e, DrvInfos & drvs)
|
static bool parseDerivations(EvalState & state, Expr e, UserEnvElems & elems)
|
||||||
{
|
{
|
||||||
ATermList es;
|
ATermList es;
|
||||||
DrvInfo drv;
|
UserEnvElem elem;
|
||||||
|
|
||||||
e = evalExpr(state, e);
|
e = evalExpr(state, e);
|
||||||
|
|
||||||
if (parseDerivation(state, e, drv))
|
if (parseDerivation(state, e, elem))
|
||||||
drvs[drv.outPath] = drv;
|
elems[elem.outPath] = elem;
|
||||||
|
|
||||||
else if (matchAttrs(e, es)) {
|
else if (matchAttrs(e, es)) {
|
||||||
ATermMap drvMap;
|
ATermMap drvMap;
|
||||||
queryAllAttrs(e, drvMap);
|
queryAllAttrs(e, drvMap);
|
||||||
for (ATermIterator i(drvMap.keys()); i; ++i) {
|
for (ATermIterator i(drvMap.keys()); i; ++i) {
|
||||||
debug(format("evaluating attribute `%1%'") % *i);
|
debug(format("evaluating attribute `%1%'") % *i);
|
||||||
if (parseDerivation(state, drvMap.get(*i), drv))
|
if (parseDerivation(state, drvMap.get(*i), elem))
|
||||||
drvs[drv.outPath] = drv;
|
elems[elem.outPath] = elem;
|
||||||
else
|
else
|
||||||
parseDerivations(state, drvMap.get(*i), drvs);
|
parseDerivations(state, drvMap.get(*i), elems);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (matchList(e, es)) {
|
else if (matchList(e, es)) {
|
||||||
for (ATermIterator i(es); i; ++i) {
|
for (ATermIterator i(es); i; ++i) {
|
||||||
debug(format("evaluating list element"));
|
debug(format("evaluating list element"));
|
||||||
if (parseDerivation(state, *i, drv))
|
if (parseDerivation(state, *i, elem))
|
||||||
drvs[drv.outPath] = drv;
|
elems[elem.outPath] = elem;
|
||||||
else
|
else
|
||||||
parseDerivations(state, *i, drvs);
|
parseDerivations(state, *i, elems);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,30 +128,18 @@ bool parseDerivations(EvalState & state, Expr e, DrvInfos & drvs)
|
||||||
|
|
||||||
|
|
||||||
static void loadDerivations(EvalState & state, Path nixExprPath,
|
static void loadDerivations(EvalState & state, Path nixExprPath,
|
||||||
string systemFilter, DrvInfos & drvs)
|
string systemFilter, UserEnvElems & elems)
|
||||||
{
|
{
|
||||||
Expr e = parseExprFromFile(state, absPath(nixExprPath));
|
Expr e = parseExprFromFile(state, absPath(nixExprPath));
|
||||||
if (!parseDerivations(state, e, drvs))
|
if (!parseDerivations(state, e, elems))
|
||||||
throw Error("set of derivations expected");
|
throw Error("set of derivations expected");
|
||||||
|
|
||||||
/* Filter out all derivations not applicable to the current
|
/* Filter out all derivations not applicable to the current
|
||||||
system. */
|
system. */
|
||||||
for (DrvInfos::iterator i = drvs.begin(), j; i != drvs.end(); i = j) {
|
for (UserEnvElems::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->second.system != systemFilter)
|
||||||
drvs.erase(i);
|
elems.erase(i);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void queryInstSources(EvalState & state,
|
|
||||||
const InstallSourceInfo & instSource, DrvInfos & drvs)
|
|
||||||
{
|
|
||||||
switch (instSource.type) {
|
|
||||||
case srcUnknown:
|
|
||||||
loadDerivations(state, instSource.nixExprPath,
|
|
||||||
instSource.systemFilter, drvs);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,7 +171,7 @@ struct AddPos : TermFun
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void queryInstalled(EvalState & state, DrvInfos & drvs,
|
static void queryInstalled(EvalState & state, UserEnvElems & elems,
|
||||||
const Path & userEnv)
|
const Path & userEnv)
|
||||||
{
|
{
|
||||||
Path path = userEnv + "/manifest";
|
Path path = userEnv + "/manifest";
|
||||||
|
@ -198,19 +185,19 @@ void queryInstalled(EvalState & state, DrvInfos & drvs,
|
||||||
AddPos addPos;
|
AddPos addPos;
|
||||||
e = bottomupRewrite(addPos, e);
|
e = bottomupRewrite(addPos, e);
|
||||||
|
|
||||||
if (!parseDerivations(state, e, drvs))
|
if (!parseDerivations(state, e, elems))
|
||||||
throw badTerm(format("set of derivations expected in `%1%'") % path, e);
|
throw badTerm(format("set of derivations expected in `%1%'") % path, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void createUserEnv(EvalState & state, const DrvInfos & drvs,
|
static void createUserEnv(EvalState & state, const UserEnvElems & 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 (DrvInfos::const_iterator i = drvs.begin();
|
for (UserEnvElems::const_iterator i = elems.begin();
|
||||||
i != drvs.end(); ++i)
|
i != elems.end(); ++i)
|
||||||
if (i->second.drvPath != "")
|
if (i->second.drvPath != "")
|
||||||
drvsToBuild.insert(i->second.drvPath);
|
drvsToBuild.insert(i->second.drvPath);
|
||||||
|
|
||||||
|
@ -225,8 +212,8 @@ void createUserEnv(EvalState & state, const DrvInfos & drvs,
|
||||||
PathSet references;
|
PathSet references;
|
||||||
ATermList manifest = ATempty;
|
ATermList manifest = ATempty;
|
||||||
ATermList inputs = ATempty;
|
ATermList inputs = ATempty;
|
||||||
for (DrvInfos::const_iterator i = drvs.begin();
|
for (UserEnvElems::const_iterator i = elems.begin();
|
||||||
i != drvs.end(); ++i)
|
i != elems.end(); ++i)
|
||||||
{
|
{
|
||||||
Path drvPath = keepDerivations ? i->second.drvPath : "";
|
Path drvPath = keepDerivations ? i->second.drvPath : "";
|
||||||
ATerm t = makeAttrs(ATmakeList5(
|
ATerm t = makeAttrs(ATmakeList5(
|
||||||
|
@ -268,7 +255,7 @@ void createUserEnv(EvalState & state, const DrvInfos & drvs,
|
||||||
|
|
||||||
/* Instantiate it. */
|
/* Instantiate it. */
|
||||||
debug(format("evaluating builder expression `%1%'") % topLevel);
|
debug(format("evaluating builder expression `%1%'") % topLevel);
|
||||||
DrvInfo topLevelDrv;
|
UserEnvElem topLevelDrv;
|
||||||
if (!parseDerivation(state, topLevel, topLevelDrv))
|
if (!parseDerivation(state, topLevel, topLevelDrv))
|
||||||
abort();
|
abort();
|
||||||
|
|
||||||
|
@ -278,67 +265,104 @@ void createUserEnv(EvalState & state, const DrvInfos & drvs,
|
||||||
|
|
||||||
/* Switch the current user environment to the output path. */
|
/* Switch the current user environment to the output path. */
|
||||||
debug(format("switching to new user environment"));
|
debug(format("switching to new user environment"));
|
||||||
Path generation = createGeneration(profile,
|
Path generation = createGeneration(profile, topLevelDrv.outPath);
|
||||||
topLevelDrv.outPath, topLevelDrv.drvPath);
|
|
||||||
switchLink(profile, generation);
|
switchLink(profile, generation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void queryInstSources(EvalState & state,
|
||||||
|
const InstallSourceInfo & instSource, const Strings & args,
|
||||||
|
UserEnvElems & elems)
|
||||||
|
{
|
||||||
|
switch (instSource.type) {
|
||||||
|
|
||||||
|
/* Get the available user environment elements from the
|
||||||
|
derivations specified in a Nix expression, including only
|
||||||
|
those with names matching any of the names in `args'. */
|
||||||
|
case srcUnknown:
|
||||||
|
case srcNixExprDrvs: {
|
||||||
|
|
||||||
|
DrvNames selectors = drvNamesFromArgs(args);
|
||||||
|
|
||||||
|
/* Load the derivations from the (default or specified)
|
||||||
|
Nix expression. */
|
||||||
|
UserEnvElems allElems;
|
||||||
|
loadDerivations(state, instSource.nixExprPath,
|
||||||
|
instSource.systemFilter, allElems);
|
||||||
|
|
||||||
|
/* Filter out the ones we're not interested in. */
|
||||||
|
for (UserEnvElems::iterator i = allElems.begin();
|
||||||
|
i != allElems.end(); ++i)
|
||||||
|
{
|
||||||
|
DrvName drvName(i->second.name);
|
||||||
|
for (DrvNames::iterator j = selectors.begin();
|
||||||
|
j != selectors.end(); ++j)
|
||||||
|
{
|
||||||
|
if (j->matches(drvName)) {
|
||||||
|
j->hits++;
|
||||||
|
elems.insert(*i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check that all selectors have been used. */
|
||||||
|
for (DrvNames::iterator i = selectors.begin();
|
||||||
|
i != selectors.end(); ++i)
|
||||||
|
if (i->hits == 0)
|
||||||
|
throw Error(format("selector `%1%' matches no derivations")
|
||||||
|
% i->fullName);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case srcNixExprs:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case srcStorePaths:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case srcProfile:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void installDerivations(Globals & globals,
|
static void installDerivations(Globals & globals,
|
||||||
DrvNames & selectors, const Path & profile)
|
const Strings & args, const Path & profile)
|
||||||
{
|
{
|
||||||
debug(format("installing derivations"));
|
debug(format("installing derivations"));
|
||||||
|
|
||||||
/* Fetch all derivations from the input file. */
|
/* Get the set of user environment elements to be installed. */
|
||||||
DrvInfos availDrvs;
|
UserEnvElems newElems;
|
||||||
queryInstSources(globals.state, globals.instSource, availDrvs);
|
queryInstSources(globals.state, globals.instSource, args, newElems);
|
||||||
|
|
||||||
/* Filter out the ones we're not interested in. */
|
StringSet newNames;
|
||||||
DrvInfos selectedDrvs;
|
for (UserEnvElems::iterator i = newElems.begin(); i != newElems.end(); ++i) {
|
||||||
StringSet selectedNames;
|
printMsg(lvlInfo,
|
||||||
for (DrvInfos::iterator i = availDrvs.begin();
|
format("installing `%1%'") % i->second.name);
|
||||||
i != availDrvs.end(); ++i)
|
newNames.insert(DrvName(i->second.name).name);
|
||||||
{
|
|
||||||
DrvName drvName(i->second.name);
|
|
||||||
for (DrvNames::iterator j = selectors.begin();
|
|
||||||
j != selectors.end(); ++j)
|
|
||||||
{
|
|
||||||
if (j->matches(drvName)) {
|
|
||||||
printMsg(lvlInfo,
|
|
||||||
format("installing `%1%'") % i->second.name);
|
|
||||||
j->hits++;
|
|
||||||
selectedDrvs.insert(*i);
|
|
||||||
selectedNames.insert(drvName.name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check that all selectors have been used. */
|
/* Add in the already installed derivations, unless they have the
|
||||||
for (DrvNames::iterator i = selectors.begin();
|
same name as a to-be-installed element. */
|
||||||
i != selectors.end(); ++i)
|
UserEnvElems installedElems;
|
||||||
if (i->hits == 0)
|
queryInstalled(globals.state, installedElems, profile);
|
||||||
throw Error(format("selector `%1%' matches no derivations")
|
|
||||||
% i->fullName);
|
|
||||||
|
|
||||||
/* Add in the already installed derivations. */
|
for (UserEnvElems::iterator i = installedElems.begin();
|
||||||
DrvInfos installedDrvs;
|
i != installedElems.end(); ++i)
|
||||||
queryInstalled(globals.state, installedDrvs, profile);
|
|
||||||
|
|
||||||
for (DrvInfos::iterator i = installedDrvs.begin();
|
|
||||||
i != installedDrvs.end(); ++i)
|
|
||||||
{
|
{
|
||||||
DrvName drvName(i->second.name);
|
DrvName drvName(i->second.name);
|
||||||
if (!globals.preserveInstalled &&
|
if (!globals.preserveInstalled &&
|
||||||
selectedNames.find(drvName.name) != selectedNames.end())
|
newNames.find(drvName.name) != newNames.end())
|
||||||
printMsg(lvlInfo,
|
printMsg(lvlInfo,
|
||||||
format("uninstalling `%1%'") % i->second.name);
|
format("uninstalling `%1%'") % i->second.name);
|
||||||
else
|
else
|
||||||
selectedDrvs.insert(*i);
|
newElems.insert(*i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (globals.dryRun) return;
|
if (globals.dryRun) return;
|
||||||
|
|
||||||
createUserEnv(globals.state, selectedDrvs,
|
createUserEnv(globals.state, newElems,
|
||||||
profile, globals.keepDerivations);
|
profile, globals.keepDerivations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -349,9 +373,7 @@ static void opInstall(Globals & globals,
|
||||||
if (opFlags.size() > 0)
|
if (opFlags.size() > 0)
|
||||||
throw UsageError(format("unknown flags `%1%'") % opFlags.front());
|
throw UsageError(format("unknown flags `%1%'") % opFlags.front());
|
||||||
|
|
||||||
DrvNames drvNames = drvNamesFromArgs(opArgs);
|
installDerivations(globals, opArgs, globals.profile);
|
||||||
|
|
||||||
installDerivations(globals, drvNames, globals.profile);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -359,7 +381,7 @@ typedef enum { utLt, utLeq, utAlways } UpgradeType;
|
||||||
|
|
||||||
|
|
||||||
static void upgradeDerivations(Globals & globals,
|
static void upgradeDerivations(Globals & globals,
|
||||||
DrvNames & selectors, const Path & profile,
|
const Strings & args, const Path & profile,
|
||||||
UpgradeType upgradeType)
|
UpgradeType upgradeType)
|
||||||
{
|
{
|
||||||
debug(format("upgrading derivations"));
|
debug(format("upgrading derivations"));
|
||||||
|
@ -370,47 +392,28 @@ 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. */
|
||||||
DrvInfos installedDrvs;
|
UserEnvElems installedElems;
|
||||||
queryInstalled(globals.state, installedDrvs, profile);
|
queryInstalled(globals.state, installedElems, profile);
|
||||||
|
|
||||||
/* Fetch all derivations from the input file. */
|
/* Fetch all derivations from the input file. */
|
||||||
DrvInfos availDrvs;
|
UserEnvElems availElems;
|
||||||
queryInstSources(globals.state, globals.instSource, availDrvs);
|
queryInstSources(globals.state, globals.instSource, args, availElems);
|
||||||
|
|
||||||
/* Go through all installed derivations. */
|
/* Go through all installed derivations. */
|
||||||
DrvInfos newDrvs;
|
UserEnvElems newElems;
|
||||||
for (DrvInfos::iterator i = installedDrvs.begin();
|
for (UserEnvElems::iterator i = installedElems.begin();
|
||||||
i != installedDrvs.end(); ++i)
|
i != installedElems.end(); ++i)
|
||||||
{
|
{
|
||||||
DrvName drvName(i->second.name);
|
DrvName drvName(i->second.name);
|
||||||
DrvName selector;
|
|
||||||
|
|
||||||
/* Do we want to upgrade this derivation? */
|
/* Find the derivation in the input Nix expression with the
|
||||||
bool upgrade = false;
|
same name and satisfying the version constraints specified
|
||||||
for (DrvNames::iterator j = selectors.begin();
|
by upgradeType. If there are multiple matches, take the
|
||||||
j != selectors.end(); ++j)
|
one with highest version. */
|
||||||
{
|
UserEnvElems::iterator bestElem = availElems.end();
|
||||||
if (j->name == "*" || j->name == drvName.name) {
|
|
||||||
j->hits++;
|
|
||||||
selector = *j;
|
|
||||||
upgrade = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!upgrade) {
|
|
||||||
newDrvs.insert(*i);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If yes, find the derivation in the input Nix expression
|
|
||||||
with the same name and satisfying the version constraints
|
|
||||||
specified by upgradeType. If there are multiple matches,
|
|
||||||
take the one with highest version. */
|
|
||||||
DrvInfos::iterator bestDrv = availDrvs.end();
|
|
||||||
DrvName bestName;
|
DrvName bestName;
|
||||||
for (DrvInfos::iterator j = availDrvs.begin();
|
for (UserEnvElems::iterator j = availElems.begin();
|
||||||
j != availDrvs.end(); ++j)
|
j != availElems.end(); ++j)
|
||||||
{
|
{
|
||||||
DrvName newName(j->second.name);
|
DrvName newName(j->second.name);
|
||||||
if (newName.name == drvName.name) {
|
if (newName.name == drvName.name) {
|
||||||
|
@ -419,31 +422,30 @@ static void upgradeDerivations(Globals & globals,
|
||||||
upgradeType == utLeq && d <= 0 ||
|
upgradeType == utLeq && d <= 0 ||
|
||||||
upgradeType == utAlways)
|
upgradeType == utAlways)
|
||||||
{
|
{
|
||||||
if (selector.matches(newName) &&
|
if ((bestElem == availElems.end() ||
|
||||||
(bestDrv == availDrvs.end() ||
|
|
||||||
compareVersions(
|
compareVersions(
|
||||||
bestName.version, newName.version) < 0))
|
bestName.version, newName.version) < 0))
|
||||||
{
|
{
|
||||||
bestDrv = j;
|
bestElem = j;
|
||||||
bestName = newName;
|
bestName = newName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bestDrv != availDrvs.end() &&
|
if (bestElem != availElems.end() &&
|
||||||
i->second.drvPath != bestDrv->second.drvPath)
|
i->second.outPath != bestElem->second.outPath)
|
||||||
{
|
{
|
||||||
printMsg(lvlInfo,
|
printMsg(lvlInfo,
|
||||||
format("upgrading `%1%' to `%2%'")
|
format("upgrading `%1%' to `%2%'")
|
||||||
% i->second.name % bestDrv->second.name);
|
% i->second.name % bestElem->second.name);
|
||||||
newDrvs.insert(*bestDrv);
|
newElems.insert(*bestElem);
|
||||||
} else newDrvs.insert(*i);
|
} else newElems.insert(*i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (globals.dryRun) return;
|
if (globals.dryRun) return;
|
||||||
|
|
||||||
createUserEnv(globals.state, newDrvs,
|
createUserEnv(globals.state, newElems,
|
||||||
profile, globals.keepDerivations);
|
profile, globals.keepDerivations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -459,20 +461,18 @@ static void opUpgrade(Globals & globals,
|
||||||
else if (*i == "--always") upgradeType = utAlways;
|
else if (*i == "--always") upgradeType = utAlways;
|
||||||
else throw UsageError(format("unknown flag `%1%'") % *i);
|
else throw UsageError(format("unknown flag `%1%'") % *i);
|
||||||
|
|
||||||
DrvNames drvNames = drvNamesFromArgs(opArgs);
|
upgradeDerivations(globals, opArgs, globals.profile, upgradeType);
|
||||||
|
|
||||||
upgradeDerivations(globals, drvNames, globals.profile, upgradeType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void uninstallDerivations(Globals & globals, DrvNames & selectors,
|
static void uninstallDerivations(Globals & globals, DrvNames & selectors,
|
||||||
Path & profile)
|
Path & profile)
|
||||||
{
|
{
|
||||||
DrvInfos installedDrvs;
|
UserEnvElems installedElems;
|
||||||
queryInstalled(globals.state, installedDrvs, profile);
|
queryInstalled(globals.state, installedElems, profile);
|
||||||
|
|
||||||
for (DrvInfos::iterator i = installedDrvs.begin();
|
for (UserEnvElems::iterator i = installedElems.begin();
|
||||||
i != installedDrvs.end(); ++i)
|
i != installedElems.end(); ++i)
|
||||||
{
|
{
|
||||||
DrvName drvName(i->second.name);
|
DrvName drvName(i->second.name);
|
||||||
for (DrvNames::iterator j = selectors.begin();
|
for (DrvNames::iterator j = selectors.begin();
|
||||||
|
@ -480,13 +480,13 @@ static void uninstallDerivations(Globals & globals, DrvNames & selectors,
|
||||||
if (j->matches(drvName)) {
|
if (j->matches(drvName)) {
|
||||||
printMsg(lvlInfo,
|
printMsg(lvlInfo,
|
||||||
format("uninstalling `%1%'") % i->second.name);
|
format("uninstalling `%1%'") % i->second.name);
|
||||||
installedDrvs.erase(i);
|
installedElems.erase(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (globals.dryRun) return;
|
if (globals.dryRun) return;
|
||||||
|
|
||||||
createUserEnv(globals.state, installedDrvs,
|
createUserEnv(globals.state, installedElems,
|
||||||
profile, globals.keepDerivations);
|
profile, globals.keepDerivations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -510,7 +510,7 @@ static bool cmpChars(char a, char b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool cmpDrvByName(const DrvInfo & a, const DrvInfo & b)
|
static bool cmpElemByName(const UserEnvElem & a, const UserEnvElem & b)
|
||||||
{
|
{
|
||||||
return lexicographical_compare(
|
return lexicographical_compare(
|
||||||
a.name.begin(), a.name.end(),
|
a.name.begin(), a.name.end(),
|
||||||
|
@ -575,17 +575,17 @@ static void opQuery(Globals & globals,
|
||||||
else throw UsageError(format("unknown flag `%1%'") % *i);
|
else throw UsageError(format("unknown flag `%1%'") % *i);
|
||||||
|
|
||||||
/* Obtain derivation information from the specified source. */
|
/* Obtain derivation information from the specified source. */
|
||||||
DrvInfos drvs;
|
UserEnvElems elems;
|
||||||
|
|
||||||
switch (source) {
|
switch (source) {
|
||||||
|
|
||||||
case sInstalled:
|
case sInstalled:
|
||||||
queryInstalled(globals.state, drvs, globals.profile);
|
queryInstalled(globals.state, elems, globals.profile);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case sAvailable: {
|
case sAvailable: {
|
||||||
loadDerivations(globals.state, globals.instSource.nixExprPath,
|
loadDerivations(globals.state, globals.instSource.nixExprPath,
|
||||||
globals.instSource.systemFilter, drvs);
|
globals.instSource.systemFilter, elems);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -595,14 +595,14 @@ static void opQuery(Globals & globals,
|
||||||
if (opArgs.size() != 0) throw UsageError("no arguments expected");
|
if (opArgs.size() != 0) throw UsageError("no arguments expected");
|
||||||
|
|
||||||
/* Sort them by name. */
|
/* Sort them by name. */
|
||||||
DrvInfoList drvs2;
|
vector<UserEnvElem> elems2;
|
||||||
for (DrvInfos::iterator i = drvs.begin(); i != drvs.end(); ++i)
|
for (UserEnvElems::iterator i = elems.begin(); i != elems.end(); ++i)
|
||||||
drvs2.push_back(i->second);
|
elems2.push_back(i->second);
|
||||||
sort(drvs2.begin(), drvs2.end(), cmpDrvByName);
|
sort(elems2.begin(), elems2.end(), cmpElemByName);
|
||||||
|
|
||||||
/* We only need to know the installed paths when we are querying
|
/* We only need to know the installed paths when we are querying
|
||||||
the status of the derivation. */
|
the status of the derivation. */
|
||||||
DrvInfos installed; /* installed paths */
|
UserEnvElems installed; /* installed paths */
|
||||||
|
|
||||||
if (printStatus)
|
if (printStatus)
|
||||||
queryInstalled(globals.state, installed, globals.profile);
|
queryInstalled(globals.state, installed, globals.profile);
|
||||||
|
@ -610,8 +610,9 @@ static void opQuery(Globals & globals,
|
||||||
/* Print the desired columns. */
|
/* Print the desired columns. */
|
||||||
Table table;
|
Table table;
|
||||||
|
|
||||||
for (DrvInfoList::iterator i = drvs2.begin(); i != drvs2.end(); ++i) {
|
for (vector<UserEnvElem>::iterator i = elems2.begin();
|
||||||
|
i != elems2.end(); ++i)
|
||||||
|
{
|
||||||
Strings columns;
|
Strings columns;
|
||||||
|
|
||||||
if (printStatus) {
|
if (printStatus) {
|
||||||
|
@ -794,6 +795,16 @@ static void opDefaultExpr(Globals & globals,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static string needArg(Strings::iterator & i,
|
||||||
|
const Strings & args, const string & arg)
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
if (i == args.end()) throw UsageError(
|
||||||
|
format("`%1%' requires an argument") % arg);
|
||||||
|
return *i;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void run(Strings args)
|
void run(Strings args)
|
||||||
{
|
{
|
||||||
Strings opFlags, opArgs;
|
Strings opFlags, opArgs;
|
||||||
|
@ -818,6 +829,12 @@ void run(Strings args)
|
||||||
|
|
||||||
if (arg == "--install" || arg == "-i")
|
if (arg == "--install" || arg == "-i")
|
||||||
op = opInstall;
|
op = opInstall;
|
||||||
|
else if (arg == "--from-expression" || arg == "-E")
|
||||||
|
globals.instSource.type = srcNixExprs;
|
||||||
|
else if (arg == "--from-profile") {
|
||||||
|
globals.instSource.type = srcProfile;
|
||||||
|
globals.instSource.profile = needArg(i, args, arg);
|
||||||
|
}
|
||||||
else if (arg == "--uninstall" || arg == "-e")
|
else if (arg == "--uninstall" || arg == "-e")
|
||||||
op = opUninstall;
|
op = opUninstall;
|
||||||
else if (arg == "--upgrade" || arg == "-u")
|
else if (arg == "--upgrade" || arg == "-u")
|
||||||
|
@ -827,16 +844,10 @@ void run(Strings args)
|
||||||
else if (arg == "--import" || arg == "-I") /* !!! bad name */
|
else if (arg == "--import" || arg == "-I") /* !!! bad name */
|
||||||
op = opDefaultExpr;
|
op = opDefaultExpr;
|
||||||
else if (arg == "--profile" || arg == "-p") {
|
else if (arg == "--profile" || arg == "-p") {
|
||||||
++i;
|
globals.profile = absPath(needArg(i, args, arg));
|
||||||
if (i == args.end()) throw UsageError(
|
|
||||||
format("`%1%' requires an argument") % arg);
|
|
||||||
globals.profile = absPath(*i);
|
|
||||||
}
|
}
|
||||||
else if (arg == "--file" || arg == "-f") {
|
else if (arg == "--file" || arg == "-f") {
|
||||||
++i;
|
globals.instSource.nixExprPath = absPath(needArg(i, args, arg));
|
||||||
if (i == args.end()) throw UsageError(
|
|
||||||
format("`%1%' requires an argument") % arg);
|
|
||||||
globals.instSource.nixExprPath = absPath(*i);
|
|
||||||
}
|
}
|
||||||
else if (arg == "--switch-profile" || arg == "-S")
|
else if (arg == "--switch-profile" || arg == "-S")
|
||||||
op = opSwitchProfile;
|
op = opSwitchProfile;
|
||||||
|
@ -855,10 +866,7 @@ void run(Strings args)
|
||||||
else if (arg == "--preserve-installed" || arg == "-P")
|
else if (arg == "--preserve-installed" || arg == "-P")
|
||||||
globals.preserveInstalled = true;
|
globals.preserveInstalled = true;
|
||||||
else if (arg == "--system-filter") {
|
else if (arg == "--system-filter") {
|
||||||
++i;
|
globals.instSource.systemFilter = needArg(i, args, arg);
|
||||||
if (i == args.end()) throw UsageError(
|
|
||||||
format("`%1%' requires an argument") % arg);
|
|
||||||
globals.instSource.systemFilter = *i;
|
|
||||||
}
|
}
|
||||||
else if (arg[0] == '-')
|
else if (arg[0] == '-')
|
||||||
opFlags.push_back(arg);
|
opFlags.push_back(arg);
|
||||||
|
|
|
@ -69,7 +69,7 @@ static void makeName(const Path & profile, unsigned int num,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Path createGeneration(Path profile, Path outPath, Path drvPath)
|
Path createGeneration(Path profile, Path outPath)
|
||||||
{
|
{
|
||||||
/* The new generation number should be higher than old the
|
/* The new generation number should be higher than old the
|
||||||
previous ones. */
|
previous ones. */
|
||||||
|
|
|
@ -28,7 +28,7 @@ typedef list<Generation> Generations;
|
||||||
profile, sorted by generation number. */
|
profile, sorted by generation number. */
|
||||||
Generations findGenerations(Path profile, int & curGen);
|
Generations findGenerations(Path profile, int & curGen);
|
||||||
|
|
||||||
Path createGeneration(Path profile, Path outPath, Path drvPath);
|
Path createGeneration(Path profile, Path outPath);
|
||||||
|
|
||||||
void deleteGeneration(const Path & profile, unsigned int gen);
|
void deleteGeneration(const Path & profile, unsigned int gen);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue