* Global configuration option `env-keep-derivations' to store pointer

to derivations in user environments.  Nice for developers (since it
  prevents build-time-only dependencies from being GC'ed, in
  conjunction with `gc-keep-outputs').  Turned off by default.
This commit is contained in:
Eelco Dolstra 2005-02-14 13:07:09 +00:00
parent b0aba6ec2a
commit 6a8ef36fe6
5 changed files with 72 additions and 35 deletions

View File

@ -7,7 +7,7 @@
# #
# In general, outputs must be registered as roots separately. # In general, outputs must be registered as roots separately.
# However, even if the output of a derivation is registered as a root, # However, even if the output of a derivation is registered as a root,
# the collector will still delete store paths that are used only a # the collector will still delete store paths that are used only at
# build time (e.g., the C compiler, or source tarballs downloaded from # build time (e.g., the C compiler, or source tarballs downloaded from
# the network). To prevent it from doing so, set this option to # the network). To prevent it from doing so, set this option to
# `true'. # `true'.
@ -28,3 +28,22 @@ gc-keep-outputs = false
# turned on). # turned on).
gc-keep-derivations = true gc-keep-derivations = true
### Option `env-keep-derivations'
#
# If `false' (default), derivations are not stored in Nix user
# environments. That is, the derivation any build-time-only
# dependencies may be garbage-collected.
#
# If `true', when you add a Nix derivation to a user environment, the
# path of the derivation is stored in the user environment. Thus, the
# derivation will not be garbage-collected until the user environment
# generation is deleted (`nix-env --delete-generations'). To prevent
# build-time-only dependencies from being collected, you should also
# turn on `gc-keep-outputs'.
#
# The difference between this option and `gc-keep-derivations' is that
# this one is `sticky': it applies to any user environment created
# while this option was enabled, while `gc-keep-derivations' only
# applies at the moment the garbage collector is run.
env-keep-derivations = false

View File

@ -306,7 +306,7 @@ void collectGarbage(GCAction action, PathSet & result)
{ {
result.clear(); result.clear();
string gcKeepOutputs = querySetting("gc-keep-outputs", "false"); bool gcKeepOutputs = queryBoolSetting("gc-keep-outputs", false);
/* Acquire the global GC root. This prevents /* Acquire the global GC root. This prevents
a) New roots from being added. a) New roots from being added.
@ -330,7 +330,7 @@ void collectGarbage(GCAction action, PathSet & result)
for (PathSet::const_iterator i = roots.begin(); i != roots.end(); ++i) for (PathSet::const_iterator i = roots.begin(); i != roots.end(); ++i)
computeFSClosure(canonPath(*i), livePaths); computeFSClosure(canonPath(*i), livePaths);
if (gcKeepOutputs == "true") { if (gcKeepOutputs) {
/* Hmz, identical to storePathRequisites in nix-store. */ /* Hmz, identical to storePathRequisites in nix-store. */
for (PathSet::iterator i = livePaths.begin(); for (PathSet::iterator i = livePaths.begin();
i != livePaths.end(); ++i) i != livePaths.end(); ++i)

View File

@ -52,7 +52,7 @@ static void readSettings()
string name, sep, value; string name, sep, value;
is >> name >> sep >> value; is >> name >> sep >> value;
if (sep != "=" || !is) if (sep != "=" || !is)
throw Error(format("illegal configuration line `%1%'") % line); throw Error(format("illegal configuration line `%1%' in `%2%'") % line % settingsFile);
settings[name] = value; settings[name] = value;
}; };
@ -67,3 +67,13 @@ string querySetting(const string & name, const string & def)
map<string, string>::iterator i = settings.find(name); map<string, string>::iterator i = settings.find(name);
return i == settings.end() ? def : i->second; return i == settings.end() ? def : i->second;
} }
bool queryBoolSetting(const string & name, bool def)
{
string value = querySetting(name, def ? "true" : "false");
if (value == "true") return true;
else if (value == "false") return false;
else throw Error(format("configuration option `%1%' should be either `true' or `false', not `%2%'")
% name % value);
}

View File

@ -55,5 +55,7 @@ extern bool readOnlyMode;
string querySetting(const string & name, const string & def); string querySetting(const string & name, const string & def);
bool queryBoolSetting(const string & name, bool def);
#endif /* !__GLOBALS_H */ #endif /* !__GLOBALS_H */

View File

@ -37,6 +37,7 @@ struct Globals
EvalState state; EvalState state;
bool dryRun; bool dryRun;
bool preserveInstalled; bool preserveInstalled;
bool keepDerivations;
}; };
@ -203,7 +204,7 @@ void queryInstalled(EvalState & state, DrvInfos & drvs,
void createUserEnv(EvalState & state, const DrvInfos & drvs, void createUserEnv(EvalState & state, const DrvInfos & drvs,
const Path & profile) const Path & profile, bool keepDerivations)
{ {
/* Build the components in the user environment, if they don't /* Build the components in the user environment, if they don't
exist already. */ exist already. */
@ -227,19 +228,23 @@ void createUserEnv(EvalState & state, const DrvInfos & drvs,
for (DrvInfos::const_iterator i = drvs.begin(); for (DrvInfos::const_iterator i = drvs.begin();
i != drvs.end(); ++i) i != drvs.end(); ++i)
{ {
ATerm t = makeAttrs(ATmakeList4( Path drvPath = keepDerivations ? i->second.drvPath : "";
ATerm t = makeAttrs(ATmakeList5(
makeBind(toATerm("type"), makeBind(toATerm("type"),
makeStr(toATerm("derivation")), makeNoPos()), makeStr(toATerm("derivation")), makeNoPos()),
makeBind(toATerm("name"), makeBind(toATerm("name"),
makeStr(toATerm(i->second.name)), makeNoPos()), makeStr(toATerm(i->second.name)), makeNoPos()),
makeBind(toATerm("system"), makeBind(toATerm("system"),
makeStr(toATerm(i->second.system)), makeNoPos()), makeStr(toATerm(i->second.system)), makeNoPos()),
makeBind(toATerm("drvPath"),
makePath(toATerm(drvPath)), makeNoPos()),
makeBind(toATerm("outPath"), makeBind(toATerm("outPath"),
makePath(toATerm(i->second.outPath)), makeNoPos()) makePath(toATerm(i->second.outPath)), makeNoPos())
)); ));
manifest = ATinsert(manifest, t); manifest = ATinsert(manifest, t);
inputs = ATinsert(inputs, makeStr(toATerm(i->second.outPath))); inputs = ATinsert(inputs, makeStr(toATerm(i->second.outPath)));
references.insert(i->second.outPath); references.insert(i->second.outPath);
if (drvPath != "") references.insert(drvPath);
} }
/* Also write a copy of the list of inputs to the store; we need /* Also write a copy of the list of inputs to the store; we need
@ -247,8 +252,6 @@ void createUserEnv(EvalState & state, const DrvInfos & drvs,
Path manifestFile = addTextToStore("env-manifest", Path manifestFile = addTextToStore("env-manifest",
atPrint(makeList(ATreverse(manifest))), references); atPrint(makeList(ATreverse(manifest))), references);
printMsg(lvlError, format("manifest is %1%") % manifestFile);
Expr topLevel = makeCall(envBuilder, makeAttrs(ATmakeList3( Expr topLevel = makeCall(envBuilder, makeAttrs(ATmakeList3(
makeBind(toATerm("system"), makeBind(toATerm("system"),
makeStr(toATerm(thisSystem)), makeNoPos()), makeStr(toATerm(thisSystem)), makeNoPos()),
@ -281,15 +284,14 @@ void createUserEnv(EvalState & state, const DrvInfos & drvs,
} }
static void installDerivations(EvalState & state, static void installDerivations(Globals & globals,
const InstallSourceInfo & instSource, DrvNames & selectors, DrvNames & selectors, const Path & profile)
const Path & profile, bool dryRun, bool preserveInstalled)
{ {
debug(format("installing derivations")); debug(format("installing derivations"));
/* Fetch all derivations from the input file. */ /* Fetch all derivations from the input file. */
DrvInfos availDrvs; DrvInfos availDrvs;
queryInstSources(state, instSource, availDrvs); queryInstSources(globals.state, globals.instSource, availDrvs);
/* Filter out the ones we're not interested in. */ /* Filter out the ones we're not interested in. */
DrvInfos selectedDrvs; DrvInfos selectedDrvs;
@ -320,13 +322,13 @@ static void installDerivations(EvalState & state,
/* Add in the already installed derivations. */ /* Add in the already installed derivations. */
DrvInfos installedDrvs; DrvInfos installedDrvs;
queryInstalled(state, installedDrvs, profile); queryInstalled(globals.state, installedDrvs, profile);
for (DrvInfos::iterator i = installedDrvs.begin(); for (DrvInfos::iterator i = installedDrvs.begin();
i != installedDrvs.end(); ++i) i != installedDrvs.end(); ++i)
{ {
DrvName drvName(i->second.name); DrvName drvName(i->second.name);
if (!preserveInstalled && if (!globals.preserveInstalled &&
selectedNames.find(drvName.name) != selectedNames.end()) selectedNames.find(drvName.name) != selectedNames.end())
printMsg(lvlInfo, printMsg(lvlInfo,
format("uninstalling `%1%'") % i->second.name); format("uninstalling `%1%'") % i->second.name);
@ -334,9 +336,10 @@ static void installDerivations(EvalState & state,
selectedDrvs.insert(*i); selectedDrvs.insert(*i);
} }
if (dryRun) return; if (globals.dryRun) return;
createUserEnv(state, selectedDrvs, profile); createUserEnv(globals.state, selectedDrvs,
profile, globals.keepDerivations);
} }
@ -348,18 +351,16 @@ static void opInstall(Globals & globals,
DrvNames drvNames = drvNamesFromArgs(opArgs); DrvNames drvNames = drvNamesFromArgs(opArgs);
installDerivations(globals.state, globals.instSource, installDerivations(globals, drvNames, globals.profile);
drvNames, globals.profile, globals.dryRun,
globals.preserveInstalled);
} }
typedef enum { utLt, utLeq, utAlways } UpgradeType; typedef enum { utLt, utLeq, utAlways } UpgradeType;
static void upgradeDerivations(EvalState & state, static void upgradeDerivations(Globals & globals,
const InstallSourceInfo & instSource, DrvNames & selectors, const Path & profile, DrvNames & selectors, const Path & profile,
UpgradeType upgradeType, bool dryRun) UpgradeType upgradeType)
{ {
debug(format("upgrading derivations")); debug(format("upgrading derivations"));
@ -370,11 +371,11 @@ static void upgradeDerivations(EvalState & state,
/* Load the currently installed derivations. */ /* Load the currently installed derivations. */
DrvInfos installedDrvs; DrvInfos installedDrvs;
queryInstalled(state, installedDrvs, profile); queryInstalled(globals.state, installedDrvs, profile);
/* Fetch all derivations from the input file. */ /* Fetch all derivations from the input file. */
DrvInfos availDrvs; DrvInfos availDrvs;
// xxx loadDerivations(state, nePath, availDrvs, systemFilter); queryInstSources(globals.state, globals.instSource, availDrvs);
/* Go through all installed derivations. */ /* Go through all installed derivations. */
DrvInfos newDrvs; DrvInfos newDrvs;
@ -440,9 +441,10 @@ static void upgradeDerivations(EvalState & state,
} else newDrvs.insert(*i); } else newDrvs.insert(*i);
} }
if (dryRun) return; if (globals.dryRun) return;
createUserEnv(state, newDrvs, profile); createUserEnv(globals.state, newDrvs,
profile, globals.keepDerivations);
} }
@ -459,16 +461,15 @@ static void opUpgrade(Globals & globals,
DrvNames drvNames = drvNamesFromArgs(opArgs); DrvNames drvNames = drvNamesFromArgs(opArgs);
upgradeDerivations(globals.state, globals.instSource, upgradeDerivations(globals, drvNames, globals.profile, upgradeType);
drvNames, globals.profile, upgradeType, globals.dryRun);
} }
static void uninstallDerivations(EvalState & state, DrvNames & selectors, static void uninstallDerivations(Globals & globals, DrvNames & selectors,
Path & profile, bool dryRun) Path & profile)
{ {
DrvInfos installedDrvs; DrvInfos installedDrvs;
queryInstalled(state, installedDrvs, profile); queryInstalled(globals.state, installedDrvs, profile);
for (DrvInfos::iterator i = installedDrvs.begin(); for (DrvInfos::iterator i = installedDrvs.begin();
i != installedDrvs.end(); ++i) i != installedDrvs.end(); ++i)
@ -483,9 +484,10 @@ static void uninstallDerivations(EvalState & state, DrvNames & selectors,
} }
} }
if (dryRun) return; if (globals.dryRun) return;
createUserEnv(state, installedDrvs, profile); createUserEnv(globals.state, installedDrvs,
profile, globals.keepDerivations);
} }
@ -497,8 +499,8 @@ static void opUninstall(Globals & globals,
DrvNames drvNames = drvNamesFromArgs(opArgs); DrvNames drvNames = drvNamesFromArgs(opArgs);
uninstallDerivations(globals.state, drvNames, uninstallDerivations(globals, drvNames,
globals.profile, globals.dryRun); globals.profile);
} }
@ -798,6 +800,7 @@ void run(Strings args)
Operation op = 0; Operation op = 0;
Globals globals; Globals globals;
globals.instSource.type = srcUnknown; globals.instSource.type = srcUnknown;
globals.instSource.nixExprPath = getDefNixExprPath(); globals.instSource.nixExprPath = getDefNixExprPath();
globals.instSource.systemFilter = thisSystem; globals.instSource.systemFilter = thisSystem;
@ -805,6 +808,9 @@ void run(Strings args)
globals.dryRun = false; globals.dryRun = false;
globals.preserveInstalled = false; globals.preserveInstalled = false;
globals.keepDerivations =
queryBoolSetting("env-keep-derivations", false);
for (Strings::iterator i = args.begin(); i != args.end(); ++i) { for (Strings::iterator i = args.begin(); i != args.end(); ++i) {
string arg = *i; string arg = *i;