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
|
||||
--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:
|
||||
|
||||
--name: print derivation names (default)
|
||||
|
|
|
@ -16,6 +16,7 @@ struct Globals
|
|||
Path profile;
|
||||
Path nixExprPath;
|
||||
EvalState state;
|
||||
bool dryRun;
|
||||
};
|
||||
|
||||
|
||||
|
@ -201,7 +202,8 @@ void createUserEnv(EvalState & state, const DrvInfos & drvs,
|
|||
|
||||
|
||||
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);
|
||||
|
||||
|
@ -239,6 +241,8 @@ static void installDerivations(EvalState & state,
|
|||
queryInstalled(state, installedDrvs, profile);
|
||||
selectedDrvs.insert(installedDrvs.begin(), installedDrvs.end());
|
||||
|
||||
if (dryRun) return;
|
||||
|
||||
createUserEnv(state, selectedDrvs, profile);
|
||||
}
|
||||
|
||||
|
@ -252,12 +256,16 @@ static void opInstall(Globals & globals,
|
|||
DrvNames drvNames = drvNamesFromArgs(opArgs);
|
||||
|
||||
installDerivations(globals.state, globals.nixExprPath,
|
||||
drvNames, globals.profile);
|
||||
drvNames, globals.profile, globals.dryRun);
|
||||
}
|
||||
|
||||
|
||||
typedef enum { utLt, utLeq, utAlways } UpgradeType;
|
||||
|
||||
|
||||
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);
|
||||
|
||||
|
@ -293,29 +301,49 @@ static void upgradeDerivations(EvalState & state,
|
|||
}
|
||||
}
|
||||
|
||||
if (!upgrade) {
|
||||
newDrvs.insert(*i);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If yes, find the derivation in the input Nix expression
|
||||
with the same name and the highest version number. */
|
||||
DrvInfos::iterator bestDrv = i;
|
||||
DrvName bestName = drvName;
|
||||
if (upgrade) {
|
||||
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;
|
||||
for (DrvInfos::iterator j = availDrvs.begin();
|
||||
j != availDrvs.end(); ++j)
|
||||
{
|
||||
DrvName newName(j->second.name);
|
||||
if (newName.name == bestName.name &&
|
||||
compareVersions(newName.version, bestName.version) > 0)
|
||||
if (newName.name == drvName.name) {
|
||||
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,
|
||||
format("upgrading `%1%' to `%2%'")
|
||||
% i->second.name % bestDrv->second.name);
|
||||
newDrvs.insert(*bestDrv);
|
||||
} else newDrvs.insert(*i);
|
||||
}
|
||||
|
||||
newDrvs.insert(*bestDrv);
|
||||
}
|
||||
if (dryRun) return;
|
||||
|
||||
createUserEnv(state, newDrvs, profile);
|
||||
}
|
||||
|
@ -324,19 +352,23 @@ static void upgradeDerivations(EvalState & state,
|
|||
static void opUpgrade(Globals & globals,
|
||||
Strings opFlags, Strings opArgs)
|
||||
{
|
||||
if (opFlags.size() > 0)
|
||||
throw UsageError(format("unknown flags `%1%'") % opFlags.front());
|
||||
if (opArgs.size() < 1) throw UsageError("Nix file expected");
|
||||
UpgradeType upgradeType = utLt;
|
||||
for (Strings::iterator i = opFlags.begin();
|
||||
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);
|
||||
|
||||
upgradeDerivations(globals.state, globals.nixExprPath,
|
||||
drvNames, globals.profile);
|
||||
drvNames, globals.profile, upgradeType, globals.dryRun);
|
||||
}
|
||||
|
||||
|
||||
static void uninstallDerivations(EvalState & state, DrvNames & selectors,
|
||||
Path & profile)
|
||||
Path & profile, bool dryRun)
|
||||
{
|
||||
DrvInfos installedDrvs;
|
||||
queryInstalled(state, installedDrvs, profile);
|
||||
|
@ -354,6 +386,8 @@ static void uninstallDerivations(EvalState & state, DrvNames & selectors,
|
|||
}
|
||||
}
|
||||
|
||||
if (dryRun) return;
|
||||
|
||||
createUserEnv(state, installedDrvs, profile);
|
||||
}
|
||||
|
||||
|
@ -366,7 +400,8 @@ static void opUninstall(Globals & globals,
|
|||
|
||||
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.nixExprPath = getDefNixExprPath();
|
||||
globals.dryRun = false;
|
||||
|
||||
for (Strings::iterator i = args.begin(); i != args.end(); ++i) {
|
||||
string arg = *i;
|
||||
|
@ -611,6 +647,10 @@ void run(Strings args)
|
|||
op = opRollback;
|
||||
else if (arg == "--list-generations")
|
||||
op = opListGenerations;
|
||||
else if (arg == "--dry-run") {
|
||||
printMsg(lvlInfo, "(dry run; not doing anything)");
|
||||
globals.dryRun = true;
|
||||
}
|
||||
else if (arg[0] == '-')
|
||||
opFlags.push_back(arg);
|
||||
else
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
#include "names.hh"
|
||||
|
||||
|
||||
DrvName::DrvName()
|
||||
{
|
||||
name = "";
|
||||
}
|
||||
|
||||
|
||||
/* Parse a derivation name. The `name' part of a derivation name is
|
||||
everything up to but not including the first dash *not* followed by
|
||||
a letter. The `version' part is the rest (excluding the separating
|
||||
|
|
|
@ -14,6 +14,7 @@ struct DrvName
|
|||
string version;
|
||||
unsigned int hits;
|
||||
|
||||
DrvName();
|
||||
DrvName(const string & s);
|
||||
bool matches(DrvName & n);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue