diff --git a/doc/manual/release-notes.xml b/doc/manual/release-notes.xml
index f5efdad85..ae773f525 100644
--- a/doc/manual/release-notes.xml
+++ b/doc/manual/release-notes.xml
@@ -69,6 +69,9 @@ irreversible.
TODO: open files etc. are now used as roots of the
garbage collector.
+ TODO: --attr / -a flags in
+ nix-env/nix-instantiate/nix-build.
+
diff --git a/src/nix-env/help.txt b/src/nix-env/help.txt
index e83194774..3287bab28 100644
--- a/src/nix-env/help.txt
+++ b/src/nix-env/help.txt
@@ -28,6 +28,15 @@ Install / upgrade / uninstall flags:
--dry-run: show what would be done, but don't do it
+Installation sources:
+
+ --from-expression / -E EXPR...: evaluate expressions specified on
+ the command line; expressions should be functions that take the
+ default Nix expression as an argument
+ --from-profile PROFILE NAMES...: copy named packages from PROFILE
+ --attr / -A ATTRS...: select attributes by name from the default Nix
+ expression
+
Upgrade flags:
--lt: upgrade if the current version is older (default)
diff --git a/src/nix-env/main.cc b/src/nix-env/main.cc
index 400bb0d87..633c85b61 100644
--- a/src/nix-env/main.cc
+++ b/src/nix-env/main.cc
@@ -25,6 +25,7 @@ typedef enum {
srcNixExprs,
srcStorePaths,
srcProfile,
+ srcAttrPath,
srcUnknown
} InstallSourceType;
@@ -35,6 +36,7 @@ struct InstallSourceInfo
Path nixExprPath; /* for srcNixExprDrvs, srcNixExprs */
Path profile; /* for srcProfile */
string systemFilter; /* for srcNixExprDrvs */
+ string attrPath; /* srcAttrPath */
};
@@ -381,6 +383,14 @@ static void queryInstSources(EvalState & state,
args, newestOnly);
break;
}
+
+ case srcAttrPath: {
+ for (Strings::const_iterator i = args.begin();
+ i != args.end(); ++i)
+ getDerivations(state,
+ parseExprFromFile(state, instSource.nixExprPath), elems, *i);
+ break;
+ }
}
}
@@ -470,7 +480,7 @@ static void opInstall(Globals & globals,
Strings opFlags, Strings opArgs)
{
if (opFlags.size() > 0)
- throw UsageError(format("unknown flags `%1%'") % opFlags.front());
+ throw UsageError(format("unknown flag `%1%'") % opFlags.front());
installDerivations(globals, opArgs, globals.profile);
}
@@ -606,7 +616,7 @@ static void opUninstall(Globals & globals,
Strings opFlags, Strings opArgs)
{
if (opFlags.size() > 0)
- throw UsageError(format("unknown flags `%1%'") % opFlags.front());
+ throw UsageError(format("unknown flag `%1%'") % opFlags.front());
DrvNames drvNames = drvNamesFromArgs(opArgs);
@@ -988,7 +998,7 @@ static void opDefaultExpr(Globals & globals,
Strings opFlags, Strings opArgs)
{
if (opFlags.size() > 0)
- throw UsageError(format("unknown flags `%1%'") % opFlags.front());
+ throw UsageError(format("unknown flag `%1%'") % opFlags.front());
if (opArgs.size() != 1)
throw UsageError(format("exactly one argument expected"));
@@ -1040,6 +1050,8 @@ void run(Strings args)
globals.instSource.type = srcProfile;
globals.instSource.profile = needArg(i, args, arg);
}
+ else if (arg == "--attr" || arg == "-A")
+ globals.instSource.type = srcAttrPath;
else if (arg == "--uninstall" || arg == "-e")
op = opUninstall;
else if (arg == "--upgrade" || arg == "-u")