cli infra: modernize legacy command interface
give legacy commands their program name and c++-converted argv directly
instead of passing on the (argc, argv) pair untouched. all are required
to process these things, and all of them do it in exactly the same way.
we can also remove a few old helpers only used to make this less awful.
Change-Id: I4ecd02343bca0cf85faf6fe043031d4f64c5f29c
This commit is contained in:
parent
c4a077d0b8
commit
9cf91b7385
|
@ -55,7 +55,7 @@ static bool allSupportedLocally(Store & store, const std::set<std::string>& requ
|
|||
return true;
|
||||
}
|
||||
|
||||
static int main_build_remote(int argc, char * * argv)
|
||||
static int main_build_remote(std::string programName, Strings argv)
|
||||
{
|
||||
{
|
||||
logger = makeJSONLogger(*logger);
|
||||
|
@ -67,10 +67,10 @@ static int main_build_remote(int argc, char * * argv)
|
|||
/* If we ever use the common args framework, make sure to
|
||||
remove initPlugins below and initialize settings first.
|
||||
*/
|
||||
if (argc != 2)
|
||||
if (argv.size() != 1)
|
||||
throw UsageError("called without required arguments");
|
||||
|
||||
verbosity = (Verbosity) std::stoll(argv[1]);
|
||||
verbosity = (Verbosity) std::stoll(argv.front());
|
||||
|
||||
FdSource source(STDIN_FILENO);
|
||||
|
||||
|
|
|
@ -33,10 +33,10 @@ namespace nix {
|
|||
|
||||
using namespace std::string_literals;
|
||||
|
||||
static void main_nix_build(int argc, char * * argv)
|
||||
static void main_nix_build(std::string programName, Strings argv)
|
||||
{
|
||||
auto dryRun = false;
|
||||
auto runEnv = std::regex_search(argv[0], std::regex("nix-shell$"));
|
||||
auto runEnv = std::regex_search(programName, std::regex("nix-shell$"));
|
||||
auto pure = false;
|
||||
auto fromArgs = false;
|
||||
auto packages = false;
|
||||
|
@ -66,29 +66,24 @@ static void main_nix_build(int argc, char * * argv)
|
|||
"http_proxy", "https_proxy", "ftp_proxy", "all_proxy", "no_proxy"
|
||||
};
|
||||
|
||||
Strings args;
|
||||
for (int i = 1; i < argc; ++i)
|
||||
args.push_back(argv[i]);
|
||||
|
||||
// Heuristic to see if we're invoked as a shebang script, namely,
|
||||
// if we have at least one argument, it's the name of an
|
||||
// executable file, and it starts with "#!".
|
||||
if (runEnv && argc > 1) {
|
||||
script = argv[1];
|
||||
if (runEnv && !argv.empty()) {
|
||||
script = argv.front();
|
||||
try {
|
||||
auto lines = tokenizeString<Strings>(readFile(script), "\n");
|
||||
if (std::regex_search(lines.front(), std::regex("^#!"))) {
|
||||
lines.pop_front();
|
||||
inShebang = true;
|
||||
for (int i = 2; i < argc; ++i)
|
||||
savedArgs.push_back(argv[i]);
|
||||
args.clear();
|
||||
savedArgs = {std::next(argv.begin()), argv.end()};
|
||||
argv.clear();
|
||||
for (auto line : lines) {
|
||||
line = chomp(line);
|
||||
std::smatch match;
|
||||
if (std::regex_match(line, match, std::regex("^#!\\s*nix-shell\\s+(.*)$")))
|
||||
for (const auto & word : shell_split(match[1].str()))
|
||||
args.push_back(word);
|
||||
argv.push_back(word);
|
||||
}
|
||||
}
|
||||
} catch (SysError &) { }
|
||||
|
@ -191,7 +186,7 @@ static void main_nix_build(int argc, char * * argv)
|
|||
return true;
|
||||
});
|
||||
|
||||
myArgs.parseCmdline(args);
|
||||
myArgs.parseCmdline(argv);
|
||||
|
||||
if (packages && fromArgs)
|
||||
throw UsageError("'-p' and '-E' are mutually exclusive");
|
||||
|
|
|
@ -162,7 +162,7 @@ static void update(const StringSet & channelNames)
|
|||
replaceSymlink(profile, channelLink);
|
||||
}
|
||||
|
||||
static int main_nix_channel(int argc, char ** argv)
|
||||
static int main_nix_channel(std::string programName, Strings argv)
|
||||
{
|
||||
{
|
||||
// Figure out the name of the `.nix-channels' file to use
|
||||
|
@ -184,7 +184,7 @@ static int main_nix_channel(int argc, char ** argv)
|
|||
cRollback
|
||||
} cmd = cNone;
|
||||
std::vector<std::string> args;
|
||||
parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) {
|
||||
LegacyArgs(programName, [&](Strings::iterator & arg, const Strings::iterator & end) {
|
||||
if (*arg == "--help") {
|
||||
showManPage("nix-channel");
|
||||
} else if (*arg == "--version") {
|
||||
|
@ -207,7 +207,7 @@ static int main_nix_channel(int argc, char ** argv)
|
|||
args.push_back(std::move(*arg));
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}).parseCmdline(argv);
|
||||
|
||||
switch (cmd) {
|
||||
case cNone:
|
||||
|
|
|
@ -56,14 +56,14 @@ void removeOldGenerations(std::string dir)
|
|||
}
|
||||
}
|
||||
|
||||
static int main_nix_collect_garbage(int argc, char * * argv)
|
||||
static int main_nix_collect_garbage(std::string programName, Strings argv)
|
||||
{
|
||||
{
|
||||
bool removeOld = false;
|
||||
|
||||
GCOptions options;
|
||||
|
||||
parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) {
|
||||
LegacyArgs(programName, [&](Strings::iterator & arg, const Strings::iterator & end) {
|
||||
if (*arg == "--help")
|
||||
showManPage("nix-collect-garbage");
|
||||
else if (*arg == "--version")
|
||||
|
@ -79,7 +79,7 @@ static int main_nix_collect_garbage(int argc, char * * argv)
|
|||
else
|
||||
return false;
|
||||
return true;
|
||||
});
|
||||
}).parseCmdline(argv);
|
||||
|
||||
if (removeOld) {
|
||||
std::set<Path> dirsToClean = {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
namespace nix {
|
||||
|
||||
static int main_nix_copy_closure(int argc, char ** argv)
|
||||
static int main_nix_copy_closure(std::string programName, Strings argv)
|
||||
{
|
||||
{
|
||||
auto gzip = false;
|
||||
|
@ -16,7 +16,7 @@ static int main_nix_copy_closure(int argc, char ** argv)
|
|||
std::string sshHost;
|
||||
PathSet storePaths;
|
||||
|
||||
parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) {
|
||||
LegacyArgs(programName, [&](Strings::iterator & arg, const Strings::iterator & end) {
|
||||
if (*arg == "--help")
|
||||
showManPage("nix-copy-closure");
|
||||
else if (*arg == "--version")
|
||||
|
@ -42,7 +42,7 @@ static int main_nix_copy_closure(int argc, char ** argv)
|
|||
else
|
||||
storePaths.insert(*arg);
|
||||
return true;
|
||||
});
|
||||
}).parseCmdline(argv);
|
||||
|
||||
if (sshHost.empty())
|
||||
throw UsageError("no host name specified");
|
||||
|
|
|
@ -1395,7 +1395,7 @@ static void opVersion(Globals & globals, Strings opFlags, Strings opArgs)
|
|||
}
|
||||
|
||||
|
||||
static int main_nix_env(int argc, char * * argv)
|
||||
static int main_nix_env(std::string programName, Strings argv)
|
||||
{
|
||||
{
|
||||
Strings opFlags, opArgs;
|
||||
|
@ -1434,7 +1434,7 @@ static int main_nix_env(int argc, char * * argv)
|
|||
using LegacyArgs::LegacyArgs;
|
||||
};
|
||||
|
||||
MyArgs myArgs(std::string(baseNameOf(argv[0])), [&](Strings::iterator & arg, const Strings::iterator & end) {
|
||||
MyArgs myArgs(programName, [&](Strings::iterator & arg, const Strings::iterator & end) {
|
||||
Operation oldOp = op;
|
||||
|
||||
if (*arg == "--help")
|
||||
|
@ -1515,7 +1515,7 @@ static int main_nix_env(int argc, char * * argv)
|
|||
return true;
|
||||
});
|
||||
|
||||
myArgs.parseCmdline(argvToStrings(argc, argv));
|
||||
myArgs.parseCmdline(argv);
|
||||
|
||||
if (showHelp) showManPage("nix-env" + opName);
|
||||
if (!op) throw UsageError("no operation specified");
|
||||
|
|
|
@ -89,7 +89,7 @@ void processExpr(EvalState & state, const Strings & attrPaths,
|
|||
}
|
||||
|
||||
|
||||
static int main_nix_instantiate(int argc, char * * argv)
|
||||
static int main_nix_instantiate(std::string programName, Strings argv)
|
||||
{
|
||||
{
|
||||
Strings files;
|
||||
|
@ -109,7 +109,7 @@ static int main_nix_instantiate(int argc, char * * argv)
|
|||
using LegacyArgs::LegacyArgs;
|
||||
};
|
||||
|
||||
MyArgs myArgs(std::string(baseNameOf(argv[0])), [&](Strings::iterator & arg, const Strings::iterator & end) {
|
||||
MyArgs myArgs(programName, [&](Strings::iterator & arg, const Strings::iterator & end) {
|
||||
if (*arg == "--help")
|
||||
showManPage("nix-instantiate");
|
||||
else if (*arg == "--version")
|
||||
|
@ -149,7 +149,7 @@ static int main_nix_instantiate(int argc, char * * argv)
|
|||
return true;
|
||||
});
|
||||
|
||||
myArgs.parseCmdline(argvToStrings(argc, argv));
|
||||
myArgs.parseCmdline(argv);
|
||||
|
||||
if (evalOnly && !wantsReadWrite)
|
||||
settings.readOnlyMode = true;
|
||||
|
|
|
@ -1031,7 +1031,7 @@ static void opVersion(Strings opFlags, Strings opArgs)
|
|||
/* Scan the arguments; find the operation, set global flags, put all
|
||||
other flags in a list, and put all other arguments in another
|
||||
list. */
|
||||
static int main_nix_store(int argc, char * * argv)
|
||||
static int main_nix_store(std::string programName, Strings argv)
|
||||
{
|
||||
{
|
||||
Strings opFlags, opArgs;
|
||||
|
@ -1040,7 +1040,7 @@ static int main_nix_store(int argc, char * * argv)
|
|||
std::string opName;
|
||||
bool showHelp = false;
|
||||
|
||||
parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) {
|
||||
LegacyArgs(programName, [&](Strings::iterator & arg, const Strings::iterator & end) {
|
||||
Operation oldOp = op;
|
||||
|
||||
if (*arg == "--help")
|
||||
|
@ -1162,7 +1162,7 @@ static int main_nix_store(int argc, char * * argv)
|
|||
throw UsageError("only one operation may be specified");
|
||||
|
||||
return true;
|
||||
});
|
||||
}).parseCmdline(argv);
|
||||
|
||||
if (showHelp) showManPage("nix-store" + opName);
|
||||
if (!op) throw UsageError("no operation specified");
|
||||
|
|
|
@ -2,12 +2,13 @@
|
|||
///@file
|
||||
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
namespace nix {
|
||||
|
||||
typedef std::function<void(int, char * *)> MainFunction;
|
||||
typedef std::function<void(std::string, std::list<std::string>)> MainFunction;
|
||||
|
||||
struct LegacyCommands
|
||||
{
|
||||
|
|
|
@ -267,20 +267,6 @@ bool LegacyArgs::processArgs(const Strings & args, bool finish)
|
|||
}
|
||||
|
||||
|
||||
void parseCmdLine(int argc, char * * argv,
|
||||
std::function<bool(Strings::iterator & arg, const Strings::iterator & end)> parseArg)
|
||||
{
|
||||
parseCmdLine(std::string(baseNameOf(argv[0])), argvToStrings(argc, argv), parseArg);
|
||||
}
|
||||
|
||||
|
||||
void parseCmdLine(const std::string & programName, const Strings & args,
|
||||
std::function<bool(Strings::iterator & arg, const Strings::iterator & end)> parseArg)
|
||||
{
|
||||
LegacyArgs(programName, parseArg).parseCmdline(args);
|
||||
}
|
||||
|
||||
|
||||
void printVersion(const std::string & programName)
|
||||
{
|
||||
std::cout << fmt("%1% (Lix, like Nix) %2%", programName, nixVersion) << std::endl;
|
||||
|
|
|
@ -21,12 +21,6 @@ int handleExceptions(const std::string & programName, std::function<void()> fun)
|
|||
*/
|
||||
void initNix();
|
||||
|
||||
void parseCmdLine(int argc, char * * argv,
|
||||
std::function<bool(Strings::iterator & arg, const Strings::iterator & end)> parseArg);
|
||||
|
||||
void parseCmdLine(const std::string & programName, const Strings & args,
|
||||
std::function<bool(Strings::iterator & arg, const Strings::iterator & end)> parseArg);
|
||||
|
||||
void printVersion(const std::string & programName);
|
||||
|
||||
/**
|
||||
|
|
|
@ -381,14 +381,6 @@ void Args::completeDir(AddCompletions & completions, size_t, std::string_view pr
|
|||
_completePath(completions, prefix, true);
|
||||
}
|
||||
|
||||
Strings argvToStrings(int argc, char * * argv)
|
||||
{
|
||||
Strings args;
|
||||
argc--; argv++;
|
||||
while (argc--) args.push_back(*argv++);
|
||||
return args;
|
||||
}
|
||||
|
||||
std::optional<ExperimentalFeature> Command::experimentalFeature ()
|
||||
{
|
||||
return { Xp::NixCommand };
|
||||
|
|
|
@ -364,8 +364,6 @@ public:
|
|||
nlohmann::json toJSON() override;
|
||||
};
|
||||
|
||||
Strings argvToStrings(int argc, char * * argv);
|
||||
|
||||
struct Completion {
|
||||
std::string completion;
|
||||
std::string description;
|
||||
|
|
|
@ -436,13 +436,13 @@ static void runDaemon(bool stdio, std::optional<TrustedFlag> forceTrustClientOpt
|
|||
daemonLoop(forceTrustClientOpt);
|
||||
}
|
||||
|
||||
static int main_nix_daemon(int argc, char * * argv)
|
||||
static int main_nix_daemon(std::string programName, Strings argv)
|
||||
{
|
||||
{
|
||||
auto stdio = false;
|
||||
std::optional<TrustedFlag> isTrustedOpt = std::nullopt;
|
||||
|
||||
parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) {
|
||||
LegacyArgs(programName, [&](Strings::iterator & arg, const Strings::iterator & end) {
|
||||
if (*arg == "--daemon")
|
||||
; // ignored for backwards compatibility
|
||||
else if (*arg == "--help")
|
||||
|
@ -462,7 +462,7 @@ static int main_nix_daemon(int argc, char * * argv)
|
|||
isTrustedOpt = std::nullopt;
|
||||
} else return false;
|
||||
return true;
|
||||
});
|
||||
}).parseCmdline(argv);
|
||||
|
||||
runDaemon(stdio, isTrustedOpt);
|
||||
|
||||
|
|
|
@ -155,7 +155,7 @@ struct CmdHash : MultiCommand
|
|||
static auto rCmdHash = registerCommand<CmdHash>("hash");
|
||||
|
||||
/* Legacy nix-hash command. */
|
||||
static int compatNixHash(int argc, char * * argv)
|
||||
static int compatNixHash(std::string programName, Strings argv)
|
||||
{
|
||||
std::optional<HashType> ht;
|
||||
bool flat = false;
|
||||
|
@ -164,7 +164,7 @@ static int compatNixHash(int argc, char * * argv)
|
|||
enum { opHash, opTo } op = opHash;
|
||||
std::vector<std::string> ss;
|
||||
|
||||
parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) {
|
||||
LegacyArgs(programName, [&](Strings::iterator & arg, const Strings::iterator & end) {
|
||||
if (*arg == "--help")
|
||||
showManPage("nix-hash");
|
||||
else if (*arg == "--version")
|
||||
|
@ -200,7 +200,7 @@ static int compatNixHash(int argc, char * * argv)
|
|||
else
|
||||
ss.push_back(*arg);
|
||||
return true;
|
||||
});
|
||||
}).parseCmdline(argv);
|
||||
|
||||
if (op == opHash) {
|
||||
CmdHashBase cmd(flat ? FileIngestionMethod::Flat : FileIngestionMethod::Recursive);
|
||||
|
|
|
@ -391,7 +391,7 @@ void mainWrapped(int argc, char * * argv)
|
|||
{
|
||||
registerLegacyCommands();
|
||||
auto legacy = (*LegacyCommands::commands)[programName];
|
||||
if (legacy) return legacy(argc, argv);
|
||||
if (legacy) return legacy(std::string(baseNameOf(argv[0])), Strings(argv + 1, argv + argc));
|
||||
}
|
||||
|
||||
evalSettings.pureEval.setDefault(true);
|
||||
|
@ -479,7 +479,7 @@ void mainWrapped(int argc, char * * argv)
|
|||
});
|
||||
|
||||
try {
|
||||
args.parseCmdline(argvToStrings(argc, argv));
|
||||
args.parseCmdline({argv + 1, argv + argc});
|
||||
} catch (UsageError &) {
|
||||
if (!args.helpRequested && !args.completions) throw;
|
||||
}
|
||||
|
|
|
@ -131,7 +131,7 @@ std::tuple<StorePath, Hash> prefetchFile(
|
|||
return {storePath.value(), hash.value()};
|
||||
}
|
||||
|
||||
static int main_nix_prefetch_url(int argc, char * * argv)
|
||||
static int main_nix_prefetch_url(std::string programName, Strings argv)
|
||||
{
|
||||
{
|
||||
HashType ht = HashType::SHA256;
|
||||
|
@ -148,7 +148,7 @@ static int main_nix_prefetch_url(int argc, char * * argv)
|
|||
using LegacyArgs::LegacyArgs;
|
||||
};
|
||||
|
||||
MyArgs myArgs(std::string(baseNameOf(argv[0])), [&](Strings::iterator & arg, const Strings::iterator & end) {
|
||||
MyArgs myArgs(programName, [&](Strings::iterator & arg, const Strings::iterator & end) {
|
||||
if (*arg == "--help")
|
||||
showManPage("nix-prefetch-url");
|
||||
else if (*arg == "--version")
|
||||
|
@ -176,7 +176,7 @@ static int main_nix_prefetch_url(int argc, char * * argv)
|
|||
return true;
|
||||
});
|
||||
|
||||
myArgs.parseCmdline(argvToStrings(argc, argv));
|
||||
myArgs.parseCmdline(argv);
|
||||
|
||||
if (args.size() > 2)
|
||||
throw UsageError("too many arguments");
|
||||
|
|
Loading…
Reference in a new issue