forked from lix-project/lix
* A command `--switch-generation' to switch to a specific generation
of the current profile, e.g., $ nix-env --list-generations ... 39 2004-02-02 17:53:53 40 2004-02-02 17:55:18 41 2004-02-02 17:55:41 42 2004-02-02 17:55:50 (current) $ nix-env --switch-generation 39 $ ls -l /nix/var/nix/profiles/default ... default -> default-39-link * Also a command `--rollback' which is just a convenience operation to rollback to the oldest generation younger than the current one. Note that generations properly form a tree. E.g., if after switching to generation 39, we perform an installation action, a generation 43 is created which is a descendant of 39, not 42. So a rollback from 43 ought to go back to 39. This is not currently implemented; generations form a linear sequence.
This commit is contained in:
parent
b8675aee54
commit
06a75a7e0c
3 changed files with 71 additions and 0 deletions
|
@ -13,6 +13,10 @@ The previous operations take a list of derivation names. The special
|
|||
name `*' may be used to indicate all derivations.
|
||||
|
||||
--switch-profile / -S [FILE]: switch to specified profile
|
||||
--switch-generation / -G NUMBER: switch to specified generation of profile
|
||||
--rollback: switch to the previous generation
|
||||
--list-generations: list available generations of a profile
|
||||
|
||||
--import / -I FILE: set default Nix expression
|
||||
|
||||
--version: output version information
|
||||
|
|
|
@ -472,6 +472,61 @@ static void opSwitchProfile(Globals & globals,
|
|||
}
|
||||
|
||||
|
||||
static const int prevGen = -2;
|
||||
|
||||
|
||||
static void switchGeneration(Globals & globals, int dstGen)
|
||||
{
|
||||
int curGen;
|
||||
Generations gens = findGenerations(globals.profile, curGen);
|
||||
|
||||
Generation dst;
|
||||
for (Generations::iterator i = gens.begin(); i != gens.end(); ++i)
|
||||
if ((dstGen == prevGen && i->number < curGen) ||
|
||||
(dstGen >= 0 && i->number == dstGen))
|
||||
dst = *i;
|
||||
|
||||
if (!dst)
|
||||
if (dstGen == prevGen)
|
||||
throw Error(format("no generation older than the current (%1%) exists")
|
||||
% curGen);
|
||||
else
|
||||
throw Error(format("generation %1% does not exist") % dstGen);
|
||||
|
||||
switchLink(globals.profile, dst.path);
|
||||
}
|
||||
|
||||
|
||||
static void opSwitchGeneration(Globals & globals,
|
||||
Strings opFlags, Strings opArgs)
|
||||
{
|
||||
if (opFlags.size() > 0)
|
||||
throw UsageError(format("unknown flag `%1%'") % opFlags.front());
|
||||
if (opArgs.size() != 1)
|
||||
throw UsageError(format("exactly one argument expected"));
|
||||
|
||||
istringstream str(opArgs.front());
|
||||
int dstGen;
|
||||
str >> dstGen;
|
||||
if (!str || !str.eof())
|
||||
throw UsageError(format("expected a generation number"));
|
||||
|
||||
switchGeneration(globals, dstGen);
|
||||
}
|
||||
|
||||
|
||||
static void opRollback(Globals & globals,
|
||||
Strings opFlags, Strings opArgs)
|
||||
{
|
||||
if (opFlags.size() > 0)
|
||||
throw UsageError(format("unknown flag `%1%'") % opFlags.front());
|
||||
if (opArgs.size() != 0)
|
||||
throw UsageError(format("no arguments expected"));
|
||||
|
||||
switchGeneration(globals, prevGen);
|
||||
}
|
||||
|
||||
|
||||
static void opListGenerations(Globals & globals,
|
||||
Strings opFlags, Strings opArgs)
|
||||
{
|
||||
|
@ -550,6 +605,10 @@ void run(Strings args)
|
|||
}
|
||||
else if (arg == "--switch-profile" || arg == "-S")
|
||||
op = opSwitchProfile;
|
||||
else if (arg == "--switch-generation" || arg == "-G")
|
||||
op = opSwitchGeneration;
|
||||
else if (arg == "--rollback")
|
||||
op = opRollback;
|
||||
else if (arg == "--list-generations")
|
||||
op = opListGenerations;
|
||||
else if (arg[0] == '-')
|
||||
|
|
|
@ -11,6 +11,14 @@ struct Generation
|
|||
int number;
|
||||
Path path;
|
||||
time_t creationTime;
|
||||
Generation()
|
||||
{
|
||||
number = -1;
|
||||
}
|
||||
operator bool() const
|
||||
{
|
||||
return number != -1;
|
||||
}
|
||||
};
|
||||
|
||||
typedef list<Generation> Generations;
|
||||
|
|
Loading…
Reference in a new issue