forked from lix-project/lix
* A command `--list-generations' to show all generations for a
profile.
This commit is contained in:
parent
7c0fa4474f
commit
73ab2ed4fd
|
@ -1,5 +1,3 @@
|
||||||
#include <cerrno>
|
|
||||||
|
|
||||||
#include "profiles.hh"
|
#include "profiles.hh"
|
||||||
#include "names.hh"
|
#include "names.hh"
|
||||||
#include "globals.hh"
|
#include "globals.hh"
|
||||||
|
@ -9,6 +7,9 @@
|
||||||
#include "eval.hh"
|
#include "eval.hh"
|
||||||
#include "help.txt.hh"
|
#include "help.txt.hh"
|
||||||
|
|
||||||
|
#include <cerrno>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
struct Globals
|
struct Globals
|
||||||
{
|
{
|
||||||
|
@ -460,9 +461,9 @@ static void opSwitchProfile(Globals & globals,
|
||||||
Strings opFlags, Strings opArgs)
|
Strings opFlags, Strings opArgs)
|
||||||
{
|
{
|
||||||
if (opFlags.size() > 0)
|
if (opFlags.size() > 0)
|
||||||
throw UsageError(format("unknown flags `%1%'") % opFlags.front());
|
throw UsageError(format("unknown flag `%1%'") % opFlags.front());
|
||||||
if (opArgs.size() != 1)
|
if (opArgs.size() != 1)
|
||||||
throw UsageError(format("`--profile' takes exactly one argument"));
|
throw UsageError(format("exactly one argument expected"));
|
||||||
|
|
||||||
Path profile = opArgs.front();
|
Path profile = opArgs.front();
|
||||||
Path profileLink = getHomeDir() + "/.nix-profile";
|
Path profileLink = getHomeDir() + "/.nix-profile";
|
||||||
|
@ -471,13 +472,34 @@ static void opSwitchProfile(Globals & globals,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void opListGenerations(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"));
|
||||||
|
|
||||||
|
Generations gens = findGenerations(globals.profile);
|
||||||
|
|
||||||
|
for (Generations::iterator i = gens.begin(); i != gens.end(); ++i) {
|
||||||
|
tm t;
|
||||||
|
if (!localtime_r(&i->creationTime, &t)) throw Error("cannot convert time");
|
||||||
|
cout << format("%|4| %|4|-%|02|-%|02| %|02|:%|02|:%|02|\n")
|
||||||
|
% i->number
|
||||||
|
% (t.tm_year + 1900) % (t.tm_mon + 1) % t.tm_mday
|
||||||
|
% t.tm_hour % t.tm_min % t.tm_sec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void opDefaultExpr(Globals & globals,
|
static void opDefaultExpr(Globals & globals,
|
||||||
Strings opFlags, Strings opArgs)
|
Strings opFlags, Strings opArgs)
|
||||||
{
|
{
|
||||||
if (opFlags.size() > 0)
|
if (opFlags.size() > 0)
|
||||||
throw UsageError(format("unknown flags `%1%'") % opFlags.front());
|
throw UsageError(format("unknown flags `%1%'") % opFlags.front());
|
||||||
if (opArgs.size() != 1)
|
if (opArgs.size() != 1)
|
||||||
throw UsageError(format("`--import' takes exactly one argument"));
|
throw UsageError(format("exactly one argument expected"));
|
||||||
|
|
||||||
Path defNixExpr = absPath(opArgs.front());
|
Path defNixExpr = absPath(opArgs.front());
|
||||||
Path defNixExprLink = getDefNixExprPath();
|
Path defNixExprLink = getDefNixExprPath();
|
||||||
|
@ -526,6 +548,8 @@ void run(Strings args)
|
||||||
}
|
}
|
||||||
else if (arg == "--switch-profile" || arg == "-S")
|
else if (arg == "--switch-profile" || arg == "-S")
|
||||||
op = opSwitchProfile;
|
op = opSwitchProfile;
|
||||||
|
else if (arg == "--list-generations")
|
||||||
|
op = opListGenerations;
|
||||||
else if (arg[0] == '-')
|
else if (arg[0] == '-')
|
||||||
opFlags.push_back(arg);
|
opFlags.push_back(arg);
|
||||||
else
|
else
|
||||||
|
|
|
@ -1,13 +1,23 @@
|
||||||
#include "profiles.hh"
|
#include "profiles.hh"
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
Path createGeneration(Path profile, Path outPath, Path drvPath)
|
|
||||||
|
static bool cmpGensByNumber(const Generation & a, const Generation & b)
|
||||||
{
|
{
|
||||||
|
return a.number < b.number;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Generations findGenerations(Path profile)
|
||||||
|
{
|
||||||
|
Generations gens;
|
||||||
|
|
||||||
Path profileDir = dirOf(profile);
|
Path profileDir = dirOf(profile);
|
||||||
string profileName = baseNameOf(profile);
|
string profileName = baseNameOf(profile);
|
||||||
|
|
||||||
unsigned int num = 0;
|
|
||||||
|
|
||||||
Strings names = readDirectory(profileDir);
|
Strings names = readDirectory(profileDir);
|
||||||
for (Strings::iterator i = names.begin(); i != names.end(); ++i) {
|
for (Strings::iterator i = names.begin(); i != names.end(); ++i) {
|
||||||
if (string(*i, 0, profileName.size() + 1) != profileName + "-") continue;
|
if (string(*i, 0, profileName.size() + 1) != profileName + "-") continue;
|
||||||
|
@ -16,9 +26,32 @@ Path createGeneration(Path profile, Path outPath, Path drvPath)
|
||||||
if (p == string::npos) continue;
|
if (p == string::npos) continue;
|
||||||
istringstream str(string(s, 0, p));
|
istringstream str(string(s, 0, p));
|
||||||
unsigned int n;
|
unsigned int n;
|
||||||
if (str >> n && str.eof() && n >= num) num = n + 1;
|
if (str >> n && str.eof()) {
|
||||||
|
Generation gen;
|
||||||
|
gen.path = profileDir + "/" + *i;
|
||||||
|
gen.number = n;
|
||||||
|
struct stat st;
|
||||||
|
if (lstat(gen.path.c_str(), &st) != 0)
|
||||||
|
throw SysError(format("statting `%1%'") % gen.path);
|
||||||
|
gen.creationTime = st.st_mtime;
|
||||||
|
gens.push_back(gen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gens.sort(cmpGensByNumber);
|
||||||
|
|
||||||
|
return gens;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Path createGeneration(Path profile, Path outPath, Path drvPath)
|
||||||
|
{
|
||||||
|
/* The new generation number should be higher than old the
|
||||||
|
previous ones. */
|
||||||
|
Generations gens = findGenerations(profile);
|
||||||
|
unsigned int num = gens.size() > 0 ? gens.front().number : 0;
|
||||||
|
|
||||||
|
/* Create the new generation. */
|
||||||
Path generation, gcrootSrc;
|
Path generation, gcrootSrc;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
|
@ -6,6 +6,20 @@
|
||||||
#include "util.hh"
|
#include "util.hh"
|
||||||
|
|
||||||
|
|
||||||
|
struct Generation
|
||||||
|
{
|
||||||
|
int number;
|
||||||
|
Path path;
|
||||||
|
time_t creationTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef list<Generation> Generations;
|
||||||
|
|
||||||
|
|
||||||
|
/* Returns the list of currently present generations for the specified
|
||||||
|
profile, sorted by generation number. */
|
||||||
|
Generations findGenerations(Path profile);
|
||||||
|
|
||||||
Path createGeneration(Path profile, Path outPath, Path drvPath);
|
Path createGeneration(Path profile, Path outPath, Path drvPath);
|
||||||
|
|
||||||
void switchLink(Path link, Path target);
|
void switchLink(Path link, Path target);
|
||||||
|
|
Loading…
Reference in a new issue