2004-02-06 16:57:10 +02:00
|
|
|
#include "profiles.hh"
|
2004-02-06 16:49:41 +02:00
|
|
|
#include "names.hh"
|
2003-11-19 19:27:16 +02:00
|
|
|
#include "globals.hh"
|
2005-01-19 18:39:47 +02:00
|
|
|
#include "build.hh"
|
2003-11-19 19:27:16 +02:00
|
|
|
#include "shared.hh"
|
|
|
|
#include "parser.hh"
|
|
|
|
#include "eval.hh"
|
2003-12-01 17:55:05 +02:00
|
|
|
#include "help.txt.hh"
|
2004-10-29 14:22:49 +03:00
|
|
|
#include "nixexpr-ast.hh"
|
2003-11-19 19:27:16 +02:00
|
|
|
|
2004-02-06 18:03:27 +02:00
|
|
|
#include <cerrno>
|
|
|
|
#include <ctime>
|
|
|
|
|
2003-11-19 19:27:16 +02:00
|
|
|
|
2003-12-22 00:34:41 +02:00
|
|
|
struct Globals
|
|
|
|
{
|
2004-02-06 12:30:20 +02:00
|
|
|
Path profile;
|
2004-01-05 18:26:43 +02:00
|
|
|
Path nixExprPath;
|
2003-12-22 00:34:41 +02:00
|
|
|
EvalState state;
|
2004-02-09 13:59:39 +02:00
|
|
|
bool dryRun;
|
2004-06-28 17:40:26 +03:00
|
|
|
bool preserveInstalled;
|
2004-07-01 16:56:56 +03:00
|
|
|
string systemFilter;
|
2003-12-22 00:34:41 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
typedef void (* Operation) (Globals & globals,
|
2003-11-19 19:27:16 +02:00
|
|
|
Strings opFlags, Strings opArgs);
|
|
|
|
|
|
|
|
|
|
|
|
struct DrvInfo
|
|
|
|
{
|
|
|
|
string name;
|
2004-07-01 16:13:37 +03:00
|
|
|
string system;
|
2003-11-19 19:27:16 +02:00
|
|
|
Path drvPath;
|
|
|
|
Path outPath;
|
|
|
|
};
|
|
|
|
|
2003-11-19 23:32:03 +02:00
|
|
|
typedef map<Path, DrvInfo> DrvInfos;
|
2004-02-02 12:51:54 +02:00
|
|
|
typedef vector<DrvInfo> DrvInfoList;
|
2003-11-19 19:27:16 +02:00
|
|
|
|
|
|
|
|
2003-12-01 17:55:05 +02:00
|
|
|
void printHelp()
|
|
|
|
{
|
|
|
|
cout << string((char *) helpText, sizeof helpText);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-11-19 19:27:16 +02:00
|
|
|
bool parseDerivation(EvalState & state, Expr e, DrvInfo & drv)
|
|
|
|
{
|
2004-10-27 01:54:26 +03:00
|
|
|
ATermList es;
|
2003-11-19 19:27:16 +02:00
|
|
|
e = evalExpr(state, e);
|
2004-10-27 01:54:26 +03:00
|
|
|
if (!matchAttrs(e, es)) return false;
|
2003-11-19 19:27:16 +02:00
|
|
|
Expr a = queryAttr(e, "type");
|
|
|
|
if (!a || evalString(state, a) != "derivation") return false;
|
|
|
|
|
|
|
|
a = queryAttr(e, "name");
|
|
|
|
if (!a) throw badTerm("derivation name missing", e);
|
|
|
|
drv.name = evalString(state, a);
|
|
|
|
|
2004-07-01 16:13:37 +03:00
|
|
|
a = queryAttr(e, "system");
|
|
|
|
if (!a)
|
|
|
|
drv.system = "unknown";
|
|
|
|
else
|
|
|
|
drv.system = evalString(state, a);
|
|
|
|
|
2003-11-19 19:27:16 +02:00
|
|
|
a = queryAttr(e, "drvPath");
|
|
|
|
if (!a) throw badTerm("derivation path missing", e);
|
|
|
|
drv.drvPath = evalPath(state, a);
|
|
|
|
|
|
|
|
a = queryAttr(e, "outPath");
|
|
|
|
if (!a) throw badTerm("output path missing", e);
|
|
|
|
drv.outPath = evalPath(state, a);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool parseDerivations(EvalState & state, Expr e, DrvInfos & drvs)
|
|
|
|
{
|
2003-11-19 23:32:03 +02:00
|
|
|
ATermList es;
|
2003-11-24 13:01:19 +02:00
|
|
|
DrvInfo drv;
|
2003-11-19 23:32:03 +02:00
|
|
|
|
2003-11-19 19:27:16 +02:00
|
|
|
e = evalExpr(state, e);
|
2003-11-24 13:01:19 +02:00
|
|
|
|
|
|
|
if (parseDerivation(state, e, drv))
|
|
|
|
drvs[drv.drvPath] = drv;
|
|
|
|
|
2004-10-27 01:54:26 +03:00
|
|
|
else if (matchAttrs(e, es)) {
|
2003-11-19 23:32:03 +02:00
|
|
|
ATermMap drvMap;
|
|
|
|
queryAllAttrs(e, drvMap);
|
|
|
|
for (ATermIterator i(drvMap.keys()); i; ++i) {
|
|
|
|
debug(format("evaluating attribute `%1%'") % *i);
|
|
|
|
if (parseDerivation(state, drvMap.get(*i), drv))
|
|
|
|
drvs[drv.drvPath] = drv;
|
2004-04-21 12:37:37 +03:00
|
|
|
else
|
|
|
|
parseDerivations(state, drvMap.get(*i), drvs);
|
2003-11-19 23:32:03 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-10-27 01:54:26 +03:00
|
|
|
else if (matchList(e, es)) {
|
2003-11-19 23:32:03 +02:00
|
|
|
for (ATermIterator i(es); i; ++i) {
|
2003-11-20 15:48:48 +02:00
|
|
|
debug(format("evaluating list element"));
|
2003-11-19 23:32:03 +02:00
|
|
|
if (parseDerivation(state, *i, drv))
|
|
|
|
drvs[drv.drvPath] = drv;
|
2004-04-21 12:37:37 +03:00
|
|
|
else
|
|
|
|
parseDerivations(state, *i, drvs);
|
2003-11-19 23:32:03 +02:00
|
|
|
}
|
2003-11-19 19:27:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-07-01 16:56:56 +03:00
|
|
|
void loadDerivations(EvalState & state, Path nePath, DrvInfos & drvs,
|
|
|
|
string systemFilter)
|
2003-11-19 19:27:16 +02:00
|
|
|
{
|
2004-02-04 18:03:29 +02:00
|
|
|
Expr e = parseExprFromFile(state, absPath(nePath));
|
2003-11-19 19:27:16 +02:00
|
|
|
if (!parseDerivations(state, e, drvs))
|
2004-04-06 01:27:41 +03:00
|
|
|
throw Error("set of derivations expected");
|
2004-07-01 16:56:56 +03:00
|
|
|
|
|
|
|
/* Filter out all derivations not applicable to the current
|
|
|
|
system. */
|
|
|
|
for (DrvInfos::iterator i = drvs.begin(), j; i != drvs.end(); i = j) {
|
|
|
|
j = i; j++;
|
|
|
|
if (systemFilter != "*" && i->second.system != systemFilter)
|
|
|
|
drvs.erase(i);
|
|
|
|
}
|
2003-11-19 19:27:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-01-05 18:26:43 +02:00
|
|
|
static Path getHomeDir()
|
|
|
|
{
|
2004-05-12 12:35:51 +03:00
|
|
|
Path homeDir(getEnv("HOME", ""));
|
2004-01-05 18:26:43 +02:00
|
|
|
if (homeDir == "") throw Error("HOME environment variable not set");
|
|
|
|
return homeDir;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static Path getDefNixExprPath()
|
|
|
|
{
|
|
|
|
return getHomeDir() + "/.nix-defexpr";
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-04-06 01:27:41 +03:00
|
|
|
struct AddPos : TermFun
|
|
|
|
{
|
|
|
|
ATerm operator () (ATerm e)
|
|
|
|
{
|
|
|
|
ATerm x, y, z;
|
2004-10-27 01:54:26 +03:00
|
|
|
if (matchBind(e, x, y, z)) return e;
|
|
|
|
if (matchBind2(e, x, y))
|
|
|
|
return makeBind(x, y, makeNoPos());
|
2004-04-06 01:27:41 +03:00
|
|
|
return e;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2003-12-22 00:34:41 +02:00
|
|
|
void queryInstalled(EvalState & state, DrvInfos & drvs,
|
|
|
|
const Path & userEnv)
|
2003-11-19 23:32:03 +02:00
|
|
|
{
|
2003-12-22 00:34:41 +02:00
|
|
|
Path path = userEnv + "/manifest";
|
2003-11-19 23:32:03 +02:00
|
|
|
|
|
|
|
if (!pathExists(path)) return; /* not an error, assume nothing installed */
|
|
|
|
|
|
|
|
Expr e = ATreadFromNamedFile(path.c_str());
|
|
|
|
if (!e) throw Error(format("cannot read Nix expression from `%1%'") % path);
|
|
|
|
|
2004-04-06 01:27:41 +03:00
|
|
|
/* Compatibility: Bind(x, y) -> Bind(x, y, NoPos). */
|
|
|
|
AddPos addPos;
|
|
|
|
e = bottomupRewrite(addPos, e);
|
|
|
|
|
2003-11-19 23:32:03 +02:00
|
|
|
if (!parseDerivations(state, e, drvs))
|
2004-04-06 01:27:41 +03:00
|
|
|
throw badTerm(format("set of derivations expected in `%1%'") % path, e);
|
2003-11-19 23:32:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-12-22 00:34:41 +02:00
|
|
|
void createUserEnv(EvalState & state, const DrvInfos & drvs,
|
2004-02-06 12:30:20 +02:00
|
|
|
const Path & profile)
|
2003-11-19 19:27:16 +02:00
|
|
|
{
|
|
|
|
/* Get the environment builder expression. */
|
2004-02-04 18:03:29 +02:00
|
|
|
Expr envBuilder = parseExprFromFile(state,
|
|
|
|
nixDataDir + "/nix/corepkgs/buildenv"); /* !!! */
|
2003-11-19 19:27:16 +02:00
|
|
|
|
|
|
|
/* Construct the whole top level derivation. */
|
|
|
|
ATermList inputs = ATempty;
|
2003-11-20 15:48:48 +02:00
|
|
|
for (DrvInfos::const_iterator i = drvs.begin();
|
|
|
|
i != drvs.end(); ++i)
|
2003-11-19 19:27:16 +02:00
|
|
|
{
|
* Removed the `id' attribute hack.
* Formalise the notion of fixed-output derivations, i.e., derivations
for which a cryptographic hash of the output is known in advance.
Changes to such derivations should not propagate upwards through the
dependency graph. Previously this was done by specifying the hash
component of the output path through the `id' attribute, but this is
insecure since you can lie about it (i.e., you can specify any hash
and then produce a completely different output). Now the
responsibility for checking the output is moved from the builder to
Nix itself.
A fixed-output derivation can be created by specifying the
`outputHash' and `outputHashAlgo' attributes, the latter taking
values `md5', `sha1', and `sha256', and the former specifying the
actual hash in hexadecimal or in base-32 (auto-detected by looking
at the length of the attribute value). MD5 is included for
compatibility but should be considered deprecated.
* Removed the `drvPath' pseudo-attribute in derivation results. It's
no longer necessary.
* Cleaned up the support for multiple output paths in derivation store
expressions. Each output now has a unique identifier (e.g., `out',
`devel', `docs'). Previously there was no way to tell output paths
apart at the store expression level.
* `nix-hash' now has a flag `--base32' to specify that the hash should
be printed in base-32 notation.
* `fetchurl' accepts parameters `sha256' and `sha1' in addition to
`md5'.
* `nix-prefetch-url' now prints out a SHA-1 hash in base-32. (TODO: a
flag to specify the hash.)
2005-01-17 18:55:19 +02:00
|
|
|
ATerm t = makeAttrs(ATmakeList5(
|
2004-11-03 20:12:03 +02:00
|
|
|
makeBind(toATerm("type"),
|
|
|
|
makeStr(toATerm("derivation")), makeNoPos()),
|
|
|
|
makeBind(toATerm("name"),
|
|
|
|
makeStr(toATerm(i->second.name)), makeNoPos()),
|
|
|
|
makeBind(toATerm("system"),
|
|
|
|
makeStr(toATerm(i->second.system)), makeNoPos()),
|
|
|
|
makeBind(toATerm("drvPath"),
|
|
|
|
makePath(toATerm(i->second.drvPath)), makeNoPos()),
|
|
|
|
makeBind(toATerm("outPath"),
|
|
|
|
makePath(toATerm(i->second.outPath)), makeNoPos())
|
2004-10-27 01:54:26 +03:00
|
|
|
));
|
2003-11-19 19:27:16 +02:00
|
|
|
inputs = ATinsert(inputs, t);
|
|
|
|
}
|
|
|
|
|
2004-10-27 01:54:26 +03:00
|
|
|
ATerm inputs2 = makeList(ATreverse(inputs));
|
2003-11-19 19:27:16 +02:00
|
|
|
|
|
|
|
/* Also write a copy of the list of inputs to the store; we need
|
|
|
|
it for future modifications of the environment. */
|
2005-01-19 16:36:00 +02:00
|
|
|
Path inputsFile = addTextToStore("env-inputs", atPrint(inputs2));
|
2003-11-19 19:27:16 +02:00
|
|
|
|
2004-10-27 01:54:26 +03:00
|
|
|
Expr topLevel = makeCall(envBuilder, makeAttrs(ATmakeList3(
|
2004-11-03 20:12:03 +02:00
|
|
|
makeBind(toATerm("system"),
|
|
|
|
makeStr(toATerm(thisSystem)), makeNoPos()),
|
|
|
|
makeBind(toATerm("derivations"), inputs2, makeNoPos()),
|
|
|
|
makeBind(toATerm("manifest"),
|
|
|
|
makePath(toATerm(inputsFile)), makeNoPos())
|
2004-10-27 01:54:26 +03:00
|
|
|
)));
|
2003-11-19 19:27:16 +02:00
|
|
|
|
|
|
|
/* Instantiate it. */
|
|
|
|
debug(format("evaluating builder expression `%1%'") % topLevel);
|
|
|
|
DrvInfo topLevelDrv;
|
|
|
|
if (!parseDerivation(state, topLevel, topLevelDrv))
|
|
|
|
abort();
|
|
|
|
|
|
|
|
/* Realise the resulting store expression. */
|
2005-01-19 13:16:11 +02:00
|
|
|
debug(format("building user environment"));
|
2005-01-19 17:02:02 +02:00
|
|
|
PathSet drvPaths;
|
|
|
|
drvPaths.insert(topLevelDrv.drvPath);
|
|
|
|
buildDerivations(drvPaths);
|
2003-11-19 19:27:16 +02:00
|
|
|
|
|
|
|
/* Switch the current user environment to the output path. */
|
|
|
|
debug(format("switching to new user environment"));
|
2004-02-06 12:30:20 +02:00
|
|
|
Path generation = createGeneration(profile,
|
2005-01-19 13:16:11 +02:00
|
|
|
topLevelDrv.outPath, topLevelDrv.drvPath);
|
2004-02-06 12:30:20 +02:00
|
|
|
switchLink(profile, generation);
|
2003-11-19 19:27:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
* Upgrade operation in `nix-env'. For instance, you can say
nix-env -u foo.nix strategoxt
to replace the installed `strategoxt' derivation with the one from `foo.nix', if
the latter has a higher version number. This is a no-op if `strategoxt' is not
installed. Wildcards are also accepted, so
nix-env -u foo.nix '*'
will replace any installed derivation with newer versions from `foo.nix', if
available.
The notion of "version number" is somewhat ad hoc, but should be useful in most
cases, as evidenced by the following unit tests for the version comparator:
TEST("1.0", "2.3", -1);
TEST("2.1", "2.3", -1);
TEST("2.3", "2.3", 0);
TEST("2.5", "2.3", 1);
TEST("3.1", "2.3", 1);
TEST("2.3.1", "2.3", 1);
TEST("2.3.1", "2.3a", 1);
TEST("2.3pre1", "2.3", -1);
TEST("2.3pre3", "2.3pre12", -1);
TEST("2.3a", "2.3c", -1);
TEST("2.3pre1", "2.3c", -1);
TEST("2.3pre1", "2.3q", -1);
(-1 = less, 0 = equal, 1 = greater)
* A new verbosity level `lvlInfo', between `lvlError' and `lvlTalkative'. This is
the default for `nix-env', so without any `-v' flags users should get useful
output, e.g.,
$ nix-env -u foo.nix strategoxt
upgrading `strategoxt-0.9.2' to `strategoxt-0.9.3'
2003-12-22 18:04:00 +02:00
|
|
|
static void installDerivations(EvalState & state,
|
2004-02-09 13:59:39 +02:00
|
|
|
Path nePath, DrvNames & selectors, const Path & profile,
|
2004-07-01 16:56:56 +03:00
|
|
|
bool dryRun, bool preserveInstalled, string systemFilter)
|
2003-11-20 15:48:48 +02:00
|
|
|
{
|
|
|
|
debug(format("installing derivations from `%1%'") % nePath);
|
|
|
|
|
|
|
|
/* Fetch all derivations from the input file. */
|
|
|
|
DrvInfos availDrvs;
|
2004-07-01 16:56:56 +03:00
|
|
|
loadDerivations(state, nePath, availDrvs, systemFilter);
|
2003-11-20 15:48:48 +02:00
|
|
|
|
|
|
|
/* Filter out the ones we're not interested in. */
|
|
|
|
DrvInfos selectedDrvs;
|
2004-06-28 17:40:26 +03:00
|
|
|
StringSet selectedNames;
|
2003-12-22 01:58:56 +02:00
|
|
|
for (DrvInfos::iterator i = availDrvs.begin();
|
|
|
|
i != availDrvs.end(); ++i)
|
|
|
|
{
|
|
|
|
DrvName drvName(i->second.name);
|
|
|
|
for (DrvNames::iterator j = selectors.begin();
|
|
|
|
j != selectors.end(); ++j)
|
2003-11-24 13:01:19 +02:00
|
|
|
{
|
2003-12-22 01:58:56 +02:00
|
|
|
if (j->matches(drvName)) {
|
* Upgrade operation in `nix-env'. For instance, you can say
nix-env -u foo.nix strategoxt
to replace the installed `strategoxt' derivation with the one from `foo.nix', if
the latter has a higher version number. This is a no-op if `strategoxt' is not
installed. Wildcards are also accepted, so
nix-env -u foo.nix '*'
will replace any installed derivation with newer versions from `foo.nix', if
available.
The notion of "version number" is somewhat ad hoc, but should be useful in most
cases, as evidenced by the following unit tests for the version comparator:
TEST("1.0", "2.3", -1);
TEST("2.1", "2.3", -1);
TEST("2.3", "2.3", 0);
TEST("2.5", "2.3", 1);
TEST("3.1", "2.3", 1);
TEST("2.3.1", "2.3", 1);
TEST("2.3.1", "2.3a", 1);
TEST("2.3pre1", "2.3", -1);
TEST("2.3pre3", "2.3pre12", -1);
TEST("2.3a", "2.3c", -1);
TEST("2.3pre1", "2.3c", -1);
TEST("2.3pre1", "2.3q", -1);
(-1 = less, 0 = equal, 1 = greater)
* A new verbosity level `lvlInfo', between `lvlError' and `lvlTalkative'. This is
the default for `nix-env', so without any `-v' flags users should get useful
output, e.g.,
$ nix-env -u foo.nix strategoxt
upgrading `strategoxt-0.9.2' to `strategoxt-0.9.3'
2003-12-22 18:04:00 +02:00
|
|
|
printMsg(lvlInfo,
|
|
|
|
format("installing `%1%'") % i->second.name);
|
|
|
|
j->hits++;
|
2003-12-22 01:58:56 +02:00
|
|
|
selectedDrvs.insert(*i);
|
2004-06-28 17:40:26 +03:00
|
|
|
selectedNames.insert(drvName.name);
|
2003-12-22 01:58:56 +02:00
|
|
|
}
|
2003-11-24 13:01:19 +02:00
|
|
|
}
|
2003-11-20 15:48:48 +02:00
|
|
|
}
|
|
|
|
|
2003-12-22 01:58:56 +02:00
|
|
|
/* Check that all selectors have been used. */
|
|
|
|
for (DrvNames::iterator i = selectors.begin();
|
|
|
|
i != selectors.end(); ++i)
|
* Upgrade operation in `nix-env'. For instance, you can say
nix-env -u foo.nix strategoxt
to replace the installed `strategoxt' derivation with the one from `foo.nix', if
the latter has a higher version number. This is a no-op if `strategoxt' is not
installed. Wildcards are also accepted, so
nix-env -u foo.nix '*'
will replace any installed derivation with newer versions from `foo.nix', if
available.
The notion of "version number" is somewhat ad hoc, but should be useful in most
cases, as evidenced by the following unit tests for the version comparator:
TEST("1.0", "2.3", -1);
TEST("2.1", "2.3", -1);
TEST("2.3", "2.3", 0);
TEST("2.5", "2.3", 1);
TEST("3.1", "2.3", 1);
TEST("2.3.1", "2.3", 1);
TEST("2.3.1", "2.3a", 1);
TEST("2.3pre1", "2.3", -1);
TEST("2.3pre3", "2.3pre12", -1);
TEST("2.3a", "2.3c", -1);
TEST("2.3pre1", "2.3c", -1);
TEST("2.3pre1", "2.3q", -1);
(-1 = less, 0 = equal, 1 = greater)
* A new verbosity level `lvlInfo', between `lvlError' and `lvlTalkative'. This is
the default for `nix-env', so without any `-v' flags users should get useful
output, e.g.,
$ nix-env -u foo.nix strategoxt
upgrading `strategoxt-0.9.2' to `strategoxt-0.9.3'
2003-12-22 18:04:00 +02:00
|
|
|
if (i->hits == 0)
|
2003-12-22 01:58:56 +02:00
|
|
|
throw Error(format("selector `%1%' matches no derivations")
|
* Upgrade operation in `nix-env'. For instance, you can say
nix-env -u foo.nix strategoxt
to replace the installed `strategoxt' derivation with the one from `foo.nix', if
the latter has a higher version number. This is a no-op if `strategoxt' is not
installed. Wildcards are also accepted, so
nix-env -u foo.nix '*'
will replace any installed derivation with newer versions from `foo.nix', if
available.
The notion of "version number" is somewhat ad hoc, but should be useful in most
cases, as evidenced by the following unit tests for the version comparator:
TEST("1.0", "2.3", -1);
TEST("2.1", "2.3", -1);
TEST("2.3", "2.3", 0);
TEST("2.5", "2.3", 1);
TEST("3.1", "2.3", 1);
TEST("2.3.1", "2.3", 1);
TEST("2.3.1", "2.3a", 1);
TEST("2.3pre1", "2.3", -1);
TEST("2.3pre3", "2.3pre12", -1);
TEST("2.3a", "2.3c", -1);
TEST("2.3pre1", "2.3c", -1);
TEST("2.3pre1", "2.3q", -1);
(-1 = less, 0 = equal, 1 = greater)
* A new verbosity level `lvlInfo', between `lvlError' and `lvlTalkative'. This is
the default for `nix-env', so without any `-v' flags users should get useful
output, e.g.,
$ nix-env -u foo.nix strategoxt
upgrading `strategoxt-0.9.2' to `strategoxt-0.9.3'
2003-12-22 18:04:00 +02:00
|
|
|
% i->fullName);
|
2003-12-22 01:58:56 +02:00
|
|
|
|
2003-11-20 15:48:48 +02:00
|
|
|
/* Add in the already installed derivations. */
|
|
|
|
DrvInfos installedDrvs;
|
2004-02-06 12:30:20 +02:00
|
|
|
queryInstalled(state, installedDrvs, profile);
|
2004-06-28 17:40:26 +03:00
|
|
|
|
|
|
|
for (DrvInfos::iterator i = installedDrvs.begin();
|
|
|
|
i != installedDrvs.end(); ++i)
|
|
|
|
{
|
|
|
|
DrvName drvName(i->second.name);
|
|
|
|
if (!preserveInstalled &&
|
|
|
|
selectedNames.find(drvName.name) != selectedNames.end())
|
|
|
|
printMsg(lvlInfo,
|
|
|
|
format("uninstalling `%1%'") % i->second.name);
|
|
|
|
else
|
|
|
|
selectedDrvs.insert(*i);
|
|
|
|
}
|
2003-11-20 15:48:48 +02:00
|
|
|
|
2004-02-09 13:59:39 +02:00
|
|
|
if (dryRun) return;
|
|
|
|
|
2004-02-06 12:30:20 +02:00
|
|
|
createUserEnv(state, selectedDrvs, profile);
|
2003-11-20 15:48:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-12-22 00:34:41 +02:00
|
|
|
static void opInstall(Globals & globals,
|
2003-11-19 19:27:16 +02:00
|
|
|
Strings opFlags, Strings opArgs)
|
|
|
|
{
|
2003-12-22 00:34:41 +02:00
|
|
|
if (opFlags.size() > 0)
|
|
|
|
throw UsageError(format("unknown flags `%1%'") % opFlags.front());
|
2003-11-19 19:27:16 +02:00
|
|
|
|
2004-01-05 18:26:43 +02:00
|
|
|
DrvNames drvNames = drvNamesFromArgs(opArgs);
|
2003-12-22 01:58:56 +02:00
|
|
|
|
2004-01-05 18:26:43 +02:00
|
|
|
installDerivations(globals.state, globals.nixExprPath,
|
2004-06-28 17:40:26 +03:00
|
|
|
drvNames, globals.profile, globals.dryRun,
|
2004-07-01 16:56:56 +03:00
|
|
|
globals.preserveInstalled, globals.systemFilter);
|
2003-12-22 01:58:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-02-09 13:59:39 +02:00
|
|
|
typedef enum { utLt, utLeq, utAlways } UpgradeType;
|
|
|
|
|
|
|
|
|
* Upgrade operation in `nix-env'. For instance, you can say
nix-env -u foo.nix strategoxt
to replace the installed `strategoxt' derivation with the one from `foo.nix', if
the latter has a higher version number. This is a no-op if `strategoxt' is not
installed. Wildcards are also accepted, so
nix-env -u foo.nix '*'
will replace any installed derivation with newer versions from `foo.nix', if
available.
The notion of "version number" is somewhat ad hoc, but should be useful in most
cases, as evidenced by the following unit tests for the version comparator:
TEST("1.0", "2.3", -1);
TEST("2.1", "2.3", -1);
TEST("2.3", "2.3", 0);
TEST("2.5", "2.3", 1);
TEST("3.1", "2.3", 1);
TEST("2.3.1", "2.3", 1);
TEST("2.3.1", "2.3a", 1);
TEST("2.3pre1", "2.3", -1);
TEST("2.3pre3", "2.3pre12", -1);
TEST("2.3a", "2.3c", -1);
TEST("2.3pre1", "2.3c", -1);
TEST("2.3pre1", "2.3q", -1);
(-1 = less, 0 = equal, 1 = greater)
* A new verbosity level `lvlInfo', between `lvlError' and `lvlTalkative'. This is
the default for `nix-env', so without any `-v' flags users should get useful
output, e.g.,
$ nix-env -u foo.nix strategoxt
upgrading `strategoxt-0.9.2' to `strategoxt-0.9.3'
2003-12-22 18:04:00 +02:00
|
|
|
static void upgradeDerivations(EvalState & state,
|
2004-02-09 13:59:39 +02:00
|
|
|
Path nePath, DrvNames & selectors, const Path & profile,
|
2004-07-01 16:56:56 +03:00
|
|
|
UpgradeType upgradeType, bool dryRun, string systemFilter)
|
* Upgrade operation in `nix-env'. For instance, you can say
nix-env -u foo.nix strategoxt
to replace the installed `strategoxt' derivation with the one from `foo.nix', if
the latter has a higher version number. This is a no-op if `strategoxt' is not
installed. Wildcards are also accepted, so
nix-env -u foo.nix '*'
will replace any installed derivation with newer versions from `foo.nix', if
available.
The notion of "version number" is somewhat ad hoc, but should be useful in most
cases, as evidenced by the following unit tests for the version comparator:
TEST("1.0", "2.3", -1);
TEST("2.1", "2.3", -1);
TEST("2.3", "2.3", 0);
TEST("2.5", "2.3", 1);
TEST("3.1", "2.3", 1);
TEST("2.3.1", "2.3", 1);
TEST("2.3.1", "2.3a", 1);
TEST("2.3pre1", "2.3", -1);
TEST("2.3pre3", "2.3pre12", -1);
TEST("2.3a", "2.3c", -1);
TEST("2.3pre1", "2.3c", -1);
TEST("2.3pre1", "2.3q", -1);
(-1 = less, 0 = equal, 1 = greater)
* A new verbosity level `lvlInfo', between `lvlError' and `lvlTalkative'. This is
the default for `nix-env', so without any `-v' flags users should get useful
output, e.g.,
$ nix-env -u foo.nix strategoxt
upgrading `strategoxt-0.9.2' to `strategoxt-0.9.3'
2003-12-22 18:04:00 +02:00
|
|
|
{
|
|
|
|
debug(format("upgrading derivations from `%1%'") % nePath);
|
|
|
|
|
|
|
|
/* Upgrade works as follows: we take all currently installed
|
|
|
|
derivations, and for any derivation matching any selector, look
|
|
|
|
for a derivation in the input Nix expression that has the same
|
|
|
|
name and a higher version number. */
|
|
|
|
|
|
|
|
/* Load the currently installed derivations. */
|
|
|
|
DrvInfos installedDrvs;
|
2004-02-06 12:30:20 +02:00
|
|
|
queryInstalled(state, installedDrvs, profile);
|
* Upgrade operation in `nix-env'. For instance, you can say
nix-env -u foo.nix strategoxt
to replace the installed `strategoxt' derivation with the one from `foo.nix', if
the latter has a higher version number. This is a no-op if `strategoxt' is not
installed. Wildcards are also accepted, so
nix-env -u foo.nix '*'
will replace any installed derivation with newer versions from `foo.nix', if
available.
The notion of "version number" is somewhat ad hoc, but should be useful in most
cases, as evidenced by the following unit tests for the version comparator:
TEST("1.0", "2.3", -1);
TEST("2.1", "2.3", -1);
TEST("2.3", "2.3", 0);
TEST("2.5", "2.3", 1);
TEST("3.1", "2.3", 1);
TEST("2.3.1", "2.3", 1);
TEST("2.3.1", "2.3a", 1);
TEST("2.3pre1", "2.3", -1);
TEST("2.3pre3", "2.3pre12", -1);
TEST("2.3a", "2.3c", -1);
TEST("2.3pre1", "2.3c", -1);
TEST("2.3pre1", "2.3q", -1);
(-1 = less, 0 = equal, 1 = greater)
* A new verbosity level `lvlInfo', between `lvlError' and `lvlTalkative'. This is
the default for `nix-env', so without any `-v' flags users should get useful
output, e.g.,
$ nix-env -u foo.nix strategoxt
upgrading `strategoxt-0.9.2' to `strategoxt-0.9.3'
2003-12-22 18:04:00 +02:00
|
|
|
|
|
|
|
/* Fetch all derivations from the input file. */
|
|
|
|
DrvInfos availDrvs;
|
2004-07-01 16:56:56 +03:00
|
|
|
loadDerivations(state, nePath, availDrvs, systemFilter);
|
* Upgrade operation in `nix-env'. For instance, you can say
nix-env -u foo.nix strategoxt
to replace the installed `strategoxt' derivation with the one from `foo.nix', if
the latter has a higher version number. This is a no-op if `strategoxt' is not
installed. Wildcards are also accepted, so
nix-env -u foo.nix '*'
will replace any installed derivation with newer versions from `foo.nix', if
available.
The notion of "version number" is somewhat ad hoc, but should be useful in most
cases, as evidenced by the following unit tests for the version comparator:
TEST("1.0", "2.3", -1);
TEST("2.1", "2.3", -1);
TEST("2.3", "2.3", 0);
TEST("2.5", "2.3", 1);
TEST("3.1", "2.3", 1);
TEST("2.3.1", "2.3", 1);
TEST("2.3.1", "2.3a", 1);
TEST("2.3pre1", "2.3", -1);
TEST("2.3pre3", "2.3pre12", -1);
TEST("2.3a", "2.3c", -1);
TEST("2.3pre1", "2.3c", -1);
TEST("2.3pre1", "2.3q", -1);
(-1 = less, 0 = equal, 1 = greater)
* A new verbosity level `lvlInfo', between `lvlError' and `lvlTalkative'. This is
the default for `nix-env', so without any `-v' flags users should get useful
output, e.g.,
$ nix-env -u foo.nix strategoxt
upgrading `strategoxt-0.9.2' to `strategoxt-0.9.3'
2003-12-22 18:04:00 +02:00
|
|
|
|
|
|
|
/* Go through all installed derivations. */
|
2003-12-24 00:13:36 +02:00
|
|
|
DrvInfos newDrvs;
|
* Upgrade operation in `nix-env'. For instance, you can say
nix-env -u foo.nix strategoxt
to replace the installed `strategoxt' derivation with the one from `foo.nix', if
the latter has a higher version number. This is a no-op if `strategoxt' is not
installed. Wildcards are also accepted, so
nix-env -u foo.nix '*'
will replace any installed derivation with newer versions from `foo.nix', if
available.
The notion of "version number" is somewhat ad hoc, but should be useful in most
cases, as evidenced by the following unit tests for the version comparator:
TEST("1.0", "2.3", -1);
TEST("2.1", "2.3", -1);
TEST("2.3", "2.3", 0);
TEST("2.5", "2.3", 1);
TEST("3.1", "2.3", 1);
TEST("2.3.1", "2.3", 1);
TEST("2.3.1", "2.3a", 1);
TEST("2.3pre1", "2.3", -1);
TEST("2.3pre3", "2.3pre12", -1);
TEST("2.3a", "2.3c", -1);
TEST("2.3pre1", "2.3c", -1);
TEST("2.3pre1", "2.3q", -1);
(-1 = less, 0 = equal, 1 = greater)
* A new verbosity level `lvlInfo', between `lvlError' and `lvlTalkative'. This is
the default for `nix-env', so without any `-v' flags users should get useful
output, e.g.,
$ nix-env -u foo.nix strategoxt
upgrading `strategoxt-0.9.2' to `strategoxt-0.9.3'
2003-12-22 18:04:00 +02:00
|
|
|
for (DrvInfos::iterator i = installedDrvs.begin();
|
|
|
|
i != installedDrvs.end(); ++i)
|
|
|
|
{
|
|
|
|
DrvName drvName(i->second.name);
|
2004-06-28 16:37:05 +03:00
|
|
|
DrvName selector;
|
* Upgrade operation in `nix-env'. For instance, you can say
nix-env -u foo.nix strategoxt
to replace the installed `strategoxt' derivation with the one from `foo.nix', if
the latter has a higher version number. This is a no-op if `strategoxt' is not
installed. Wildcards are also accepted, so
nix-env -u foo.nix '*'
will replace any installed derivation with newer versions from `foo.nix', if
available.
The notion of "version number" is somewhat ad hoc, but should be useful in most
cases, as evidenced by the following unit tests for the version comparator:
TEST("1.0", "2.3", -1);
TEST("2.1", "2.3", -1);
TEST("2.3", "2.3", 0);
TEST("2.5", "2.3", 1);
TEST("3.1", "2.3", 1);
TEST("2.3.1", "2.3", 1);
TEST("2.3.1", "2.3a", 1);
TEST("2.3pre1", "2.3", -1);
TEST("2.3pre3", "2.3pre12", -1);
TEST("2.3a", "2.3c", -1);
TEST("2.3pre1", "2.3c", -1);
TEST("2.3pre1", "2.3q", -1);
(-1 = less, 0 = equal, 1 = greater)
* A new verbosity level `lvlInfo', between `lvlError' and `lvlTalkative'. This is
the default for `nix-env', so without any `-v' flags users should get useful
output, e.g.,
$ nix-env -u foo.nix strategoxt
upgrading `strategoxt-0.9.2' to `strategoxt-0.9.3'
2003-12-22 18:04:00 +02:00
|
|
|
|
|
|
|
/* Do we want to upgrade this derivation? */
|
|
|
|
bool upgrade = false;
|
|
|
|
for (DrvNames::iterator j = selectors.begin();
|
|
|
|
j != selectors.end(); ++j)
|
|
|
|
{
|
2004-06-28 16:37:05 +03:00
|
|
|
if (j->name == "*" || j->name == drvName.name) {
|
* Upgrade operation in `nix-env'. For instance, you can say
nix-env -u foo.nix strategoxt
to replace the installed `strategoxt' derivation with the one from `foo.nix', if
the latter has a higher version number. This is a no-op if `strategoxt' is not
installed. Wildcards are also accepted, so
nix-env -u foo.nix '*'
will replace any installed derivation with newer versions from `foo.nix', if
available.
The notion of "version number" is somewhat ad hoc, but should be useful in most
cases, as evidenced by the following unit tests for the version comparator:
TEST("1.0", "2.3", -1);
TEST("2.1", "2.3", -1);
TEST("2.3", "2.3", 0);
TEST("2.5", "2.3", 1);
TEST("3.1", "2.3", 1);
TEST("2.3.1", "2.3", 1);
TEST("2.3.1", "2.3a", 1);
TEST("2.3pre1", "2.3", -1);
TEST("2.3pre3", "2.3pre12", -1);
TEST("2.3a", "2.3c", -1);
TEST("2.3pre1", "2.3c", -1);
TEST("2.3pre1", "2.3q", -1);
(-1 = less, 0 = equal, 1 = greater)
* A new verbosity level `lvlInfo', between `lvlError' and `lvlTalkative'. This is
the default for `nix-env', so without any `-v' flags users should get useful
output, e.g.,
$ nix-env -u foo.nix strategoxt
upgrading `strategoxt-0.9.2' to `strategoxt-0.9.3'
2003-12-22 18:04:00 +02:00
|
|
|
j->hits++;
|
2004-06-28 16:37:05 +03:00
|
|
|
selector = *j;
|
* Upgrade operation in `nix-env'. For instance, you can say
nix-env -u foo.nix strategoxt
to replace the installed `strategoxt' derivation with the one from `foo.nix', if
the latter has a higher version number. This is a no-op if `strategoxt' is not
installed. Wildcards are also accepted, so
nix-env -u foo.nix '*'
will replace any installed derivation with newer versions from `foo.nix', if
available.
The notion of "version number" is somewhat ad hoc, but should be useful in most
cases, as evidenced by the following unit tests for the version comparator:
TEST("1.0", "2.3", -1);
TEST("2.1", "2.3", -1);
TEST("2.3", "2.3", 0);
TEST("2.5", "2.3", 1);
TEST("3.1", "2.3", 1);
TEST("2.3.1", "2.3", 1);
TEST("2.3.1", "2.3a", 1);
TEST("2.3pre1", "2.3", -1);
TEST("2.3pre3", "2.3pre12", -1);
TEST("2.3a", "2.3c", -1);
TEST("2.3pre1", "2.3c", -1);
TEST("2.3pre1", "2.3q", -1);
(-1 = less, 0 = equal, 1 = greater)
* A new verbosity level `lvlInfo', between `lvlError' and `lvlTalkative'. This is
the default for `nix-env', so without any `-v' flags users should get useful
output, e.g.,
$ nix-env -u foo.nix strategoxt
upgrading `strategoxt-0.9.2' to `strategoxt-0.9.3'
2003-12-22 18:04:00 +02:00
|
|
|
upgrade = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-02-09 13:59:39 +02:00
|
|
|
if (!upgrade) {
|
|
|
|
newDrvs.insert(*i);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
* Upgrade operation in `nix-env'. For instance, you can say
nix-env -u foo.nix strategoxt
to replace the installed `strategoxt' derivation with the one from `foo.nix', if
the latter has a higher version number. This is a no-op if `strategoxt' is not
installed. Wildcards are also accepted, so
nix-env -u foo.nix '*'
will replace any installed derivation with newer versions from `foo.nix', if
available.
The notion of "version number" is somewhat ad hoc, but should be useful in most
cases, as evidenced by the following unit tests for the version comparator:
TEST("1.0", "2.3", -1);
TEST("2.1", "2.3", -1);
TEST("2.3", "2.3", 0);
TEST("2.5", "2.3", 1);
TEST("3.1", "2.3", 1);
TEST("2.3.1", "2.3", 1);
TEST("2.3.1", "2.3a", 1);
TEST("2.3pre1", "2.3", -1);
TEST("2.3pre3", "2.3pre12", -1);
TEST("2.3a", "2.3c", -1);
TEST("2.3pre1", "2.3c", -1);
TEST("2.3pre1", "2.3q", -1);
(-1 = less, 0 = equal, 1 = greater)
* A new verbosity level `lvlInfo', between `lvlError' and `lvlTalkative'. This is
the default for `nix-env', so without any `-v' flags users should get useful
output, e.g.,
$ nix-env -u foo.nix strategoxt
upgrading `strategoxt-0.9.2' to `strategoxt-0.9.3'
2003-12-22 18:04:00 +02:00
|
|
|
/* If yes, find the derivation in the input Nix expression
|
2004-02-09 13:59:39 +02:00
|
|
|
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 == drvName.name) {
|
|
|
|
int d = compareVersions(drvName.version, newName.version);
|
|
|
|
if (upgradeType == utLt && d < 0 ||
|
|
|
|
upgradeType == utLeq && d <= 0 ||
|
|
|
|
upgradeType == utAlways)
|
|
|
|
{
|
2004-06-28 16:37:05 +03:00
|
|
|
if (selector.matches(newName) &&
|
|
|
|
(bestDrv == availDrvs.end() ||
|
|
|
|
compareVersions(
|
|
|
|
bestName.version, newName.version) < 0))
|
2004-02-09 13:59:39 +02:00
|
|
|
{
|
|
|
|
bestDrv = j;
|
|
|
|
bestName = newName;
|
|
|
|
}
|
|
|
|
}
|
2003-12-24 00:13:36 +02:00
|
|
|
}
|
* Upgrade operation in `nix-env'. For instance, you can say
nix-env -u foo.nix strategoxt
to replace the installed `strategoxt' derivation with the one from `foo.nix', if
the latter has a higher version number. This is a no-op if `strategoxt' is not
installed. Wildcards are also accepted, so
nix-env -u foo.nix '*'
will replace any installed derivation with newer versions from `foo.nix', if
available.
The notion of "version number" is somewhat ad hoc, but should be useful in most
cases, as evidenced by the following unit tests for the version comparator:
TEST("1.0", "2.3", -1);
TEST("2.1", "2.3", -1);
TEST("2.3", "2.3", 0);
TEST("2.5", "2.3", 1);
TEST("3.1", "2.3", 1);
TEST("2.3.1", "2.3", 1);
TEST("2.3.1", "2.3a", 1);
TEST("2.3pre1", "2.3", -1);
TEST("2.3pre3", "2.3pre12", -1);
TEST("2.3a", "2.3c", -1);
TEST("2.3pre1", "2.3c", -1);
TEST("2.3pre1", "2.3q", -1);
(-1 = less, 0 = equal, 1 = greater)
* A new verbosity level `lvlInfo', between `lvlError' and `lvlTalkative'. This is
the default for `nix-env', so without any `-v' flags users should get useful
output, e.g.,
$ nix-env -u foo.nix strategoxt
upgrading `strategoxt-0.9.2' to `strategoxt-0.9.3'
2003-12-22 18:04:00 +02:00
|
|
|
}
|
|
|
|
|
2004-02-09 13:59:39 +02:00
|
|
|
if (bestDrv != availDrvs.end() &&
|
|
|
|
i->second.drvPath != bestDrv->second.drvPath)
|
|
|
|
{
|
* Upgrade operation in `nix-env'. For instance, you can say
nix-env -u foo.nix strategoxt
to replace the installed `strategoxt' derivation with the one from `foo.nix', if
the latter has a higher version number. This is a no-op if `strategoxt' is not
installed. Wildcards are also accepted, so
nix-env -u foo.nix '*'
will replace any installed derivation with newer versions from `foo.nix', if
available.
The notion of "version number" is somewhat ad hoc, but should be useful in most
cases, as evidenced by the following unit tests for the version comparator:
TEST("1.0", "2.3", -1);
TEST("2.1", "2.3", -1);
TEST("2.3", "2.3", 0);
TEST("2.5", "2.3", 1);
TEST("3.1", "2.3", 1);
TEST("2.3.1", "2.3", 1);
TEST("2.3.1", "2.3a", 1);
TEST("2.3pre1", "2.3", -1);
TEST("2.3pre3", "2.3pre12", -1);
TEST("2.3a", "2.3c", -1);
TEST("2.3pre1", "2.3c", -1);
TEST("2.3pre1", "2.3q", -1);
(-1 = less, 0 = equal, 1 = greater)
* A new verbosity level `lvlInfo', between `lvlError' and `lvlTalkative'. This is
the default for `nix-env', so without any `-v' flags users should get useful
output, e.g.,
$ nix-env -u foo.nix strategoxt
upgrading `strategoxt-0.9.2' to `strategoxt-0.9.3'
2003-12-22 18:04:00 +02:00
|
|
|
printMsg(lvlInfo,
|
|
|
|
format("upgrading `%1%' to `%2%'")
|
|
|
|
% i->second.name % bestDrv->second.name);
|
2004-02-09 13:59:39 +02:00
|
|
|
newDrvs.insert(*bestDrv);
|
|
|
|
} else newDrvs.insert(*i);
|
* Upgrade operation in `nix-env'. For instance, you can say
nix-env -u foo.nix strategoxt
to replace the installed `strategoxt' derivation with the one from `foo.nix', if
the latter has a higher version number. This is a no-op if `strategoxt' is not
installed. Wildcards are also accepted, so
nix-env -u foo.nix '*'
will replace any installed derivation with newer versions from `foo.nix', if
available.
The notion of "version number" is somewhat ad hoc, but should be useful in most
cases, as evidenced by the following unit tests for the version comparator:
TEST("1.0", "2.3", -1);
TEST("2.1", "2.3", -1);
TEST("2.3", "2.3", 0);
TEST("2.5", "2.3", 1);
TEST("3.1", "2.3", 1);
TEST("2.3.1", "2.3", 1);
TEST("2.3.1", "2.3a", 1);
TEST("2.3pre1", "2.3", -1);
TEST("2.3pre3", "2.3pre12", -1);
TEST("2.3a", "2.3c", -1);
TEST("2.3pre1", "2.3c", -1);
TEST("2.3pre1", "2.3q", -1);
(-1 = less, 0 = equal, 1 = greater)
* A new verbosity level `lvlInfo', between `lvlError' and `lvlTalkative'. This is
the default for `nix-env', so without any `-v' flags users should get useful
output, e.g.,
$ nix-env -u foo.nix strategoxt
upgrading `strategoxt-0.9.2' to `strategoxt-0.9.3'
2003-12-22 18:04:00 +02:00
|
|
|
}
|
|
|
|
|
2004-02-09 13:59:39 +02:00
|
|
|
if (dryRun) return;
|
|
|
|
|
2004-02-06 12:30:20 +02:00
|
|
|
createUserEnv(state, newDrvs, profile);
|
* Upgrade operation in `nix-env'. For instance, you can say
nix-env -u foo.nix strategoxt
to replace the installed `strategoxt' derivation with the one from `foo.nix', if
the latter has a higher version number. This is a no-op if `strategoxt' is not
installed. Wildcards are also accepted, so
nix-env -u foo.nix '*'
will replace any installed derivation with newer versions from `foo.nix', if
available.
The notion of "version number" is somewhat ad hoc, but should be useful in most
cases, as evidenced by the following unit tests for the version comparator:
TEST("1.0", "2.3", -1);
TEST("2.1", "2.3", -1);
TEST("2.3", "2.3", 0);
TEST("2.5", "2.3", 1);
TEST("3.1", "2.3", 1);
TEST("2.3.1", "2.3", 1);
TEST("2.3.1", "2.3a", 1);
TEST("2.3pre1", "2.3", -1);
TEST("2.3pre3", "2.3pre12", -1);
TEST("2.3a", "2.3c", -1);
TEST("2.3pre1", "2.3c", -1);
TEST("2.3pre1", "2.3q", -1);
(-1 = less, 0 = equal, 1 = greater)
* A new verbosity level `lvlInfo', between `lvlError' and `lvlTalkative'. This is
the default for `nix-env', so without any `-v' flags users should get useful
output, e.g.,
$ nix-env -u foo.nix strategoxt
upgrading `strategoxt-0.9.2' to `strategoxt-0.9.3'
2003-12-22 18:04:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-12-22 01:58:56 +02:00
|
|
|
static void opUpgrade(Globals & globals,
|
|
|
|
Strings opFlags, Strings opArgs)
|
|
|
|
{
|
2004-02-09 13:59:39 +02:00
|
|
|
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);
|
2003-12-22 01:58:56 +02:00
|
|
|
|
2004-01-05 18:26:43 +02:00
|
|
|
DrvNames drvNames = drvNamesFromArgs(opArgs);
|
* Upgrade operation in `nix-env'. For instance, you can say
nix-env -u foo.nix strategoxt
to replace the installed `strategoxt' derivation with the one from `foo.nix', if
the latter has a higher version number. This is a no-op if `strategoxt' is not
installed. Wildcards are also accepted, so
nix-env -u foo.nix '*'
will replace any installed derivation with newer versions from `foo.nix', if
available.
The notion of "version number" is somewhat ad hoc, but should be useful in most
cases, as evidenced by the following unit tests for the version comparator:
TEST("1.0", "2.3", -1);
TEST("2.1", "2.3", -1);
TEST("2.3", "2.3", 0);
TEST("2.5", "2.3", 1);
TEST("3.1", "2.3", 1);
TEST("2.3.1", "2.3", 1);
TEST("2.3.1", "2.3a", 1);
TEST("2.3pre1", "2.3", -1);
TEST("2.3pre3", "2.3pre12", -1);
TEST("2.3a", "2.3c", -1);
TEST("2.3pre1", "2.3c", -1);
TEST("2.3pre1", "2.3q", -1);
(-1 = less, 0 = equal, 1 = greater)
* A new verbosity level `lvlInfo', between `lvlError' and `lvlTalkative'. This is
the default for `nix-env', so without any `-v' flags users should get useful
output, e.g.,
$ nix-env -u foo.nix strategoxt
upgrading `strategoxt-0.9.2' to `strategoxt-0.9.3'
2003-12-22 18:04:00 +02:00
|
|
|
|
2004-01-05 18:26:43 +02:00
|
|
|
upgradeDerivations(globals.state, globals.nixExprPath,
|
2004-07-01 16:56:56 +03:00
|
|
|
drvNames, globals.profile, upgradeType, globals.dryRun,
|
|
|
|
globals.systemFilter);
|
2003-11-19 19:27:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
* Upgrade operation in `nix-env'. For instance, you can say
nix-env -u foo.nix strategoxt
to replace the installed `strategoxt' derivation with the one from `foo.nix', if
the latter has a higher version number. This is a no-op if `strategoxt' is not
installed. Wildcards are also accepted, so
nix-env -u foo.nix '*'
will replace any installed derivation with newer versions from `foo.nix', if
available.
The notion of "version number" is somewhat ad hoc, but should be useful in most
cases, as evidenced by the following unit tests for the version comparator:
TEST("1.0", "2.3", -1);
TEST("2.1", "2.3", -1);
TEST("2.3", "2.3", 0);
TEST("2.5", "2.3", 1);
TEST("3.1", "2.3", 1);
TEST("2.3.1", "2.3", 1);
TEST("2.3.1", "2.3a", 1);
TEST("2.3pre1", "2.3", -1);
TEST("2.3pre3", "2.3pre12", -1);
TEST("2.3a", "2.3c", -1);
TEST("2.3pre1", "2.3c", -1);
TEST("2.3pre1", "2.3q", -1);
(-1 = less, 0 = equal, 1 = greater)
* A new verbosity level `lvlInfo', between `lvlError' and `lvlTalkative'. This is
the default for `nix-env', so without any `-v' flags users should get useful
output, e.g.,
$ nix-env -u foo.nix strategoxt
upgrading `strategoxt-0.9.2' to `strategoxt-0.9.3'
2003-12-22 18:04:00 +02:00
|
|
|
static void uninstallDerivations(EvalState & state, DrvNames & selectors,
|
2004-02-09 13:59:39 +02:00
|
|
|
Path & profile, bool dryRun)
|
2003-11-20 15:48:48 +02:00
|
|
|
{
|
|
|
|
DrvInfos installedDrvs;
|
2004-02-06 12:30:20 +02:00
|
|
|
queryInstalled(state, installedDrvs, profile);
|
2003-11-20 15:48:48 +02:00
|
|
|
|
2003-12-22 01:58:56 +02:00
|
|
|
for (DrvInfos::iterator i = installedDrvs.begin();
|
|
|
|
i != installedDrvs.end(); ++i)
|
2003-11-20 15:48:48 +02:00
|
|
|
{
|
2003-12-22 01:58:56 +02:00
|
|
|
DrvName drvName(i->second.name);
|
|
|
|
for (DrvNames::iterator j = selectors.begin();
|
|
|
|
j != selectors.end(); ++j)
|
* Upgrade operation in `nix-env'. For instance, you can say
nix-env -u foo.nix strategoxt
to replace the installed `strategoxt' derivation with the one from `foo.nix', if
the latter has a higher version number. This is a no-op if `strategoxt' is not
installed. Wildcards are also accepted, so
nix-env -u foo.nix '*'
will replace any installed derivation with newer versions from `foo.nix', if
available.
The notion of "version number" is somewhat ad hoc, but should be useful in most
cases, as evidenced by the following unit tests for the version comparator:
TEST("1.0", "2.3", -1);
TEST("2.1", "2.3", -1);
TEST("2.3", "2.3", 0);
TEST("2.5", "2.3", 1);
TEST("3.1", "2.3", 1);
TEST("2.3.1", "2.3", 1);
TEST("2.3.1", "2.3a", 1);
TEST("2.3pre1", "2.3", -1);
TEST("2.3pre3", "2.3pre12", -1);
TEST("2.3a", "2.3c", -1);
TEST("2.3pre1", "2.3c", -1);
TEST("2.3pre1", "2.3q", -1);
(-1 = less, 0 = equal, 1 = greater)
* A new verbosity level `lvlInfo', between `lvlError' and `lvlTalkative'. This is
the default for `nix-env', so without any `-v' flags users should get useful
output, e.g.,
$ nix-env -u foo.nix strategoxt
upgrading `strategoxt-0.9.2' to `strategoxt-0.9.3'
2003-12-22 18:04:00 +02:00
|
|
|
if (j->matches(drvName)) {
|
|
|
|
printMsg(lvlInfo,
|
|
|
|
format("uninstalling `%1%'") % i->second.name);
|
2003-12-22 01:58:56 +02:00
|
|
|
installedDrvs.erase(i);
|
* Upgrade operation in `nix-env'. For instance, you can say
nix-env -u foo.nix strategoxt
to replace the installed `strategoxt' derivation with the one from `foo.nix', if
the latter has a higher version number. This is a no-op if `strategoxt' is not
installed. Wildcards are also accepted, so
nix-env -u foo.nix '*'
will replace any installed derivation with newer versions from `foo.nix', if
available.
The notion of "version number" is somewhat ad hoc, but should be useful in most
cases, as evidenced by the following unit tests for the version comparator:
TEST("1.0", "2.3", -1);
TEST("2.1", "2.3", -1);
TEST("2.3", "2.3", 0);
TEST("2.5", "2.3", 1);
TEST("3.1", "2.3", 1);
TEST("2.3.1", "2.3", 1);
TEST("2.3.1", "2.3a", 1);
TEST("2.3pre1", "2.3", -1);
TEST("2.3pre3", "2.3pre12", -1);
TEST("2.3a", "2.3c", -1);
TEST("2.3pre1", "2.3c", -1);
TEST("2.3pre1", "2.3q", -1);
(-1 = less, 0 = equal, 1 = greater)
* A new verbosity level `lvlInfo', between `lvlError' and `lvlTalkative'. This is
the default for `nix-env', so without any `-v' flags users should get useful
output, e.g.,
$ nix-env -u foo.nix strategoxt
upgrading `strategoxt-0.9.2' to `strategoxt-0.9.3'
2003-12-22 18:04:00 +02:00
|
|
|
}
|
2003-11-20 15:48:48 +02:00
|
|
|
}
|
|
|
|
|
2004-02-09 13:59:39 +02:00
|
|
|
if (dryRun) return;
|
|
|
|
|
2004-02-06 12:30:20 +02:00
|
|
|
createUserEnv(state, installedDrvs, profile);
|
2003-11-20 15:48:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-12-22 00:34:41 +02:00
|
|
|
static void opUninstall(Globals & globals,
|
2003-11-20 15:48:48 +02:00
|
|
|
Strings opFlags, Strings opArgs)
|
|
|
|
{
|
2003-12-22 00:34:41 +02:00
|
|
|
if (opFlags.size() > 0)
|
|
|
|
throw UsageError(format("unknown flags `%1%'") % opFlags.front());
|
|
|
|
|
2003-12-22 01:58:56 +02:00
|
|
|
DrvNames drvNames = drvNamesFromArgs(opArgs);
|
|
|
|
|
2004-02-09 13:59:39 +02:00
|
|
|
uninstallDerivations(globals.state, drvNames,
|
|
|
|
globals.profile, globals.dryRun);
|
2003-11-20 15:48:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-10-14 18:09:55 +03:00
|
|
|
static bool cmpChars(char a, char b)
|
|
|
|
{
|
|
|
|
return toupper(a) < toupper(b);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-02-02 12:51:54 +02:00
|
|
|
static bool cmpDrvByName(const DrvInfo & a, const DrvInfo & b)
|
|
|
|
{
|
2004-10-14 18:09:55 +03:00
|
|
|
return lexicographical_compare(
|
|
|
|
a.name.begin(), a.name.end(),
|
|
|
|
b.name.begin(), b.name.end(), cmpChars);
|
2004-02-02 12:51:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-07-01 16:35:10 +03:00
|
|
|
typedef list<Strings> Table;
|
|
|
|
|
|
|
|
|
|
|
|
void printTable(Table & table)
|
|
|
|
{
|
2004-10-29 14:22:49 +03:00
|
|
|
unsigned int nrColumns = table.size() > 0 ? table.front().size() : 0;
|
2004-07-01 16:35:10 +03:00
|
|
|
|
2004-10-29 14:22:49 +03:00
|
|
|
vector<unsigned int> widths;
|
2004-07-01 16:35:10 +03:00
|
|
|
widths.resize(nrColumns);
|
|
|
|
|
|
|
|
for (Table::iterator i = table.begin(); i != table.end(); ++i) {
|
|
|
|
assert(i->size() == nrColumns);
|
2004-10-29 14:22:49 +03:00
|
|
|
Strings::iterator j;
|
|
|
|
unsigned int column;
|
2004-07-01 16:35:10 +03:00
|
|
|
for (j = i->begin(), column = 0; j != i->end(); ++j, ++column)
|
|
|
|
if (j->size() > widths[column]) widths[column] = j->size();
|
|
|
|
}
|
|
|
|
|
|
|
|
for (Table::iterator i = table.begin(); i != table.end(); ++i) {
|
2004-10-29 14:22:49 +03:00
|
|
|
Strings::iterator j;
|
|
|
|
unsigned int column;
|
2004-07-01 16:35:10 +03:00
|
|
|
for (j = i->begin(), column = 0; j != i->end(); ++j, ++column)
|
|
|
|
{
|
|
|
|
cout << *j;
|
|
|
|
if (column < nrColumns - 1)
|
|
|
|
cout << string(widths[column] - j->size() + 2, ' ');
|
|
|
|
}
|
|
|
|
cout << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-12-22 00:34:41 +02:00
|
|
|
static void opQuery(Globals & globals,
|
2003-11-19 19:27:16 +02:00
|
|
|
Strings opFlags, Strings opArgs)
|
|
|
|
{
|
2004-07-01 16:13:37 +03:00
|
|
|
bool printStatus = false;
|
|
|
|
bool printName = true;
|
|
|
|
bool printSystem = false;
|
|
|
|
bool printDrvPath = false;
|
|
|
|
|
2003-11-19 19:27:16 +02:00
|
|
|
enum { sInstalled, sAvailable } source = sInstalled;
|
|
|
|
|
2004-10-27 13:24:44 +03:00
|
|
|
readOnlyMode = true; /* makes evaluation a bit faster */
|
|
|
|
|
2003-11-19 19:27:16 +02:00
|
|
|
for (Strings::iterator i = opFlags.begin();
|
|
|
|
i != opFlags.end(); ++i)
|
2004-07-01 16:13:37 +03:00
|
|
|
if (*i == "--status" || *i == "-s") printStatus = true;
|
|
|
|
else if (*i == "--no-name") printName = false;
|
|
|
|
else if (*i == "--system") printSystem = true;
|
|
|
|
else if (*i == "--expr") printDrvPath = true;
|
2003-11-19 19:27:16 +02:00
|
|
|
else if (*i == "--installed") source = sInstalled;
|
2004-01-05 18:26:43 +02:00
|
|
|
else if (*i == "--available" || *i == "-a") source = sAvailable;
|
2003-11-19 19:27:16 +02:00
|
|
|
else throw UsageError(format("unknown flag `%1%'") % *i);
|
|
|
|
|
|
|
|
/* Obtain derivation information from the specified source. */
|
|
|
|
DrvInfos drvs;
|
|
|
|
|
|
|
|
switch (source) {
|
|
|
|
|
|
|
|
case sInstalled:
|
2004-02-06 12:30:20 +02:00
|
|
|
queryInstalled(globals.state, drvs, globals.profile);
|
2003-11-19 19:27:16 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case sAvailable: {
|
2004-07-01 16:56:56 +03:00
|
|
|
loadDerivations(globals.state, globals.nixExprPath,
|
|
|
|
drvs, globals.systemFilter);
|
2003-11-19 19:27:16 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
default: abort();
|
|
|
|
}
|
|
|
|
|
2003-11-19 23:32:03 +02:00
|
|
|
if (opArgs.size() != 0) throw UsageError("no arguments expected");
|
2004-02-02 12:51:54 +02:00
|
|
|
|
|
|
|
/* Sort them by name. */
|
|
|
|
DrvInfoList drvs2;
|
|
|
|
for (DrvInfos::iterator i = drvs.begin(); i != drvs.end(); ++i)
|
|
|
|
drvs2.push_back(i->second);
|
|
|
|
sort(drvs2.begin(), drvs2.end(), cmpDrvByName);
|
2003-11-19 19:27:16 +02:00
|
|
|
|
2004-07-01 16:13:37 +03:00
|
|
|
/* We only need to know the installed paths when we are querying
|
|
|
|
the status of the derivation. */
|
|
|
|
PathSet installedPaths; /* output paths of installed drvs */
|
|
|
|
|
|
|
|
if (printStatus) {
|
|
|
|
DrvInfos installed;
|
|
|
|
queryInstalled(globals.state, installed, globals.profile);
|
2003-11-19 23:32:03 +02:00
|
|
|
|
2004-07-01 16:13:37 +03:00
|
|
|
for (DrvInfos::iterator i = installed.begin();
|
|
|
|
i != installed.end(); ++i)
|
|
|
|
installedPaths.insert(i->second.outPath);
|
|
|
|
}
|
2004-01-15 16:43:00 +02:00
|
|
|
|
2004-07-01 16:13:37 +03:00
|
|
|
/* Print the desired columns. */
|
2004-07-01 16:35:10 +03:00
|
|
|
Table table;
|
|
|
|
|
2004-07-01 16:13:37 +03:00
|
|
|
for (DrvInfoList::iterator i = drvs2.begin(); i != drvs2.end(); ++i) {
|
|
|
|
|
|
|
|
Strings columns;
|
|
|
|
|
|
|
|
if (printStatus) {
|
|
|
|
Substitutes subs = querySubstitutes(i->drvPath);
|
|
|
|
columns.push_back(
|
|
|
|
(string) (installedPaths.find(i->outPath)
|
|
|
|
!= installedPaths.end() ? "I" : "-")
|
|
|
|
+ (isValidPath(i->outPath) ? "P" : "-")
|
|
|
|
+ (subs.size() > 0 ? "S" : "-"));
|
2003-11-19 23:32:03 +02:00
|
|
|
}
|
2004-07-01 16:13:37 +03:00
|
|
|
|
|
|
|
if (printName) columns.push_back(i->name);
|
|
|
|
|
|
|
|
if (printSystem) columns.push_back(i->system);
|
|
|
|
|
|
|
|
if (printDrvPath) columns.push_back(i->drvPath);
|
2004-07-01 16:35:10 +03:00
|
|
|
|
|
|
|
table.push_back(columns);
|
2003-11-19 19:27:16 +02:00
|
|
|
}
|
2004-07-01 16:35:10 +03:00
|
|
|
|
|
|
|
printTable(table);
|
2003-11-19 19:27:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-01-05 13:18:59 +02:00
|
|
|
static void opSwitchProfile(Globals & globals,
|
|
|
|
Strings opFlags, Strings opArgs)
|
|
|
|
{
|
|
|
|
if (opFlags.size() > 0)
|
2004-02-06 18:03:27 +02:00
|
|
|
throw UsageError(format("unknown flag `%1%'") % opFlags.front());
|
2004-02-06 12:59:06 +02:00
|
|
|
if (opArgs.size() != 1)
|
2004-02-06 18:03:27 +02:00
|
|
|
throw UsageError(format("exactly one argument expected"));
|
2004-01-05 13:18:59 +02:00
|
|
|
|
2004-02-06 12:59:06 +02:00
|
|
|
Path profile = opArgs.front();
|
|
|
|
Path profileLink = getHomeDir() + "/.nix-profile";
|
2004-01-05 13:18:59 +02:00
|
|
|
|
2004-09-10 00:12:53 +03:00
|
|
|
SwitchToOriginalUser sw;
|
2004-02-06 12:30:20 +02:00
|
|
|
switchLink(profileLink, profile);
|
2004-01-05 18:26:43 +02:00
|
|
|
}
|
2004-01-05 13:18:59 +02:00
|
|
|
|
2004-01-05 18:26:43 +02:00
|
|
|
|
2004-02-08 16:07:43 +02:00
|
|
|
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);
|
|
|
|
|
2004-02-10 15:42:58 +02:00
|
|
|
printMsg(lvlInfo, format("switching from generation %1% to %2%")
|
|
|
|
% curGen % dst.number);
|
|
|
|
|
|
|
|
if (globals.dryRun) return;
|
|
|
|
|
2004-02-08 16:07:43 +02:00
|
|
|
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"));
|
|
|
|
|
|
|
|
int dstGen;
|
2004-09-10 16:32:08 +03:00
|
|
|
if (!string2Int(opArgs.front(), dstGen))
|
2004-02-08 16:07:43 +02:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-02-06 18:03:27 +02:00
|
|
|
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"));
|
|
|
|
|
2004-02-06 18:16:55 +02:00
|
|
|
int curGen;
|
|
|
|
Generations gens = findGenerations(globals.profile, curGen);
|
2004-02-06 18:03:27 +02:00
|
|
|
|
|
|
|
for (Generations::iterator i = gens.begin(); i != gens.end(); ++i) {
|
|
|
|
tm t;
|
|
|
|
if (!localtime_r(&i->creationTime, &t)) throw Error("cannot convert time");
|
2004-02-06 18:16:55 +02:00
|
|
|
cout << format("%|4| %|4|-%|02|-%|02| %|02|:%|02|:%|02| %||\n")
|
2004-02-06 18:03:27 +02:00
|
|
|
% i->number
|
|
|
|
% (t.tm_year + 1900) % (t.tm_mon + 1) % t.tm_mday
|
2004-02-06 18:16:55 +02:00
|
|
|
% t.tm_hour % t.tm_min % t.tm_sec
|
|
|
|
% (i->number == curGen ? "(current)" : "");
|
2004-02-06 18:03:27 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-09-10 16:32:08 +03:00
|
|
|
static void deleteGeneration2(const Path & profile, unsigned int gen)
|
|
|
|
{
|
|
|
|
printMsg(lvlInfo, format("removing generation %1%") % gen);
|
|
|
|
deleteGeneration(profile, gen);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void opDeleteGenerations(Globals & globals,
|
|
|
|
Strings opFlags, Strings opArgs)
|
|
|
|
{
|
|
|
|
if (opFlags.size() > 0)
|
|
|
|
throw UsageError(format("unknown flag `%1%'") % opFlags.front());
|
|
|
|
|
|
|
|
int curGen;
|
|
|
|
Generations gens = findGenerations(globals.profile, curGen);
|
|
|
|
|
|
|
|
for (Strings::iterator i = opArgs.begin(); i != opArgs.end(); ++i) {
|
|
|
|
|
|
|
|
if (*i == "old") {
|
|
|
|
for (Generations::iterator j = gens.begin(); j != gens.end(); ++j)
|
|
|
|
if (j->number != curGen)
|
|
|
|
deleteGeneration2(globals.profile, j->number);
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
int n;
|
|
|
|
if (!string2Int(*i, n) || n < 0)
|
|
|
|
throw UsageError(format("invalid generation specifier `%1%'") % *i);
|
|
|
|
bool found = false;
|
|
|
|
for (Generations::iterator j = gens.begin(); j != gens.end(); ++j) {
|
|
|
|
if (j->number == n) {
|
|
|
|
deleteGeneration2(globals.profile, j->number);
|
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!found)
|
|
|
|
printMsg(lvlError, format("generation %1% does not exist") % n);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-01-05 18:26:43 +02:00
|
|
|
static void opDefaultExpr(Globals & globals,
|
|
|
|
Strings opFlags, Strings opArgs)
|
|
|
|
{
|
|
|
|
if (opFlags.size() > 0)
|
|
|
|
throw UsageError(format("unknown flags `%1%'") % opFlags.front());
|
|
|
|
if (opArgs.size() != 1)
|
2004-02-06 18:03:27 +02:00
|
|
|
throw UsageError(format("exactly one argument expected"));
|
2004-01-05 18:26:43 +02:00
|
|
|
|
2004-01-20 22:36:58 +02:00
|
|
|
Path defNixExpr = absPath(opArgs.front());
|
2004-01-05 18:26:43 +02:00
|
|
|
Path defNixExprLink = getDefNixExprPath();
|
2004-01-05 13:18:59 +02:00
|
|
|
|
2004-09-10 00:12:53 +03:00
|
|
|
SwitchToOriginalUser sw;
|
2004-01-05 18:26:43 +02:00
|
|
|
switchLink(defNixExprLink, defNixExpr);
|
2004-01-05 13:18:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-11-19 19:27:16 +02:00
|
|
|
void run(Strings args)
|
|
|
|
{
|
|
|
|
Strings opFlags, opArgs;
|
|
|
|
Operation op = 0;
|
2003-12-22 00:34:41 +02:00
|
|
|
|
|
|
|
Globals globals;
|
2004-01-05 18:26:43 +02:00
|
|
|
globals.nixExprPath = getDefNixExprPath();
|
2004-02-09 13:59:39 +02:00
|
|
|
globals.dryRun = false;
|
2004-06-28 17:40:26 +03:00
|
|
|
globals.preserveInstalled = false;
|
2004-07-01 16:56:56 +03:00
|
|
|
globals.systemFilter = thisSystem;
|
2003-11-19 19:27:16 +02:00
|
|
|
|
|
|
|
for (Strings::iterator i = args.begin(); i != args.end(); ++i) {
|
|
|
|
string arg = *i;
|
|
|
|
|
|
|
|
Operation oldOp = op;
|
|
|
|
|
|
|
|
if (arg == "--install" || arg == "-i")
|
|
|
|
op = opInstall;
|
2003-12-22 00:34:41 +02:00
|
|
|
else if (arg == "--uninstall" || arg == "-e")
|
2003-11-20 15:48:48 +02:00
|
|
|
op = opUninstall;
|
2003-12-22 01:58:56 +02:00
|
|
|
else if (arg == "--upgrade" || arg == "-u")
|
|
|
|
op = opUpgrade;
|
2003-11-20 15:48:48 +02:00
|
|
|
else if (arg == "--query" || arg == "-q")
|
2003-11-19 19:27:16 +02:00
|
|
|
op = opQuery;
|
2004-01-05 18:26:43 +02:00
|
|
|
else if (arg == "--import" || arg == "-I") /* !!! bad name */
|
|
|
|
op = opDefaultExpr;
|
2004-02-06 12:30:20 +02:00
|
|
|
else if (arg == "--profile" || arg == "-p") {
|
2003-12-22 00:34:41 +02:00
|
|
|
++i;
|
|
|
|
if (i == args.end()) throw UsageError(
|
|
|
|
format("`%1%' requires an argument") % arg);
|
2004-02-06 12:30:20 +02:00
|
|
|
globals.profile = absPath(*i);
|
2003-12-22 00:34:41 +02:00
|
|
|
}
|
2004-01-05 18:26:43 +02:00
|
|
|
else if (arg == "--file" || arg == "-f") {
|
|
|
|
++i;
|
|
|
|
if (i == args.end()) throw UsageError(
|
|
|
|
format("`%1%' requires an argument") % arg);
|
|
|
|
globals.nixExprPath = absPath(*i);
|
|
|
|
}
|
2004-02-06 12:30:20 +02:00
|
|
|
else if (arg == "--switch-profile" || arg == "-S")
|
2004-01-05 13:18:59 +02:00
|
|
|
op = opSwitchProfile;
|
2004-02-08 16:07:43 +02:00
|
|
|
else if (arg == "--switch-generation" || arg == "-G")
|
|
|
|
op = opSwitchGeneration;
|
|
|
|
else if (arg == "--rollback")
|
|
|
|
op = opRollback;
|
2004-02-06 18:03:27 +02:00
|
|
|
else if (arg == "--list-generations")
|
|
|
|
op = opListGenerations;
|
2004-09-10 16:32:08 +03:00
|
|
|
else if (arg == "--delete-generations")
|
|
|
|
op = opDeleteGenerations;
|
2004-02-09 13:59:39 +02:00
|
|
|
else if (arg == "--dry-run") {
|
|
|
|
printMsg(lvlInfo, "(dry run; not doing anything)");
|
|
|
|
globals.dryRun = true;
|
|
|
|
}
|
2004-06-28 17:40:26 +03:00
|
|
|
else if (arg == "--preserve-installed" || arg == "-P")
|
|
|
|
globals.preserveInstalled = true;
|
2004-07-01 16:56:56 +03:00
|
|
|
else if (arg == "--system-filter") {
|
|
|
|
++i;
|
|
|
|
if (i == args.end()) throw UsageError(
|
|
|
|
format("`%1%' requires an argument") % arg);
|
|
|
|
globals.systemFilter = *i;
|
|
|
|
}
|
2003-12-02 12:21:40 +02:00
|
|
|
else if (arg[0] == '-')
|
|
|
|
opFlags.push_back(arg);
|
2003-11-19 19:27:16 +02:00
|
|
|
else
|
|
|
|
opArgs.push_back(arg);
|
|
|
|
|
|
|
|
if (oldOp && oldOp != op)
|
|
|
|
throw UsageError("only one operation may be specified");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!op) throw UsageError("no operation specified");
|
|
|
|
|
2004-02-06 12:59:06 +02:00
|
|
|
if (globals.profile == "") {
|
2004-09-10 00:12:53 +03:00
|
|
|
SwitchToOriginalUser sw;
|
2004-02-06 12:59:06 +02:00
|
|
|
Path profileLink = getHomeDir() + "/.nix-profile";
|
|
|
|
globals.profile = pathExists(profileLink)
|
|
|
|
? absPath(readLink(profileLink), dirOf(profileLink))
|
|
|
|
: canonPath(nixStateDir + "/profiles/default");
|
|
|
|
}
|
|
|
|
|
2003-11-19 19:27:16 +02:00
|
|
|
openDB();
|
|
|
|
|
2003-12-22 00:34:41 +02:00
|
|
|
op(globals, opFlags, opArgs);
|
2003-11-19 19:27:16 +02:00
|
|
|
|
2003-12-22 00:34:41 +02:00
|
|
|
printEvalStats(globals.state);
|
2003-11-19 19:27:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
string programId = "nix-env";
|