aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2004-02-08 14:07:43 +0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2004-02-08 14:07:43 +0000
commit06a75a7e0c1813d90c205e654da43a32812ce5f4 (patch)
tree9cebb38c38d38c4e30ea28de86bd2e2f05eb1325
parentb8675aee5470c5387e4bfe4906e4ab1e94b610b2 (diff)
* 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.
-rw-r--r--src/nix-env/help.txt4
-rw-r--r--src/nix-env/main.cc59
-rw-r--r--src/nix-env/profiles.hh8
3 files changed, 71 insertions, 0 deletions
diff --git a/src/nix-env/help.txt b/src/nix-env/help.txt
index 3832f1655..9a772fc83 100644
--- a/src/nix-env/help.txt
+++ b/src/nix-env/help.txt
@@ -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
diff --git a/src/nix-env/main.cc b/src/nix-env/main.cc
index 5ef61bb30..69b3fdd9c 100644
--- a/src/nix-env/main.cc
+++ b/src/nix-env/main.cc
@@ -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] == '-')
diff --git a/src/nix-env/profiles.hh b/src/nix-env/profiles.hh
index 2422c9f74..2ce468dfa 100644
--- a/src/nix-env/profiles.hh
+++ b/src/nix-env/profiles.hh
@@ -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;