aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2017-10-24 12:45:11 +0200
committerEelco Dolstra <edolstra@gmail.com>2017-10-24 12:58:34 +0200
commit0d59f1ca49c9f7f3b2edaadcf590360ec66a6257 (patch)
treea03d53d84fb61eb354e2634705d8a076f0c1c76d /src
parent25f32625e2f2a3a1e1b3a3811da82f21c3a3b880 (diff)
nix: Respect -I, --arg, --argstr
Also, random cleanup to argument handling.
Diffstat (limited to 'src')
-rw-r--r--src/libexpr/common-eval-args.cc57
-rw-r--r--src/libexpr/common-eval-args.hh26
-rw-r--r--src/libexpr/common-opts.cc67
-rw-r--r--src/libexpr/common-opts.hh20
-rw-r--r--src/libmain/common-args.cc28
-rw-r--r--src/libmain/shared.cc116
-rw-r--r--src/libmain/shared.hh14
-rw-r--r--src/libstore/globals.cc6
-rw-r--r--src/libutil/args.cc18
-rw-r--r--src/libutil/args.hh68
-rw-r--r--src/libutil/config.cc6
-rwxr-xr-xsrc/nix-build/nix-build.cc23
-rw-r--r--src/nix-env/nix-env.cc22
-rw-r--r--src/nix-instantiate/nix-instantiate.cc22
-rw-r--r--src/nix-prefetch-url/nix-prefetch-url.cc21
-rw-r--r--src/nix/command.cc6
-rw-r--r--src/nix/command.hh11
-rw-r--r--src/nix/copy.cc12
-rw-r--r--src/nix/hash.cc14
-rw-r--r--src/nix/installables.cc26
-rw-r--r--src/nix/main.cc36
-rw-r--r--src/nix/repl.cc13
-rw-r--r--src/nix/run.cc11
-rw-r--r--src/nix/search.cc4
-rw-r--r--src/nix/sigs.cc9
-rw-r--r--src/nix/verify.cc2
26 files changed, 354 insertions, 304 deletions
diff --git a/src/libexpr/common-eval-args.cc b/src/libexpr/common-eval-args.cc
new file mode 100644
index 000000000..3e0c78f28
--- /dev/null
+++ b/src/libexpr/common-eval-args.cc
@@ -0,0 +1,57 @@
+#include "common-eval-args.hh"
+#include "shared.hh"
+#include "download.hh"
+#include "util.hh"
+#include "eval.hh"
+
+namespace nix {
+
+MixEvalArgs::MixEvalArgs()
+{
+ mkFlag()
+ .longName("arg")
+ .description("argument to be passed to Nix functions")
+ .labels({"name", "expr"})
+ .handler([&](std::vector<std::string> ss) { autoArgs[ss[0]] = 'E' + ss[1]; });
+
+ mkFlag()
+ .longName("argstr")
+ .description("string-valued argument to be passed to Nix functions")
+ .labels({"name", "string"})
+ .handler([&](std::vector<std::string> ss) { autoArgs[ss[0]] = 'S' + ss[1]; });
+
+ mkFlag()
+ .shortName('I')
+ .longName("include")
+ .description("add a path to the list of locations used to look up <...> file names")
+ .label("path")
+ .handler([&](std::string s) { searchPath.push_back(s); });
+}
+
+Bindings * MixEvalArgs::getAutoArgs(EvalState & state)
+{
+ Bindings * res = state.allocBindings(autoArgs.size());
+ for (auto & i : autoArgs) {
+ Value * v = state.allocValue();
+ if (i.second[0] == 'E')
+ state.mkThunk_(*v, state.parseExprFromString(string(i.second, 1), absPath(".")));
+ else
+ mkString(*v, string(i.second, 1));
+ res->push_back(Attr(state.symbols.create(i.first), v));
+ }
+ res->sort();
+ return res;
+}
+
+Path lookupFileArg(EvalState & state, string s)
+{
+ if (isUri(s))
+ return getDownloader()->downloadCached(state.store, s, true);
+ else if (s.size() > 2 && s.at(0) == '<' && s.at(s.size() - 1) == '>') {
+ Path p = s.substr(1, s.size() - 2);
+ return state.findFile(p);
+ } else
+ return absPath(s);
+}
+
+}
diff --git a/src/libexpr/common-eval-args.hh b/src/libexpr/common-eval-args.hh
new file mode 100644
index 000000000..09fa406b2
--- /dev/null
+++ b/src/libexpr/common-eval-args.hh
@@ -0,0 +1,26 @@
+#pragma once
+
+#include "args.hh"
+
+namespace nix {
+
+class Store;
+class EvalState;
+struct Bindings;
+
+struct MixEvalArgs : virtual Args
+{
+ MixEvalArgs();
+
+ Bindings * getAutoArgs(EvalState & state);
+
+ Strings searchPath;
+
+private:
+
+ std::map<std::string, std::string> autoArgs;
+};
+
+Path lookupFileArg(EvalState & state, string s);
+
+}
diff --git a/src/libexpr/common-opts.cc b/src/libexpr/common-opts.cc
deleted file mode 100644
index 6b31961d3..000000000
--- a/src/libexpr/common-opts.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-#include "common-opts.hh"
-#include "shared.hh"
-#include "download.hh"
-#include "util.hh"
-
-
-namespace nix {
-
-
-bool parseAutoArgs(Strings::iterator & i,
- const Strings::iterator & argsEnd, std::map<string, string> & res)
-{
- string arg = *i;
- if (arg != "--arg" && arg != "--argstr") return false;
-
- UsageError error(format("'%1%' requires two arguments") % arg);
-
- if (++i == argsEnd) throw error;
- string name = *i;
- if (++i == argsEnd) throw error;
- string value = *i;
-
- res[name] = (arg == "--arg" ? 'E' : 'S') + value;
-
- return true;
-}
-
-
-Bindings * evalAutoArgs(EvalState & state, std::map<string, string> & in)
-{
- Bindings * res = state.allocBindings(in.size());
- for (auto & i : in) {
- Value * v = state.allocValue();
- if (i.second[0] == 'E')
- state.mkThunk_(*v, state.parseExprFromString(string(i.second, 1), absPath(".")));
- else
- mkString(*v, string(i.second, 1));
- res->push_back(Attr(state.symbols.create(i.first), v));
- }
- res->sort();
- return res;
-}
-
-
-bool parseSearchPathArg(Strings::iterator & i,
- const Strings::iterator & argsEnd, Strings & searchPath)
-{
- if (*i != "-I") return false;
- if (++i == argsEnd) throw UsageError("'-I' requires an argument");
- searchPath.push_back(*i);
- return true;
-}
-
-
-Path lookupFileArg(EvalState & state, string s)
-{
- if (isUri(s))
- return getDownloader()->downloadCached(state.store, s, true);
- else if (s.size() > 2 && s.at(0) == '<' && s.at(s.size() - 1) == '>') {
- Path p = s.substr(1, s.size() - 2);
- return state.findFile(p);
- } else
- return absPath(s);
-}
-
-
-}
diff --git a/src/libexpr/common-opts.hh b/src/libexpr/common-opts.hh
deleted file mode 100644
index cb2732d6f..000000000
--- a/src/libexpr/common-opts.hh
+++ /dev/null
@@ -1,20 +0,0 @@
-#pragma once
-
-#include "eval.hh"
-
-namespace nix {
-
-class Store;
-
-/* Some common option parsing between nix-env and nix-instantiate. */
-bool parseAutoArgs(Strings::iterator & i,
- const Strings::iterator & argsEnd, std::map<string, string> & res);
-
-Bindings * evalAutoArgs(EvalState & state, std::map<string, string> & in);
-
-bool parseSearchPathArg(Strings::iterator & i,
- const Strings::iterator & argsEnd, Strings & searchPath);
-
-Path lookupFileArg(EvalState & state, string s);
-
-}
diff --git a/src/libmain/common-args.cc b/src/libmain/common-args.cc
index 3fa42c2aa..ea27aaa35 100644
--- a/src/libmain/common-args.cc
+++ b/src/libmain/common-args.cc
@@ -6,28 +6,30 @@ namespace nix {
MixCommonArgs::MixCommonArgs(const string & programName)
: programName(programName)
{
- mkFlag('v', "verbose", "increase verbosity level", []() {
- verbosity = (Verbosity) (verbosity + 1);
- });
+ mkFlag()
+ .longName("verbose")
+ .shortName('v')
+ .description("increase verbosity level")
+ .handler([]() { verbosity = (Verbosity) (verbosity + 1); });
- mkFlag(0, "quiet", "decrease verbosity level", []() {
- verbosity = verbosity > lvlError ? (Verbosity) (verbosity - 1) : lvlError;
- });
+ mkFlag()
+ .longName("quiet")
+ .description("decrease verbosity level")
+ .handler([]() { verbosity = verbosity > lvlError ? (Verbosity) (verbosity - 1) : lvlError; });
- mkFlag(0, "debug", "enable debug output", []() {
- verbosity = lvlDebug;
- });
+ mkFlag()
+ .longName("debug")
+ .description("enable debug output")
+ .handler([]() { verbosity = lvlDebug; });
mkFlag()
.longName("option")
.labels({"name", "value"})
.description("set a Nix configuration option (overriding nix.conf)")
.arity(2)
- .handler([](Strings ss) {
- auto name = ss.front(); ss.pop_front();
- auto value = ss.front();
+ .handler([](std::vector<std::string> ss) {
try {
- settings.set(name, value);
+ settings.set(ss[0], ss[1]);
} catch (UsageError & e) {
warn(e.what());
}
diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc
index aef5d88bf..9123a3d1a 100644
--- a/src/libmain/shared.cc
+++ b/src/libmain/shared.cc
@@ -1,4 +1,3 @@
-#include "common-args.hh"
#include "globals.hh"
#include "shared.hh"
#include "store-api.hh"
@@ -149,71 +148,78 @@ void initNix()
}
-struct LegacyArgs : public MixCommonArgs
+LegacyArgs::LegacyArgs(const std::string & programName,
+ std::function<bool(Strings::iterator & arg, const Strings::iterator & end)> parseArg)
+ : MixCommonArgs(programName), parseArg(parseArg)
{
- std::function<bool(Strings::iterator & arg, const Strings::iterator & end)> parseArg;
-
- LegacyArgs(const std::string & programName,
- std::function<bool(Strings::iterator & arg, const Strings::iterator & end)> parseArg)
- : MixCommonArgs(programName), parseArg(parseArg)
- {
- mkFlag('Q', "no-build-output", "do not show build output",
- &settings.verboseBuild, false);
-
- mkFlag('K', "keep-failed", "keep temporary directories of failed builds",
- &(bool&) settings.keepFailed);
-
- mkFlag('k', "keep-going", "keep going after a build fails",
- &(bool&) settings.keepGoing);
+ mkFlag()
+ .longName("no-build-output")
+ .shortName('Q')
+ .description("do not show build output")
+ .set(&settings.verboseBuild, false);
+
+ mkFlag()
+ .longName("keep-failed")
+ .shortName('K')
+ .description("keep temporary directories of failed builds")
+ .set(&(bool&) settings.keepFailed, true);
+
+ mkFlag()
+ .longName("keep-going")
+ .shortName('k')
+ .description("keep going after a build fails")
+ .set(&(bool&) settings.keepGoing, true);
+
+ mkFlag()
+ .longName("fallback")
+ .description("build from source if substitution fails")
+ .set(&(bool&) settings.tryFallback, true);
+
+ mkFlag1('j', "max-jobs", "jobs", "maximum number of parallel builds", [=](std::string s) {
+ settings.set("max-jobs", s);
+ });
- mkFlag(0, "fallback", "build from source if substitution fails", []() {
- settings.tryFallback = true;
+ auto intSettingAlias = [&](char shortName, const std::string & longName,
+ const std::string & description, const std::string & dest) {
+ mkFlag<unsigned int>(shortName, longName, description, [=](unsigned int n) {
+ settings.set(dest, std::to_string(n));
});
+ };
- mkFlag1('j', "max-jobs", "jobs", "maximum number of parallel builds", [=](std::string s) {
- settings.set("max-jobs", s);
- });
+ intSettingAlias(0, "cores", "maximum number of CPU cores to use inside a build", "cores");
+ intSettingAlias(0, "max-silent-time", "number of seconds of silence before a build is killed", "max-silent-time");
+ intSettingAlias(0, "timeout", "number of seconds before a build is killed", "timeout");
- auto intSettingAlias = [&](char shortName, const std::string & longName,
- const std::string & description, const std::string & dest) {
- mkFlag<unsigned int>(shortName, longName, description, [=](unsigned int n) {
- settings.set(dest, std::to_string(n));
- });
- };
+ mkFlag(0, "readonly-mode", "do not write to the Nix store",
+ &settings.readOnlyMode);
- intSettingAlias(0, "cores", "maximum number of CPU cores to use inside a build", "cores");
- intSettingAlias(0, "max-silent-time", "number of seconds of silence before a build is killed", "max-silent-time");
- intSettingAlias(0, "timeout", "number of seconds before a build is killed", "timeout");
+ mkFlag(0, "show-trace", "show Nix expression stack trace in evaluation errors",
+ &settings.showTrace);
- mkFlag(0, "readonly-mode", "do not write to the Nix store",
- &settings.readOnlyMode);
+ mkFlag(0, "no-gc-warning", "disable warning about not using '--add-root'",
+ &gcWarning, false);
+}
- mkFlag(0, "show-trace", "show Nix expression stack trace in evaluation errors",
- &settings.showTrace);
- mkFlag(0, "no-gc-warning", "disable warning about not using '--add-root'",
- &gcWarning, false);
- }
+bool LegacyArgs::processFlag(Strings::iterator & pos, Strings::iterator end)
+{
+ if (MixCommonArgs::processFlag(pos, end)) return true;
+ bool res = parseArg(pos, end);
+ if (res) ++pos;
+ return res;
+}
- bool processFlag(Strings::iterator & pos, Strings::iterator end) override
- {
- if (MixCommonArgs::processFlag(pos, end)) return true;
- bool res = parseArg(pos, end);
- if (res) ++pos;
- return res;
- }
- bool processArgs(const Strings & args, bool finish) override
- {
- if (args.empty()) return true;
- assert(args.size() == 1);
- Strings ss(args);
- auto pos = ss.begin();
- if (!parseArg(pos, ss.end()))
- throw UsageError(format("unexpected argument '%1%'") % args.front());
- return true;
- }
-};
+bool LegacyArgs::processArgs(const Strings & args, bool finish)
+{
+ if (args.empty()) return true;
+ assert(args.size() == 1);
+ Strings ss(args);
+ auto pos = ss.begin();
+ if (!parseArg(pos, ss.end()))
+ throw UsageError(format("unexpected argument '%1%'") % args.front());
+ return true;
+}
void parseCmdLine(int argc, char * * argv,
diff --git a/src/libmain/shared.hh b/src/libmain/shared.hh
index 2a1e42dd9..9219dbed8 100644
--- a/src/libmain/shared.hh
+++ b/src/libmain/shared.hh
@@ -2,6 +2,7 @@
#include "util.hh"
#include "args.hh"
+#include "common-args.hh"
#include <signal.h>
@@ -69,6 +70,19 @@ template<class N> N getIntArg(const string & opt,
}
+struct LegacyArgs : public MixCommonArgs
+{
+ std::function<bool(Strings::iterator & arg, const Strings::iterator & end)> parseArg;
+
+ LegacyArgs(const std::string & programName,
+ std::function<bool(Strings::iterator & arg, const Strings::iterator & end)> parseArg);
+
+ bool processFlag(Strings::iterator & pos, Strings::iterator end) override;
+
+ bool processArgs(const Strings & args, bool finish) override;
+};
+
+
/* Show the manual page for the specified program. */
void showManPage(const string & name);
diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc
index bef2510d9..4fa02f920 100644
--- a/src/libstore/globals.cc
+++ b/src/libstore/globals.cc
@@ -116,17 +116,17 @@ template<> void BaseSetting<SandboxMode>::convertToArg(Args & args, const std::s
args.mkFlag()
.longName(name)
.description("Enable sandboxing.")
- .handler([=](Strings ss) { value = smEnabled; })
+ .handler([=](std::vector<std::string> ss) { value = smEnabled; })
.category(category);
args.mkFlag()
.longName("no-" + name)
.description("Disable sandboxing.")
- .handler([=](Strings ss) { value = smDisabled; })
+ .handler([=](std::vector<std::string> ss) { value = smDisabled; })
.category(category);
args.mkFlag()
.longName("relaxed-" + name)
.description("Enable sandboxing, but allow builds to disable it.")
- .handler([=](Strings ss) { value = smRelaxed; })
+ .handler([=](std::vector<std::string> ss) { value = smRelaxed; })
.category(category);
}
diff --git a/src/libutil/args.cc b/src/libutil/args.cc
index d17a1e7a9..7af2a1bf7 100644
--- a/src/libutil/args.cc
+++ b/src/libutil/args.cc
@@ -100,7 +100,7 @@ bool Args::processFlag(Strings::iterator & pos, Strings::iterator end)
auto process = [&](const std::string & name, const Flag & flag) -> bool {
++pos;
- Strings args;
+ std::vector<std::string> args;
for (size_t n = 0 ; n < flag.arity; ++n) {
if (pos == end) {
if (flag.arity == ArityAny) break;
@@ -109,7 +109,7 @@ bool Args::processFlag(Strings::iterator & pos, Strings::iterator end)
}
args.push_back(*pos++);
}
- flag.handler(args);
+ flag.handler(std::move(args));
return true;
};
@@ -144,7 +144,9 @@ bool Args::processArgs(const Strings & args, bool finish)
if ((exp.arity == 0 && finish) ||
(exp.arity > 0 && args.size() == exp.arity))
{
- exp.handler(args);
+ std::vector<std::string> ss;
+ for (auto & s : args) ss.push_back(s);
+ exp.handler(std::move(ss));
expectedArgs.pop_front();
res = true;
}
@@ -155,13 +157,17 @@ bool Args::processArgs(const Strings & args, bool finish)
return res;
}
-void Args::mkHashTypeFlag(const std::string & name, HashType * ht)
+Args::FlagMaker & Args::FlagMaker::mkHashTypeFlag(HashType * ht)
{
- mkFlag1(0, name, "TYPE", "hash algorithm ('md5', 'sha1', 'sha256', or 'sha512')", [=](std::string s) {
+ arity(1);
+ label("type");
+ description("hash algorithm ('md5', 'sha1', 'sha256', or 'sha512')");
+ handler([ht](std::string s) {
*ht = parseHashType(s);
if (*ht == htUnknown)
- throw UsageError(format("unknown hash type '%1%'") % s);
+ throw UsageError("unknown hash type '%1%'", s);
});
+ return *this;
}
Strings argvToStrings(int argc, char * * argv)
diff --git a/src/libutil/args.hh b/src/libutil/args.hh
index 37e31825a..ad5fcca39 100644
--- a/src/libutil/args.hh
+++ b/src/libutil/args.hh
@@ -37,7 +37,7 @@ protected:
std::string description;
Strings labels;
size_t arity = 0;
- std::function<void(Strings)> handler;
+ std::function<void(std::vector<std::string>)> handler;
std::string category;
};
@@ -54,7 +54,7 @@ protected:
std::string label;
size_t arity; // 0 = any
bool optional;
- std::function<void(Strings)> handler;
+ std::function<void(std::vector<std::string>)> handler;
};
std::list<ExpectedArg> expectedArgs;
@@ -76,24 +76,35 @@ public:
FlagMaker & longName(const std::string & s) { flag->longName = s; return *this; };
FlagMaker & shortName(char s) { flag->shortName = s; return *this; };
FlagMaker & description(const std::string & s) { flag->description = s; return *this; };
- FlagMaker & labels(const Strings & ls) { flag->labels = ls; return *this; };
+ FlagMaker & label(const std::string & l) { flag->arity = 1; flag->labels = {l}; return *this; };
+ FlagMaker & labels(const Strings & ls) { flag->arity = ls.size(); flag->labels = ls; return *this; };
FlagMaker & arity(size_t arity) { flag->arity = arity; return *this; };
- FlagMaker & handler(std::function<void(Strings)> handler) { flag->handler = handler; return *this; };
+ FlagMaker & handler(std::function<void(std::vector<std::string>)> handler) { flag->handler = handler; return *this; };
+ FlagMaker & handler(std::function<void()> handler) { flag->handler = [handler](std::vector<std::string>) { handler(); }; return *this; };
+ FlagMaker & handler(std::function<void(std::string)> handler) {
+ flag->arity = 1;
+ flag->handler = [handler](std::vector<std::string> ss) { handler(std::move(ss[0])); };
+ return *this;
+ };
FlagMaker & category(const std::string & s) { flag->category = s; return *this; };
template<class T>
- FlagMaker & dest(T * dest) {
+ FlagMaker & dest(T * dest)
+ {
flag->arity = 1;
- flag->handler = [=](Strings ss) { *dest = ss.front(); };
+ flag->handler = [=](std::vector<std::string> ss) { *dest = ss[0]; };
return *this;
};
template<class T>
- FlagMaker & set(T * dest, const T & val) {
+ FlagMaker & set(T * dest, const T & val)
+ {
flag->arity = 0;
- flag->handler = [=](Strings ss) { *dest = val; };
+ flag->handler = [=](std::vector<std::string> ss) { *dest = val; };
return *this;
};
+
+ FlagMaker & mkHashTypeFlag(HashType * ht);
};
FlagMaker mkFlag();
@@ -101,16 +112,6 @@ public:
/* Helper functions for constructing flags / positional
arguments. */
- void mkFlag(char shortName, const std::string & longName,
- const std::string & description, std::function<void()> fun)
- {
- mkFlag()
- .shortName(shortName)
- .longName(longName)
- .description(description)
- .handler(std::bind(fun));
- }
-
void mkFlag1(char shortName, const std::string & longName,
const std::string & label, const std::string & description,
std::function<void(std::string)> fun)
@@ -121,7 +122,7 @@ public:
.labels({label})
.description(description)
.arity(1)
- .handler([=](Strings ss) { fun(ss.front()); });
+ .handler([=](std::vector<std::string> ss) { fun(ss[0]); });
}
void mkFlag(char shortName, const std::string & name,
@@ -130,17 +131,6 @@ public:
mkFlag(shortName, name, description, dest, true);
}
- void mkFlag(char shortName, const std::string & longName,
- const std::string & label, const std::string & description,
- string * dest)
- {
- mkFlag1(shortName, longName, label, description, [=](std::string s) {
- *dest = s;
- });
- }
-
- void mkHashTypeFlag(const std::string & name, HashType * ht);
-
template<class T>
void mkFlag(char shortName, const std::string & longName, const std::string & description,
T * dest, const T & value)
@@ -149,7 +139,7 @@ public:
.shortName(shortName)
.longName(longName)
.description(description)
- .handler([=](Strings ss) { *dest = value; });
+ .handler([=](std::vector<std::string> ss) { *dest = value; });
}
template<class I>
@@ -171,10 +161,10 @@ public:
.labels({"N"})
.description(description)
.arity(1)
- .handler([=](Strings ss) {
+ .handler([=](std::vector<std::string> ss) {
I n;
- if (!string2Int(ss.front(), n))
- throw UsageError(format("flag '--%1%' requires a integer argument") % longName);
+ if (!string2Int(ss[0], n))
+ throw UsageError("flag '--%s' requires a integer argument", longName);
fun(n);
});
}
@@ -182,16 +172,16 @@ public:
/* Expect a string argument. */
void expectArg(const std::string & label, string * dest, bool optional = false)
{
- expectedArgs.push_back(ExpectedArg{label, 1, optional, [=](Strings ss) {
- *dest = ss.front();
+ expectedArgs.push_back(ExpectedArg{label, 1, optional, [=](std::vector<std::string> ss) {
+ *dest = ss[0];
}});
}
/* Expect 0 or more arguments. */
- void expectArgs(const std::string & label, Strings * dest)
+ void expectArgs(const std::string & label, std::vector<std::string> * dest)
{
- expectedArgs.push_back(ExpectedArg{label, 0, false, [=](Strings ss) {
- *dest = ss;
+ expectedArgs.push_back(ExpectedArg{label, 0, false, [=](std::vector<std::string> ss) {
+ *dest = std::move(ss);
}});
}
diff --git a/src/libutil/config.cc b/src/libutil/config.cc
index 27157a831..14c4cca03 100644
--- a/src/libutil/config.cc
+++ b/src/libutil/config.cc
@@ -152,7 +152,7 @@ void BaseSetting<T>::convertToArg(Args & args, const std::string & category)
.longName(name)
.description(description)
.arity(1)
- .handler([=](Strings ss) { set(*ss.begin()); })
+ .handler([=](std::vector<std::string> ss) { set(ss[0]); })
.category(category);
}
@@ -201,12 +201,12 @@ template<> void BaseSetting<bool>::convertToArg(Args & args, const std::string &
args.mkFlag()
.longName(name)
.description(description)
- .handler([=](Strings ss) { value = true; })
+ .handler([=](std::vector<std::string> ss) { value = true; })
.category(category);
args.mkFlag()
.longName("no-" + name)
.description(description)
- .handler([=](Strings ss) { value = false; })
+ .handler([=](std::vector<std::string> ss) { value = false; })
.category(category);
}
diff --git a/src/nix-build/nix-build.cc b/src/nix-build/nix-build.cc
index 4541c89a7..85137206f 100755
--- a/src/nix-build/nix-build.cc
+++ b/src/nix-build/nix-build.cc
@@ -14,7 +14,7 @@
#include "eval.hh"
#include "eval-inline.hh"
#include "get-drvs.hh"
-#include "common-opts.hh"
+#include "common-eval-args.hh"
#include "attr-path.hh"
using namespace nix;
@@ -80,8 +80,6 @@ void mainWrapped(int argc, char * * argv)
auto interactive = isatty(STDIN_FILENO) && isatty(STDERR_FILENO);
Strings attrPaths;
Strings left;
- Strings searchPath;
- std::map<string, string> autoArgs_;
RepairFlag repair = NoRepair;
Path gcRoot;
BuildMode buildMode = bmNormal;
@@ -129,7 +127,12 @@ void mainWrapped(int argc, char * * argv)
} catch (SysError &) { }
}
- parseCmdLine(myName, args, [&](Strings::iterator & arg, const Strings::iterator & end) {
+ struct MyArgs : LegacyArgs, MixEvalArgs
+ {
+ using LegacyArgs::LegacyArgs;
+ };
+
+ MyArgs myArgs(myName, [&](Strings::iterator & arg, const Strings::iterator & end) {
if (*arg == "--help") {
deletePath(tmpDir);
showManPage(myName);
@@ -153,12 +156,6 @@ void mainWrapped(int argc, char * * argv)
else if (*arg == "--out-link" || *arg == "-o")
outLink = getArg(*arg, arg, end);
- else if (parseAutoArgs(arg, end, autoArgs_))
- ;
-
- else if (parseSearchPathArg(arg, end, searchPath))
- ;
-
else if (*arg == "--add-root")
gcRoot = getArg(*arg, arg, end);
@@ -237,15 +234,17 @@ void mainWrapped(int argc, char * * argv)
return true;
});
+ myArgs.parseCmdline(args);
+
if (packages && fromArgs)
throw UsageError("'-p' and '-E' are mutually exclusive");
auto store = openStore();
- EvalState state(searchPath, store);
+ EvalState state(myArgs.searchPath, store);
state.repair = repair;
- Bindings & autoArgs(*evalAutoArgs(state, autoArgs_));
+ Bindings & autoArgs = *myArgs.getAutoArgs(state);
if (packages) {
std::ostringstream joined;
diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc
index 94fbc09f6..016caf6d2 100644
--- a/src/nix-env/nix-env.cc
+++ b/src/nix-env/nix-env.cc
@@ -1,5 +1,5 @@
#include "attr-path.hh"
-#include "common-opts.hh"
+#include "common-eval-args.hh"
#include "derivations.hh"
#include "eval.hh"
#include "get-drvs.hh"
@@ -1309,8 +1309,7 @@ int main(int argc, char * * argv)
initNix();
initGC();
- Strings opFlags, opArgs, searchPath;
- std::map<string, string> autoArgs_;
+ Strings opFlags, opArgs;
Operation op = 0;
RepairFlag repair = NoRepair;
string file;
@@ -1326,7 +1325,12 @@ int main(int argc, char * * argv)
globals.removeAll = false;
globals.prebuiltOnly = false;
- parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) {
+ struct MyArgs : LegacyArgs, MixEvalArgs
+ {
+ using LegacyArgs::LegacyArgs;
+ };
+
+ MyArgs myArgs(baseNameOf(argv[0]), [&](Strings::iterator & arg, const Strings::iterator & end) {
Operation oldOp = op;
if (*arg == "--help")
@@ -1335,10 +1339,6 @@ int main(int argc, char * * argv)
op = opVersion;
else if (*arg == "--install" || *arg == "-i")
op = opInstall;
- else if (parseAutoArgs(arg, end, autoArgs_))
- ;
- else if (parseSearchPathArg(arg, end, searchPath))
- ;
else if (*arg == "--force-name") // undocumented flag for nix-install-package
globals.forceName = getArg(*arg, arg, end);
else if (*arg == "--uninstall" || *arg == "-e")
@@ -1391,17 +1391,19 @@ int main(int argc, char * * argv)
return true;
});
+ myArgs.parseCmdline(argvToStrings(argc, argv));
+
if (!op) throw UsageError("no operation specified");
auto store = openStore();
- globals.state = std::shared_ptr<EvalState>(new EvalState(searchPath, store));
+ globals.state = std::shared_ptr<EvalState>(new EvalState(myArgs.searchPath, store));
globals.state->repair = repair;
if (file != "")
globals.instSource.nixExprPath = lookupFileArg(*globals.state, file);
- globals.instSource.autoArgs = evalAutoArgs(*globals.state, autoArgs_);
+ globals.instSource.autoArgs = myArgs.getAutoArgs(*globals.state);
if (globals.profile == "")
globals.profile = getEnv("NIX_PROFILE", "");
diff --git a/src/nix-instantiate/nix-instantiate.cc b/src/nix-instantiate/nix-instantiate.cc
index 2498df0f0..55ac007e8 100644
--- a/src/nix-instantiate/nix-instantiate.cc
+++ b/src/nix-instantiate/nix-instantiate.cc
@@ -8,7 +8,7 @@
#include "value-to-json.hh"
#include "util.hh"
#include "store-api.hh"
-#include "common-opts.hh"
+#include "common-eval-args.hh"
#include <map>
#include <iostream>
@@ -89,7 +89,7 @@ int main(int argc, char * * argv)
initNix();
initGC();
- Strings files, searchPath;
+ Strings files;
bool readStdin = false;
bool fromArgs = false;
bool findFile = false;
@@ -100,10 +100,14 @@ int main(int argc, char * * argv)
bool strict = false;
Strings attrPaths;
bool wantsReadWrite = false;
- std::map<string, string> autoArgs_;
RepairFlag repair = NoRepair;
- parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) {
+ struct MyArgs : LegacyArgs, MixEvalArgs
+ {
+ using LegacyArgs::LegacyArgs;
+ };
+
+ MyArgs myArgs(baseNameOf(argv[0]), [&](Strings::iterator & arg, const Strings::iterator & end) {
if (*arg == "--help")
showManPage("nix-instantiate");
else if (*arg == "--version")
@@ -122,10 +126,6 @@ int main(int argc, char * * argv)
findFile = true;
else if (*arg == "--attr" || *arg == "-A")
attrPaths.push_back(getArg(*arg, arg, end));
- else if (parseAutoArgs(arg, end, autoArgs_))
- ;
- else if (parseSearchPathArg(arg, end, searchPath))
- ;
else if (*arg == "--add-root")
gcRoot = getArg(*arg, arg, end);
else if (*arg == "--indirect")
@@ -149,15 +149,17 @@ int main(int argc, char * * argv)
return true;
});
+ myArgs.parseCmdline(argvToStrings(argc, argv));
+
if (evalOnly && !wantsReadWrite)
settings.readOnlyMode = true;
auto store = openStore();
- EvalState state(searchPath, store);
+ EvalState state(myArgs.searchPath, store);
state.repair = repair;
- Bindings & autoArgs(*evalAutoArgs(state, autoArgs_));
+ Bindings & autoArgs = *myArgs.getAutoArgs(state);
if (attrPaths.empty()) attrPaths = {""};
diff --git a/src/nix-prefetch-url/nix-prefetch-url.cc b/src/nix-prefetch-url/nix-prefetch-url.cc
index 7e62a033b..fef3eaa45 100644
--- a/src/nix-prefetch-url/nix-prefetch-url.cc
+++ b/src/nix-prefetch-url/nix-prefetch-url.cc
@@ -4,7 +4,7 @@
#include "store-api.hh"
#include "eval.hh"
#include "eval-inline.hh"
-#include "common-opts.hh"
+#include "common-eval-args.hh"
#include "attr-path.hh"
#include <iostream>
@@ -48,15 +48,18 @@ int main(int argc, char * * argv)
HashType ht = htSHA256;
std::vector<string> args;
- Strings searchPath;
bool printPath = getEnv("PRINT_PATH") != "";
bool fromExpr = false;
string attrPath;
- std::map<string, string> autoArgs_;
bool unpack = false;
string name;
- parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) {
+ struct MyArgs : LegacyArgs, MixEvalArgs
+ {
+ using LegacyArgs::LegacyArgs;
+ };
+
+ MyArgs myArgs(baseNameOf(argv[0]), [&](Strings::iterator & arg, const Strings::iterator & end) {
if (*arg == "--help")
showManPage("nix-prefetch-url");
else if (*arg == "--version")
@@ -77,10 +80,6 @@ int main(int argc, char * * argv)
unpack = true;
else if (*arg == "--name")
name = getArg(*arg, arg, end);
- else if (parseAutoArgs(arg, end, autoArgs_))
- ;
- else if (parseSearchPathArg(arg, end, searchPath))
- ;
else if (*arg != "" && arg->at(0) == '-')
return false;
else
@@ -88,13 +87,15 @@ int main(int argc, char * * argv)
return true;
});
+ myArgs.parseCmdline(argvToStrings(argc, argv));
+
if (args.size() > 2)
throw UsageError("too many arguments");
auto store = openStore();
- EvalState state(searchPath, store);
+ EvalState state(myArgs.searchPath, store);
- Bindings & autoArgs(*evalAutoArgs(state, autoArgs_));
+ Bindings & autoArgs = *myArgs.getAutoArgs(state);
/* If -A is given, get the URI from the specified Nix
expression. */
diff --git a/src/nix/command.cc b/src/nix/command.cc
index 70d642605..1e6f0d2bb 100644
--- a/src/nix/command.cc
+++ b/src/nix/command.cc
@@ -24,11 +24,11 @@ void Command::printHelp(const string & programName, std::ostream & out)
MultiCommand::MultiCommand(const Commands & _commands)
: commands(_commands)
{
- expectedArgs.push_back(ExpectedArg{"command", 1, true, [=](Strings ss) {
+ expectedArgs.push_back(ExpectedArg{"command", 1, true, [=](std::vector<std::string> ss) {
assert(!command);
- auto i = commands.find(ss.front());
+ auto i = commands.find(ss[0]);
if (i == commands.end())
- throw UsageError(format("'%1%' is not a recognised command") % ss.front());
+ throw UsageError("'%s' is not a recognised command", ss[0]);
command = i->second;
}});
}
diff --git a/src/nix/command.hh b/src/nix/command.hh
index 77ca8cfb6..daa3b3fa7 100644
--- a/src/nix/command.hh
+++ b/src/nix/command.hh
@@ -1,10 +1,12 @@
#pragma once
#include "args.hh"
+#include "common-eval-args.hh"
namespace nix {
struct Value;
+struct Bindings;
class EvalState;
/* A command is an argument parser that can be executed by calling its
@@ -68,14 +70,11 @@ struct Installable
}
};
-struct SourceExprCommand : virtual Args, StoreCommand
+struct SourceExprCommand : virtual Args, StoreCommand, MixEvalArgs
{
Path file;
- SourceExprCommand()
- {
- mkFlag('f', "file", "file", "evaluate FILE rather than the default", &file);
- }
+ SourceExprCommand();
/* Return a value representing the Nix expression from which we
are installing. This is either the file specified by ‘--file’,
@@ -111,7 +110,7 @@ struct InstallablesCommand : virtual Args, SourceExprCommand
private:
- Strings _installables;
+ std::vector<std::string> _installables;
};
struct InstallableCommand : virtual Args, SourceExprCommand
diff --git a/src/nix/copy.cc b/src/nix/copy.cc
index 071ac3890..2ddea9e70 100644
--- a/src/nix/copy.cc
+++ b/src/nix/copy.cc
@@ -19,8 +19,16 @@ struct CmdCopy : StorePathsCommand
CmdCopy()
: StorePathsCommand(true)
{
- mkFlag(0, "from", "store-uri", "URI of the source Nix store", &srcUri);
- mkFlag(0, "to", "store-uri", "URI of the destination Nix store", &dstUri);
+ mkFlag()
+ .longName("from")
+ .labels({"store-uri"})
+ .description("URI of the source Nix store")
+ .dest(&srcUri);
+ mkFlag()
+ .longName("to")
+ .labels({"store-uri"})
+ .description("URI of the destination Nix store")
+ .dest(&dstUri);
mkFlag()
.longName("no-check-sigs")
diff --git a/src/nix/hash.cc b/src/nix/hash.cc
index 923dabb10..64062fb97 100644
--- a/src/nix/hash.cc
+++ b/src/nix/hash.cc
@@ -12,14 +12,16 @@ struct CmdHash : Command
Base base = Base16;
bool truncate = false;
HashType ht = htSHA512;
- Strings paths;
+ std::vector<std::string> paths;
CmdHash(Mode mode) : mode(mode)
{
mkFlag(0, "base64", "print hash in base-64", &base, Base64);
mkFlag(0, "base32", "print hash in base-32 (Nix-specific)", &base, Base32);
mkFlag(0, "base16", "print hash in base-16", &base, Base16);
- mkHashTypeFlag("type", &ht);
+ mkFlag()
+ .longName("type")
+ .mkHashTypeFlag(&ht);
expectArgs("paths", &paths);
}
@@ -53,11 +55,13 @@ struct CmdToBase : Command
{
Base base;
HashType ht = htSHA512;
- Strings args;
+ std::vector<std::string> args;
CmdToBase(Base base) : base(base)
{
- mkHashTypeFlag("type", &ht);
+ mkFlag()
+ .longName("type")
+ .mkHashTypeFlag(&ht);
expectArgs("strings", &args);
}
@@ -95,7 +99,7 @@ static int compatNixHash(int argc, char * * argv)
bool base32 = false;
bool truncate = false;
enum { opHash, opTo32, opTo16 } op = opHash;
- Strings ss;
+ std::vector<std::string> ss;
parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) {
if (*arg == "--help")
diff --git a/src/nix/installables.cc b/src/nix/installables.cc
index c83d6316d..ae93c4ef6 100644
--- a/src/nix/installables.cc
+++ b/src/nix/installables.cc
@@ -1,6 +1,6 @@
#include "command.hh"
#include "attr-path.hh"
-#include "common-opts.hh"
+#include "common-eval-args.hh"
#include "derivations.hh"
#include "eval-inline.hh"
#include "eval.hh"
@@ -12,6 +12,16 @@
namespace nix {
+SourceExprCommand::SourceExprCommand()
+{
+ mkFlag()
+ .shortName('f')
+ .longName("file")
+ .label("file")
+ .description("evaluate FILE rather than the default")
+ .dest(&file);
+}
+
Value * SourceExprCommand::getSourceExpr(EvalState & state)
{
if (vSourceExpr) return vSourceExpr;
@@ -66,7 +76,7 @@ Value * SourceExprCommand::getSourceExpr(EvalState & state)
ref<EvalState> SourceExprCommand::getEvalState()
{
if (!evalState)
- evalState = std::make_shared<EvalState>(Strings{}, getStore());
+ evalState = std::make_shared<EvalState>(searchPath, getStore());
return ref<EvalState>(evalState);
}
@@ -120,9 +130,7 @@ struct InstallableValue : Installable
auto v = toValue(*state);
- // FIXME
- std::map<string, string> autoArgs_;
- Bindings & autoArgs(*evalAutoArgs(*state, autoArgs_));
+ Bindings & autoArgs = *cmd.getAutoArgs(*state);
DrvInfos drvs;
getDerivations(*state, *v, "", autoArgs, drvs, false);
@@ -187,9 +195,7 @@ struct InstallableAttrPath : InstallableValue
{
auto source = cmd.getSourceExpr(state);
- // FIXME
- std::map<string, string> autoArgs_;
- Bindings & autoArgs(*evalAutoArgs(state, autoArgs_));
+ Bindings & autoArgs = *cmd.getAutoArgs(state);
Value * v = findAlongAttrPath(state, attrPath, autoArgs, *source);
state.forceValue(*v);
@@ -203,14 +209,14 @@ std::string attrRegex = R"([A-Za-z_][A-Za-z0-9-_+]*)";
static std::regex attrPathRegex(fmt(R"(%1%(\.%1%)*)", attrRegex));
static std::vector<std::shared_ptr<Installable>> parseInstallables(
- SourceExprCommand & cmd, ref<Store> store, Strings ss, bool useDefaultInstallables)
+ SourceExprCommand & cmd, ref<Store> store, std::vector<std::string> ss, bool useDefaultInstallables)
{
std::vector<std::shared_ptr<Installable>> result;
if (ss.empty() && useDefaultInstallables) {
if (cmd.file == "")
cmd.file = ".";
- ss = Strings{""};
+ ss = {""};
}
for (auto & s : ss) {
diff --git a/src/nix/main.cc b/src/nix/main.cc
index ec9b58b20..060402cd0 100644
--- a/src/nix/main.cc
+++ b/src/nix/main.cc
@@ -20,19 +20,29 @@ struct NixArgs : virtual MultiCommand, virtual MixCommonArgs
{
NixArgs() : MultiCommand(*RegisterCommand::commands), MixCommonArgs("nix")
{
- mkFlag('h', "help", "show usage information", [&]() { showHelpAndExit(); });
-
- mkFlag(0, "help-config", "show configuration options", [=]() {
- std::cout << "The following configuration options are available:\n\n";
- Table2 tbl;
- for (const auto & s : settings._getSettings())
- if (!s.second.isAlias)
- tbl.emplace_back(s.first, s.second.setting->description);
- printTable(std::cout, tbl);
- throw Exit();
- });
-
- mkFlag(0, "version", "show version information", std::bind(printVersion, programName));
+ mkFlag()
+ .longName("help")
+ .shortName('h')
+ .description("show usage information")
+ .handler([&]() { showHelpAndExit(); });
+
+ mkFlag()
+ .longName("help-config")
+ .description("show configuration options")
+ .handler([&]() {
+ std::cout << "The following configuration options are available:\n\n";
+ Table2 tbl;
+ for (const auto & s : settings._getSettings())
+ if (!s.second.isAlias)
+ tbl.emplace_back(s.first, s.second.setting->description);
+ printTable(std::cout, tbl);
+ throw Exit();
+ });
+
+ mkFlag()
+ .longName("version")
+ .description("show version information")
+ .handler([&]() { printVersion(programName); });
std::string cat = "config";
settings.convertToArgs(*this, cat);
diff --git a/src/nix/repl.cc b/src/nix/repl.cc
index 781b4463e..28a8ebc8c 100644
--- a/src/nix/repl.cc
+++ b/src/nix/repl.cc
@@ -7,7 +7,7 @@
#include "eval.hh"
#include "eval-inline.hh"
#include "store-api.hh"
-#include "common-opts.hh"
+#include "common-eval-args.hh"
#include "get-drvs.hh"
#include "derivations.hh"
#include "affinity.hh"
@@ -44,7 +44,7 @@ struct NixRepl
NixRepl(const Strings & searchPath, nix::ref<Store> store);
~NixRepl();
- void mainLoop(const Strings & files);
+ void mainLoop(const std::vector<std::string> & files);
StringSet completePrefix(string prefix);
bool getLine(string & input, const std::string &prompt);
Path getDerivationPath(Value & v);
@@ -131,7 +131,7 @@ static void completionCallback(const char * s, linenoiseCompletions *lc)
}
-void NixRepl::mainLoop(const Strings & files)
+void NixRepl::mainLoop(const std::vector<std::string> & files)
{
string error = ANSI_RED "error:" ANSI_NORMAL " ";
std::cout << "Welcome to Nix version " << nixVersion << ". Type :? for help." << std::endl << std::endl;
@@ -664,9 +664,9 @@ std::ostream & NixRepl::printValue(std::ostream & str, Value & v, unsigned int m
return str;
}
-struct CmdRepl : StoreCommand
+struct CmdRepl : StoreCommand, MixEvalArgs
{
- Strings files;
+ std::vector<std::string> files;
CmdRepl()
{
@@ -682,8 +682,7 @@ struct CmdRepl : StoreCommand
void run(ref<Store> store) override
{
- // FIXME: pass searchPath
- NixRepl repl({}, openStore());
+ NixRepl repl(searchPath, openStore());
repl.mainLoop(files);
}
};
diff --git a/src/nix/run.cc b/src/nix/run.cc
index 2f93ca351..6657a8631 100644
--- a/src/nix/run.cc
+++ b/src/nix/run.cc
@@ -20,7 +20,7 @@ extern char * * environ;
struct CmdRun : InstallablesCommand
{
- Strings command = { "bash" };
+ std::vector<std::string> command = { "bash" };
StringSet keep, unset;
bool ignoreEnvironment = false;
@@ -32,7 +32,7 @@ struct CmdRun : InstallablesCommand
.description("command and arguments to be executed; defaults to 'bash'")
.arity(ArityAny)
.labels({"command", "args"})
- .handler([&](Strings ss) {
+ .handler([&](std::vector<std::string> ss) {
if (ss.empty()) throw UsageError("--command requires at least one argument");
command = ss;
});
@@ -49,7 +49,7 @@ struct CmdRun : InstallablesCommand
.description("keep specified environment variable")
.arity(1)
.labels({"name"})
- .handler([&](Strings ss) { keep.insert(ss.front()); });
+ .handler([&](std::vector<std::string> ss) { keep.insert(ss.front()); });
mkFlag()
.longName("unset")
@@ -57,7 +57,7 @@ struct CmdRun : InstallablesCommand
.description("unset specified environment variable")
.arity(1)
.labels({"name"})
- .handler([&](Strings ss) { unset.insert(ss.front()); });
+ .handler([&](std::vector<std::string> ss) { unset.insert(ss.front()); });
}
std::string name() override
@@ -126,7 +126,8 @@ struct CmdRun : InstallablesCommand
setenv("PATH", concatStringsSep(":", unixPath).c_str(), 1);
std::string cmd = *command.begin();
- Strings args = command;
+ Strings args;
+ for (auto & arg : command) args.push_back(arg);
stopProgressBar();
diff --git a/src/nix/search.cc b/src/nix/search.cc
index 9476b79fb..f458367dc 100644
--- a/src/nix/search.cc
+++ b/src/nix/search.cc
@@ -38,12 +38,12 @@ struct CmdSearch : SourceExprCommand, MixJSON
.longName("update-cache")
.shortName('u')
.description("update the package search cache")
- .handler([&](Strings ss) { writeCache = true; useCache = false; });
+ .handler([&]() { writeCache = true; useCache = false; });
mkFlag()
.longName("no-cache")
.description("do not use or update the package search cache")
- .handler([&](Strings ss) { writeCache = false; useCache = false; });
+ .handler([&]() { writeCache = false; useCache = false; });
}
std::string name() override
diff --git a/src/nix/sigs.cc b/src/nix/sigs.cc
index 992ff7428..b1825c412 100644
--- a/src/nix/sigs.cc
+++ b/src/nix/sigs.cc
@@ -19,7 +19,7 @@ struct CmdCopySigs : StorePathsCommand
.labels({"store-uri"})
.description("use signatures from specified store")
.arity(1)
- .handler([&](Strings ss) { substituterUris.push_back(ss.front()); });
+ .handler([&](std::vector<std::string> ss) { substituterUris.push_back(ss[0]); });
}
std::string name() override
@@ -101,7 +101,12 @@ struct CmdSignPaths : StorePathsCommand
CmdSignPaths()
{
- mkFlag('k', "key-file", {"file"}, "file containing the secret signing key", &secretKeyFile);
+ mkFlag()
+ .shortName('k')
+ .longName("key-file")
+ .label("file")
+ .description("file containing the secret signing key")
+ .dest(&secretKeyFile);
}
std::string name() override
diff --git a/src/nix/verify.cc b/src/nix/verify.cc
index 4913d9900..6540208a8 100644
--- a/src/nix/verify.cc
+++ b/src/nix/verify.cc
@@ -25,7 +25,7 @@ struct CmdVerify : StorePathsCommand
.labels({"store-uri"})
.description("use signatures from specified store")
.arity(1)
- .handler([&](Strings ss) { substituterUris.push_back(ss.front()); });
+ .handler([&](std::vector<std::string> ss) { substituterUris.push_back(ss[0]); });
mkIntFlag('n', "sigs-needed", "require that each path has at least N valid signatures", &sigsNeeded);
}