nix: Respect -I, --arg, --argstr

Also, random cleanup to argument handling.
This commit is contained in:
Eelco Dolstra 2017-10-24 12:45:11 +02:00
parent 25f32625e2
commit 0d59f1ca49
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
26 changed files with 349 additions and 299 deletions

View file

@ -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;
}});
}

View file

@ -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

View file

@ -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")

View file

@ -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")

View file

@ -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) {

View file

@ -20,19 +20,29 @@ struct NixArgs : virtual MultiCommand, virtual MixCommonArgs
{
NixArgs() : MultiCommand(*RegisterCommand::commands), MixCommonArgs("nix")
{
mkFlag('h', "help", "show usage information", [&]() { showHelpAndExit(); });
mkFlag()
.longName("help")
.shortName('h')
.description("show usage information")
.handler([&]() { 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()
.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(0, "version", "show version information", std::bind(printVersion, programName));
mkFlag()
.longName("version")
.description("show version information")
.handler([&]() { printVersion(programName); });
std::string cat = "config";
settings.convertToArgs(*this, cat);

View file

@ -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);
}
};

View file

@ -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();

View file

@ -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

View file

@ -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

View file

@ -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);
}