diff --git a/doc/manual/nix-env.xml b/doc/manual/nix-env.xml index 8a496da259..4772c2b110 100644 --- a/doc/manual/nix-env.xml +++ b/doc/manual/nix-env.xml @@ -183,6 +183,10 @@ + + + + drvnames @@ -197,6 +201,35 @@ in the active Nix expression are added. + + Currently installed derivations with a name equal to the name + of a derivation being added are removed unless the option + is specified. + + + + + + Flags + + + + + / + + + Do not remove derivations with a name matching one of + the derivations being installed. Usually, trying to + have two versions of the same package installed in the + same generation of a profile will lead to an error in + building the generation, due to file name clashes + between the two versions. However, this is not the case + for all packages. + + + + + @@ -204,7 +237,11 @@ $ nix-env --install gcc-3.3.2 (install specific version) +installing `gcc-3.3.2' +uninstalling `gcc-3.1' (previously installed version is removed) + $ nix-env --install gcc (just pick any version) + $ nix-env -f ~/foo.nix -i '*' (install everything in foo.nix) diff --git a/src/nix-env/main.cc b/src/nix-env/main.cc index 1f16e72ae0..09604a2d0d 100644 --- a/src/nix-env/main.cc +++ b/src/nix-env/main.cc @@ -17,6 +17,7 @@ struct Globals Path nixExprPath; EvalState state; bool dryRun; + bool preserveInstalled; }; @@ -225,7 +226,7 @@ void createUserEnv(EvalState & state, const DrvInfos & drvs, static void installDerivations(EvalState & state, Path nePath, DrvNames & selectors, const Path & profile, - bool dryRun) + bool dryRun, bool preserveInstalled) { debug(format("installing derivations from `%1%'") % nePath); @@ -235,6 +236,7 @@ static void installDerivations(EvalState & state, /* Filter out the ones we're not interested in. */ DrvInfos selectedDrvs; + StringSet selectedNames; for (DrvInfos::iterator i = availDrvs.begin(); i != availDrvs.end(); ++i) { @@ -247,6 +249,7 @@ static void installDerivations(EvalState & state, format("installing `%1%'") % i->second.name); j->hits++; selectedDrvs.insert(*i); + selectedNames.insert(drvName.name); } } } @@ -261,7 +264,18 @@ static void installDerivations(EvalState & state, /* Add in the already installed derivations. */ DrvInfos installedDrvs; queryInstalled(state, installedDrvs, profile); - selectedDrvs.insert(installedDrvs.begin(), installedDrvs.end()); + + 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); + } if (dryRun) return; @@ -278,7 +292,8 @@ static void opInstall(Globals & globals, DrvNames drvNames = drvNamesFromArgs(opArgs); installDerivations(globals.state, globals.nixExprPath, - drvNames, globals.profile, globals.dryRun); + drvNames, globals.profile, globals.dryRun, + globals.preserveInstalled); } @@ -641,6 +656,7 @@ void run(Strings args) Globals globals; globals.nixExprPath = getDefNixExprPath(); globals.dryRun = false; + globals.preserveInstalled = false; for (Strings::iterator i = args.begin(); i != args.end(); ++i) { string arg = *i; @@ -681,6 +697,8 @@ void run(Strings args) printMsg(lvlInfo, "(dry run; not doing anything)"); globals.dryRun = true; } + else if (arg == "--preserve-installed" || arg == "-P") + globals.preserveInstalled = true; else if (arg[0] == '-') opFlags.push_back(arg); else