aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2017-08-29 14:28:57 +0200
committerEelco Dolstra <edolstra@gmail.com>2017-08-29 14:42:48 +0200
commit5cc8609e30ab4f76053f3159c51ea78d9215bc8c (patch)
tree1a8d1d78f82389280f6c59954b8f82bdb2823f43 /src
parent93a5ef0516881ec133fc5e54069add6dd64ffbdd (diff)
nix run: Allow passing a command to execute
E.g. nix run nixpkgs.hello -c hello --greeting Hallo Note that unlike "nix-shell --command", no quoting of arguments is necessary. "-c" (short for "--command") cannot be combined with "--" because they both consume all remaining arguments. But since installables shouldn't start with a dash, this is unlikely to cause problems.
Diffstat (limited to 'src')
-rw-r--r--src/libutil/args.cc4
-rw-r--r--src/libutil/args.hh2
-rw-r--r--src/nix/run.cc16
3 files changed, 19 insertions, 3 deletions
diff --git a/src/libutil/args.cc b/src/libutil/args.cc
index 2b72079f2..d17a1e7a9 100644
--- a/src/libutil/args.cc
+++ b/src/libutil/args.cc
@@ -102,9 +102,11 @@ bool Args::processFlag(Strings::iterator & pos, Strings::iterator end)
++pos;
Strings args;
for (size_t n = 0 ; n < flag.arity; ++n) {
- if (pos == end)
+ if (pos == end) {
+ if (flag.arity == ArityAny) break;
throw UsageError(format("flag '%1%' requires %2% argument(s)")
% name % flag.arity);
+ }
args.push_back(*pos++);
}
flag.handler(args);
diff --git a/src/libutil/args.hh b/src/libutil/args.hh
index fd910b965..044ed209e 100644
--- a/src/libutil/args.hh
+++ b/src/libutil/args.hh
@@ -26,6 +26,8 @@ public:
protected:
+ static const size_t ArityAny = std::numeric_limits<size_t>::max();
+
/* Flags. */
struct Flag
{
diff --git a/src/nix/run.cc b/src/nix/run.cc
index e58e2f187..39fbcc8ac 100644
--- a/src/nix/run.cc
+++ b/src/nix/run.cc
@@ -17,8 +17,20 @@ std::string chrootHelperName = "__run_in_chroot";
struct CmdRun : InstallablesCommand
{
+ Strings command = { "bash" };
+
CmdRun()
{
+ mkFlag()
+ .longName("command")
+ .shortName('c')
+ .description("command and arguments to be executed; defaults to 'bash'")
+ .arity(ArityAny)
+ .labels({"command", "args"})
+ .handler([&](Strings ss) {
+ if (ss.empty()) throw UsageError("--command requires at least one argument");
+ command = ss;
+ });
}
std::string name() override
@@ -43,8 +55,8 @@ struct CmdRun : InstallablesCommand
unixPath.push_front(path + "/bin");
setenv("PATH", concatStringsSep(":", unixPath).c_str(), 1);
- std::string cmd = "bash";
- Strings args = { cmd };
+ std::string cmd = *command.begin();
+ Strings args = command;
/* If this is a diverted store (i.e. its "logical" location
(typically /nix/store) differs from its "physical" location