forked from lix-project/lix
* In --upgrade': added flags
--lt', --leq',
--always' to specify
whether we want to upgrade if the current version is less than the available version (default), when it is less or equal, or always. * Added a flag `--dry-run' to show what would happen in `--install', `--uninstall', and `--upgrade', without actually performing the operation.
This commit is contained in:
parent
06a75a7e0c
commit
618aa69b01
|
@ -22,6 +22,16 @@ name `*' may be used to indicate all derivations.
|
||||||
--version: output version information
|
--version: output version information
|
||||||
--help: display help
|
--help: display help
|
||||||
|
|
||||||
|
Install / upgrade / uninstall flags:
|
||||||
|
|
||||||
|
--dry-run: show what would be done, but don't do it
|
||||||
|
|
||||||
|
Upgrade flags:
|
||||||
|
|
||||||
|
--lt: upgrade unless the current version is older (default)
|
||||||
|
--leq: upgrade unless the current version is older or current
|
||||||
|
--always: upgrade regardless of current version
|
||||||
|
|
||||||
Query types:
|
Query types:
|
||||||
|
|
||||||
--name: print derivation names (default)
|
--name: print derivation names (default)
|
||||||
|
|
|
@ -16,6 +16,7 @@ struct Globals
|
||||||
Path profile;
|
Path profile;
|
||||||
Path nixExprPath;
|
Path nixExprPath;
|
||||||
EvalState state;
|
EvalState state;
|
||||||
|
bool dryRun;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -201,7 +202,8 @@ void createUserEnv(EvalState & state, const DrvInfos & drvs,
|
||||||
|
|
||||||
|
|
||||||
static void installDerivations(EvalState & state,
|
static void installDerivations(EvalState & state,
|
||||||
Path nePath, DrvNames & selectors, const Path & profile)
|
Path nePath, DrvNames & selectors, const Path & profile,
|
||||||
|
bool dryRun)
|
||||||
{
|
{
|
||||||
debug(format("installing derivations from `%1%'") % nePath);
|
debug(format("installing derivations from `%1%'") % nePath);
|
||||||
|
|
||||||
|
@ -239,6 +241,8 @@ static void installDerivations(EvalState & state,
|
||||||
queryInstalled(state, installedDrvs, profile);
|
queryInstalled(state, installedDrvs, profile);
|
||||||
selectedDrvs.insert(installedDrvs.begin(), installedDrvs.end());
|
selectedDrvs.insert(installedDrvs.begin(), installedDrvs.end());
|
||||||
|
|
||||||
|
if (dryRun) return;
|
||||||
|
|
||||||
createUserEnv(state, selectedDrvs, profile);
|
createUserEnv(state, selectedDrvs, profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,12 +256,16 @@ static void opInstall(Globals & globals,
|
||||||
DrvNames drvNames = drvNamesFromArgs(opArgs);
|
DrvNames drvNames = drvNamesFromArgs(opArgs);
|
||||||
|
|
||||||
installDerivations(globals.state, globals.nixExprPath,
|
installDerivations(globals.state, globals.nixExprPath,
|
||||||
drvNames, globals.profile);
|
drvNames, globals.profile, globals.dryRun);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum { utLt, utLeq, utAlways } UpgradeType;
|
||||||
|
|
||||||
|
|
||||||
static void upgradeDerivations(EvalState & state,
|
static void upgradeDerivations(EvalState & state,
|
||||||
Path nePath, DrvNames & selectors, const Path & profile)
|
Path nePath, DrvNames & selectors, const Path & profile,
|
||||||
|
UpgradeType upgradeType, bool dryRun)
|
||||||
{
|
{
|
||||||
debug(format("upgrading derivations from `%1%'") % nePath);
|
debug(format("upgrading derivations from `%1%'") % nePath);
|
||||||
|
|
||||||
|
@ -293,30 +301,50 @@ static void upgradeDerivations(EvalState & state,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!upgrade) {
|
||||||
|
newDrvs.insert(*i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* If yes, find the derivation in the input Nix expression
|
/* If yes, find the derivation in the input Nix expression
|
||||||
with the same name and the highest version number. */
|
with the same name and satisfying the version constraints
|
||||||
DrvInfos::iterator bestDrv = i;
|
specified by upgradeType. If there are multiple matches,
|
||||||
DrvName bestName = drvName;
|
take the one with highest version. */
|
||||||
if (upgrade) {
|
DrvInfos::iterator bestDrv = availDrvs.end();
|
||||||
for (DrvInfos::iterator j = availDrvs.begin();
|
DrvName bestName;
|
||||||
j != availDrvs.end(); ++j)
|
for (DrvInfos::iterator j = availDrvs.begin();
|
||||||
{
|
j != availDrvs.end(); ++j)
|
||||||
DrvName newName(j->second.name);
|
{
|
||||||
if (newName.name == bestName.name &&
|
DrvName newName(j->second.name);
|
||||||
compareVersions(newName.version, bestName.version) > 0)
|
if (newName.name == drvName.name) {
|
||||||
bestDrv = j;
|
int d = compareVersions(drvName.version, newName.version);
|
||||||
|
if (upgradeType == utLt && d < 0 ||
|
||||||
|
upgradeType == utLeq && d <= 0 ||
|
||||||
|
upgradeType == utAlways)
|
||||||
|
{
|
||||||
|
if (bestDrv == availDrvs.end() ||
|
||||||
|
compareVersions(
|
||||||
|
bestName.version, newName.version) < 0)
|
||||||
|
{
|
||||||
|
bestDrv = j;
|
||||||
|
bestName = newName;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bestDrv != i) {
|
if (bestDrv != availDrvs.end() &&
|
||||||
|
i->second.drvPath != bestDrv->second.drvPath)
|
||||||
|
{
|
||||||
printMsg(lvlInfo,
|
printMsg(lvlInfo,
|
||||||
format("upgrading `%1%' to `%2%'")
|
format("upgrading `%1%' to `%2%'")
|
||||||
% i->second.name % bestDrv->second.name);
|
% i->second.name % bestDrv->second.name);
|
||||||
}
|
newDrvs.insert(*bestDrv);
|
||||||
|
} else newDrvs.insert(*i);
|
||||||
newDrvs.insert(*bestDrv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dryRun) return;
|
||||||
|
|
||||||
createUserEnv(state, newDrvs, profile);
|
createUserEnv(state, newDrvs, profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,19 +352,23 @@ static void upgradeDerivations(EvalState & state,
|
||||||
static void opUpgrade(Globals & globals,
|
static void opUpgrade(Globals & globals,
|
||||||
Strings opFlags, Strings opArgs)
|
Strings opFlags, Strings opArgs)
|
||||||
{
|
{
|
||||||
if (opFlags.size() > 0)
|
UpgradeType upgradeType = utLt;
|
||||||
throw UsageError(format("unknown flags `%1%'") % opFlags.front());
|
for (Strings::iterator i = opFlags.begin();
|
||||||
if (opArgs.size() < 1) throw UsageError("Nix file expected");
|
i != opFlags.end(); ++i)
|
||||||
|
if (*i == "--lt") upgradeType = utLt;
|
||||||
|
else if (*i == "--leq") upgradeType = utLeq;
|
||||||
|
else if (*i == "--always") upgradeType = utAlways;
|
||||||
|
else throw UsageError(format("unknown flag `%1%'") % *i);
|
||||||
|
|
||||||
DrvNames drvNames = drvNamesFromArgs(opArgs);
|
DrvNames drvNames = drvNamesFromArgs(opArgs);
|
||||||
|
|
||||||
upgradeDerivations(globals.state, globals.nixExprPath,
|
upgradeDerivations(globals.state, globals.nixExprPath,
|
||||||
drvNames, globals.profile);
|
drvNames, globals.profile, upgradeType, globals.dryRun);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void uninstallDerivations(EvalState & state, DrvNames & selectors,
|
static void uninstallDerivations(EvalState & state, DrvNames & selectors,
|
||||||
Path & profile)
|
Path & profile, bool dryRun)
|
||||||
{
|
{
|
||||||
DrvInfos installedDrvs;
|
DrvInfos installedDrvs;
|
||||||
queryInstalled(state, installedDrvs, profile);
|
queryInstalled(state, installedDrvs, profile);
|
||||||
|
@ -354,6 +386,8 @@ static void uninstallDerivations(EvalState & state, DrvNames & selectors,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dryRun) return;
|
||||||
|
|
||||||
createUserEnv(state, installedDrvs, profile);
|
createUserEnv(state, installedDrvs, profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,7 +400,8 @@ static void opUninstall(Globals & globals,
|
||||||
|
|
||||||
DrvNames drvNames = drvNamesFromArgs(opArgs);
|
DrvNames drvNames = drvNamesFromArgs(opArgs);
|
||||||
|
|
||||||
uninstallDerivations(globals.state, drvNames, globals.profile);
|
uninstallDerivations(globals.state, drvNames,
|
||||||
|
globals.profile, globals.dryRun);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -575,6 +610,7 @@ void run(Strings args)
|
||||||
|
|
||||||
Globals globals;
|
Globals globals;
|
||||||
globals.nixExprPath = getDefNixExprPath();
|
globals.nixExprPath = getDefNixExprPath();
|
||||||
|
globals.dryRun = false;
|
||||||
|
|
||||||
for (Strings::iterator i = args.begin(); i != args.end(); ++i) {
|
for (Strings::iterator i = args.begin(); i != args.end(); ++i) {
|
||||||
string arg = *i;
|
string arg = *i;
|
||||||
|
@ -611,6 +647,10 @@ void run(Strings args)
|
||||||
op = opRollback;
|
op = opRollback;
|
||||||
else if (arg == "--list-generations")
|
else if (arg == "--list-generations")
|
||||||
op = opListGenerations;
|
op = opListGenerations;
|
||||||
|
else if (arg == "--dry-run") {
|
||||||
|
printMsg(lvlInfo, "(dry run; not doing anything)");
|
||||||
|
globals.dryRun = true;
|
||||||
|
}
|
||||||
else if (arg[0] == '-')
|
else if (arg[0] == '-')
|
||||||
opFlags.push_back(arg);
|
opFlags.push_back(arg);
|
||||||
else
|
else
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
#include "names.hh"
|
#include "names.hh"
|
||||||
|
|
||||||
|
|
||||||
|
DrvName::DrvName()
|
||||||
|
{
|
||||||
|
name = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Parse a derivation name. The `name' part of a derivation name is
|
/* Parse a derivation name. The `name' part of a derivation name is
|
||||||
everything up to but not including the first dash *not* followed by
|
everything up to but not including the first dash *not* followed by
|
||||||
a letter. The `version' part is the rest (excluding the separating
|
a letter. The `version' part is the rest (excluding the separating
|
||||||
|
|
|
@ -14,6 +14,7 @@ struct DrvName
|
||||||
string version;
|
string version;
|
||||||
unsigned int hits;
|
unsigned int hits;
|
||||||
|
|
||||||
|
DrvName();
|
||||||
DrvName(const string & s);
|
DrvName(const string & s);
|
||||||
bool matches(DrvName & n);
|
bool matches(DrvName & n);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue