aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libexpr/primops.cc21
-rw-r--r--src/libutil/util.hh8
-rw-r--r--src/nix-env/help.txt3
-rw-r--r--src/nix-env/main.cc152
-rw-r--r--src/nix-env/profiles.cc2
5 files changed, 125 insertions, 61 deletions
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 013eba594..da9d1e635 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -94,6 +94,7 @@ static void processBinding(EvalState & state, Expr e, Derivation & drv,
else if (matchAttrs(e, es)) {
Expr a = queryAttr(e, "type");
+
if (a && evalString(state, a) == "derivation") {
a = queryAttr(e, "drvPath");
if (!a) throw Error("derivation name missing");
@@ -104,12 +105,22 @@ static void processBinding(EvalState & state, Expr e, Derivation & drv,
/* !!! supports only single output path */
Path outPath = evalPath(state, a);
- StringSet ids;
- ids.insert("out");
- drv.inputDrvs[drvPath] = ids;
+ drv.inputDrvs[drvPath] = singleton<StringSet>("out");
+ ss.push_back(outPath);
+ }
+
+ else if (a && evalString(state, a) == "storePath") {
+
+ a = queryAttr(e, "outPath");
+ if (!a) throw Error("output path missing");
+ /* !!! supports only single output path */
+ Path outPath = evalPath(state, a);
+
+ drv.inputSrcs.insert(outPath);
ss.push_back(outPath);
- } else
- throw Error("invalid derivation attribute");
+ }
+
+ else throw Error("invalid derivation attribute");
}
else if (matchPath(e, s)) {
diff --git a/src/libutil/util.hh b/src/libutil/util.hh
index b67913862..2577f79e1 100644
--- a/src/libutil/util.hh
+++ b/src/libutil/util.hh
@@ -112,6 +112,14 @@ Path createTempDir();
not already exist. */
void writeStringToFile(const Path & path, const string & s);
+template<class T, class A>
+T singleton(const A & a)
+{
+ T t;
+ t.insert(a);
+ return t;
+}
+
/* Messages. */
diff --git a/src/nix-env/help.txt b/src/nix-env/help.txt
index fe9eca79e..4fc160284 100644
--- a/src/nix-env/help.txt
+++ b/src/nix-env/help.txt
@@ -37,7 +37,8 @@ Upgrade flags:
Query types:
--name: print derivation names (default)
- --expr: print derivation store expression
+ --drv-path: print path of derivation
+ --out-path: print path of derivation output
--status / -s: print installed/present status
Query sources:
diff --git a/src/nix-env/main.cc b/src/nix-env/main.cc
index da77e2428..d45dd2bd8 100644
--- a/src/nix-env/main.cc
+++ b/src/nix-env/main.cc
@@ -12,14 +12,31 @@
#include <ctime>
+typedef enum {
+ srcNixExprDrvs,
+ srcNixExprs,
+ srcStorePaths,
+ srcProfile,
+ srcUnknown
+} InstallSourceType;
+
+
+struct InstallSourceInfo
+{
+ InstallSourceType type;
+ Path nixExprPath; /* for srcNixExprDrvs, srcNixExprs */
+ Path profile; /* for srcProfile */
+ string systemFilter; /* for srcNixExprDrvs */
+};
+
+
struct Globals
{
+ InstallSourceInfo instSource;
Path profile;
- Path nixExprPath;
EvalState state;
bool dryRun;
bool preserveInstalled;
- string systemFilter;
};
@@ -64,8 +81,7 @@ bool parseDerivation(EvalState & state, Expr e, DrvInfo & drv)
drv.system = evalString(state, a);
a = queryAttr(e, "drvPath");
- if (!a) throw badTerm("derivation path missing", e);
- drv.drvPath = evalPath(state, a);
+ if (a) drv.drvPath = evalPath(state, a);
a = queryAttr(e, "outPath");
if (!a) throw badTerm("output path missing", e);
@@ -83,7 +99,7 @@ bool parseDerivations(EvalState & state, Expr e, DrvInfos & drvs)
e = evalExpr(state, e);
if (parseDerivation(state, e, drv))
- drvs[drv.drvPath] = drv;
+ drvs[drv.outPath] = drv;
else if (matchAttrs(e, es)) {
ATermMap drvMap;
@@ -91,7 +107,7 @@ bool parseDerivations(EvalState & state, Expr e, DrvInfos & drvs)
for (ATermIterator i(drvMap.keys()); i; ++i) {
debug(format("evaluating attribute `%1%'") % *i);
if (parseDerivation(state, drvMap.get(*i), drv))
- drvs[drv.drvPath] = drv;
+ drvs[drv.outPath] = drv;
else
parseDerivations(state, drvMap.get(*i), drvs);
}
@@ -101,7 +117,7 @@ bool parseDerivations(EvalState & state, Expr e, DrvInfos & drvs)
for (ATermIterator i(es); i; ++i) {
debug(format("evaluating list element"));
if (parseDerivation(state, *i, drv))
- drvs[drv.drvPath] = drv;
+ drvs[drv.outPath] = drv;
else
parseDerivations(state, *i, drvs);
}
@@ -111,10 +127,10 @@ bool parseDerivations(EvalState & state, Expr e, DrvInfos & drvs)
}
-void loadDerivations(EvalState & state, Path nePath, DrvInfos & drvs,
- string systemFilter)
+static void loadDerivations(EvalState & state, Path nixExprPath,
+ string systemFilter, DrvInfos & drvs)
{
- Expr e = parseExprFromFile(state, absPath(nePath));
+ Expr e = parseExprFromFile(state, absPath(nixExprPath));
if (!parseDerivations(state, e, drvs))
throw Error("set of derivations expected");
@@ -128,6 +144,18 @@ void loadDerivations(EvalState & state, Path nePath, DrvInfos & drvs,
}
+static void queryInstSources(EvalState & state,
+ const InstallSourceInfo & instSource, DrvInfos & drvs)
+{
+ switch (instSource.type) {
+ case srcUnknown:
+ loadDerivations(state, instSource.nixExprPath,
+ instSource.systemFilter, drvs);
+ break;
+ }
+}
+
+
static Path getHomeDir()
{
Path homeDir(getEnv("HOME", ""));
@@ -177,43 +205,62 @@ void queryInstalled(EvalState & state, DrvInfos & drvs,
void createUserEnv(EvalState & state, const DrvInfos & drvs,
const Path & profile)
{
+ /* Build the components in the user environment, if they don't
+ exist already. */
+ PathSet drvsToBuild;
+ for (DrvInfos::const_iterator i = drvs.begin();
+ i != drvs.end(); ++i)
+ if (i->second.drvPath != "")
+ drvsToBuild.insert(i->second.drvPath);
+
+ debug(format("building user environment dependencies"));
+ buildDerivations(drvsToBuild);
+
/* Get the environment builder expression. */
Expr envBuilder = parseExprFromFile(state,
nixDataDir + "/nix/corepkgs/buildenv"); /* !!! */
/* Construct the whole top level derivation. */
+ PathSet references;
+ ATermList manifest = ATempty;
ATermList inputs = ATempty;
for (DrvInfos::const_iterator i = drvs.begin();
i != drvs.end(); ++i)
{
- ATerm t = makeAttrs(ATmakeList5(
+ ATerm t = makeAttrs(ATmakeList4(
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())
));
- inputs = ATinsert(inputs, t);
+ manifest = ATinsert(manifest, t);
+ inputs = ATinsert(inputs, makeStr(toATerm(i->second.outPath)));
+ references.insert(i->second.outPath);
}
- ATerm inputs2 = makeList(ATreverse(inputs));
-
/* Also write a copy of the list of inputs to the store; we need
it for future modifications of the environment. */
- Path inputsFile = addTextToStore("env-inputs", atPrint(inputs2),
- PathSet() /* !!! incorrect */);
+ Path manifestFile = addTextToStore("env-manifest",
+ atPrint(makeList(ATreverse(manifest))), references);
+
+ printMsg(lvlError, format("manifest is %1%") % manifestFile);
Expr topLevel = makeCall(envBuilder, makeAttrs(ATmakeList3(
makeBind(toATerm("system"),
makeStr(toATerm(thisSystem)), makeNoPos()),
- makeBind(toATerm("derivations"), inputs2, makeNoPos()),
+ makeBind(toATerm("derivations"),
+ makeList(ATreverse(inputs)), makeNoPos()),
makeBind(toATerm("manifest"),
- makePath(toATerm(inputsFile)), makeNoPos())
+ makeAttrs(ATmakeList2(
+ makeBind(toATerm("type"),
+ makeStr(toATerm("storePath")), makeNoPos()),
+ makeBind(toATerm("outPath"),
+ makePath(toATerm(manifestFile)), makeNoPos())
+ )), makeNoPos())
)));
/* Instantiate it. */
@@ -224,9 +271,7 @@ void createUserEnv(EvalState & state, const DrvInfos & drvs,
/* Realise the resulting store expression. */
debug(format("building user environment"));
- PathSet drvPaths;
- drvPaths.insert(topLevelDrv.drvPath);
- buildDerivations(drvPaths);
+ buildDerivations(singleton<PathSet>(topLevelDrv.drvPath));
/* Switch the current user environment to the output path. */
debug(format("switching to new user environment"));
@@ -237,14 +282,14 @@ void createUserEnv(EvalState & state, const DrvInfos & drvs,
static void installDerivations(EvalState & state,
- Path nePath, DrvNames & selectors, const Path & profile,
- bool dryRun, bool preserveInstalled, string systemFilter)
+ const InstallSourceInfo & instSource, DrvNames & selectors,
+ const Path & profile, bool dryRun, bool preserveInstalled)
{
- debug(format("installing derivations from `%1%'") % nePath);
+ debug(format("installing derivations"));
/* Fetch all derivations from the input file. */
DrvInfos availDrvs;
- loadDerivations(state, nePath, availDrvs, systemFilter);
+ queryInstSources(state, instSource, availDrvs);
/* Filter out the ones we're not interested in. */
DrvInfos selectedDrvs;
@@ -303,9 +348,9 @@ static void opInstall(Globals & globals,
DrvNames drvNames = drvNamesFromArgs(opArgs);
- installDerivations(globals.state, globals.nixExprPath,
+ installDerivations(globals.state, globals.instSource,
drvNames, globals.profile, globals.dryRun,
- globals.preserveInstalled, globals.systemFilter);
+ globals.preserveInstalled);
}
@@ -313,10 +358,10 @@ typedef enum { utLt, utLeq, utAlways } UpgradeType;
static void upgradeDerivations(EvalState & state,
- Path nePath, DrvNames & selectors, const Path & profile,
- UpgradeType upgradeType, bool dryRun, string systemFilter)
+ const InstallSourceInfo & instSource, DrvNames & selectors, const Path & profile,
+ UpgradeType upgradeType, bool dryRun)
{
- debug(format("upgrading derivations from `%1%'") % nePath);
+ debug(format("upgrading derivations"));
/* Upgrade works as follows: we take all currently installed
derivations, and for any derivation matching any selector, look
@@ -329,7 +374,7 @@ static void upgradeDerivations(EvalState & state,
/* Fetch all derivations from the input file. */
DrvInfos availDrvs;
- loadDerivations(state, nePath, availDrvs, systemFilter);
+ // xxx loadDerivations(state, nePath, availDrvs, systemFilter);
/* Go through all installed derivations. */
DrvInfos newDrvs;
@@ -414,9 +459,8 @@ static void opUpgrade(Globals & globals,
DrvNames drvNames = drvNamesFromArgs(opArgs);
- upgradeDerivations(globals.state, globals.nixExprPath,
- drvNames, globals.profile, upgradeType, globals.dryRun,
- globals.systemFilter);
+ upgradeDerivations(globals.state, globals.instSource,
+ drvNames, globals.profile, upgradeType, globals.dryRun);
}
@@ -511,6 +555,7 @@ static void opQuery(Globals & globals,
bool printName = true;
bool printSystem = false;
bool printDrvPath = false;
+ bool printOutPath = false;
enum { sInstalled, sAvailable } source = sInstalled;
@@ -521,7 +566,8 @@ static void opQuery(Globals & globals,
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;
+ else if (*i == "--drv-path") printDrvPath = true;
+ else if (*i == "--out-path") printOutPath = true;
else if (*i == "--installed") source = sInstalled;
else if (*i == "--available" || *i == "-a") source = sAvailable;
else throw UsageError(format("unknown flag `%1%'") % *i);
@@ -536,8 +582,8 @@ static void opQuery(Globals & globals,
break;
case sAvailable: {
- loadDerivations(globals.state, globals.nixExprPath,
- drvs, globals.systemFilter);
+ loadDerivations(globals.state, globals.instSource.nixExprPath,
+ globals.instSource.systemFilter, drvs);
break;
}
@@ -554,16 +600,10 @@ static void opQuery(Globals & globals,
/* We only need to know the installed paths when we are querying
the status of the derivation. */
- PathSet installedPaths; /* output paths of installed drvs */
+ DrvInfos installed; /* installed paths */
- if (printStatus) {
- DrvInfos installed;
+ if (printStatus)
queryInstalled(globals.state, installed, globals.profile);
-
- for (DrvInfos::iterator i = installed.begin();
- i != installed.end(); ++i)
- installedPaths.insert(i->second.outPath);
- }
/* Print the desired columns. */
Table table;
@@ -575,8 +615,8 @@ static void opQuery(Globals & globals,
if (printStatus) {
Substitutes subs = querySubstitutes(noTxn, i->drvPath);
columns.push_back(
- (string) (installedPaths.find(i->outPath)
- != installedPaths.end() ? "I" : "-")
+ (string) (installed.find(i->outPath)
+ != installed.end() ? "I" : "-")
+ (isValidPath(i->outPath) ? "P" : "-")
+ (subs.size() > 0 ? "S" : "-"));
}
@@ -585,7 +625,9 @@ static void opQuery(Globals & globals,
if (printSystem) columns.push_back(i->system);
- if (printDrvPath) columns.push_back(i->drvPath);
+ if (printDrvPath) columns.push_back(i->drvPath == "" ? "-" : i->drvPath);
+
+ if (printOutPath) columns.push_back(i->outPath);
table.push_back(columns);
}
@@ -756,10 +798,12 @@ void run(Strings args)
Operation op = 0;
Globals globals;
- globals.nixExprPath = getDefNixExprPath();
+ globals.instSource.type = srcUnknown;
+ globals.instSource.nixExprPath = getDefNixExprPath();
+ globals.instSource.systemFilter = thisSystem;
+
globals.dryRun = false;
globals.preserveInstalled = false;
- globals.systemFilter = thisSystem;
for (Strings::iterator i = args.begin(); i != args.end(); ++i) {
string arg = *i;
@@ -786,7 +830,7 @@ void run(Strings args)
++i;
if (i == args.end()) throw UsageError(
format("`%1%' requires an argument") % arg);
- globals.nixExprPath = absPath(*i);
+ globals.instSource.nixExprPath = absPath(*i);
}
else if (arg == "--switch-profile" || arg == "-S")
op = opSwitchProfile;
@@ -808,7 +852,7 @@ void run(Strings args)
++i;
if (i == args.end()) throw UsageError(
format("`%1%' requires an argument") % arg);
- globals.systemFilter = *i;
+ globals.instSource.systemFilter = *i;
}
else if (arg[0] == '-')
opFlags.push_back(arg);
diff --git a/src/nix-env/profiles.cc b/src/nix-env/profiles.cc
index abfdf9fed..20aaded77 100644
--- a/src/nix-env/profiles.cc
+++ b/src/nix-env/profiles.cc
@@ -65,7 +65,7 @@ static void makeNames(const Path & profile, unsigned int num,
Path & outLink, Path & drvLink)
{
Path prefix = (format("%1%-%2%") % profile % num).str();
- outLink = prefix + "-output";
+ outLink = prefix + "-link";
drvLink = prefix + "-drv";
}