Allow registering subcommands of subcommands
This commit is contained in:
parent
b2d6c6161e
commit
5781f45c46
3 changed files with 27 additions and 4 deletions
|
@ -11,7 +11,21 @@ extern char * * environ __attribute__((weak));
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
Commands * RegisterCommand::commands = nullptr;
|
RegisterCommand::Commands * RegisterCommand::commands = nullptr;
|
||||||
|
|
||||||
|
nix::Commands RegisterCommand::getCommandsFor(const std::vector<std::string> & prefix)
|
||||||
|
{
|
||||||
|
nix::Commands res;
|
||||||
|
for (auto & [name, command] : *RegisterCommand::commands)
|
||||||
|
if (name.size() == prefix.size() + 1) {
|
||||||
|
bool equal = true;
|
||||||
|
for (size_t i = 0; i < prefix.size(); ++i)
|
||||||
|
if (name[i] != prefix[i]) equal = false;
|
||||||
|
if (equal)
|
||||||
|
res.insert_or_assign(name[prefix.size()], command);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
void NixMultiCommand::printHelp(const string & programName, std::ostream & out)
|
void NixMultiCommand::printHelp(const string & programName, std::ostream & out)
|
||||||
{
|
{
|
||||||
|
|
|
@ -176,20 +176,29 @@ struct StorePathCommand : public InstallablesCommand
|
||||||
/* A helper class for registering commands globally. */
|
/* A helper class for registering commands globally. */
|
||||||
struct RegisterCommand
|
struct RegisterCommand
|
||||||
{
|
{
|
||||||
|
typedef std::map<std::vector<std::string>, std::function<ref<Command>()>> Commands;
|
||||||
static Commands * commands;
|
static Commands * commands;
|
||||||
|
|
||||||
RegisterCommand(const std::string & name,
|
RegisterCommand(std::vector<std::string> && name,
|
||||||
std::function<ref<Command>()> command)
|
std::function<ref<Command>()> command)
|
||||||
{
|
{
|
||||||
if (!commands) commands = new Commands;
|
if (!commands) commands = new Commands;
|
||||||
commands->emplace(name, command);
|
commands->emplace(name, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static nix::Commands getCommandsFor(const std::vector<std::string> & prefix);
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
static RegisterCommand registerCommand(const std::string & name)
|
static RegisterCommand registerCommand(const std::string & name)
|
||||||
{
|
{
|
||||||
return RegisterCommand(name, [](){ return make_ref<T>(); });
|
return RegisterCommand({name}, [](){ return make_ref<T>(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
static RegisterCommand registerCommand2(std::vector<std::string> && name)
|
||||||
|
{
|
||||||
|
return RegisterCommand(std::move(name), [](){ return make_ref<T>(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
Buildables build(ref<Store> store, Realise mode,
|
Buildables build(ref<Store> store, Realise mode,
|
||||||
|
|
|
@ -59,7 +59,7 @@ struct NixArgs : virtual MultiCommand, virtual MixCommonArgs
|
||||||
bool useNet = true;
|
bool useNet = true;
|
||||||
bool refresh = false;
|
bool refresh = false;
|
||||||
|
|
||||||
NixArgs() : MultiCommand(*RegisterCommand::commands), MixCommonArgs("nix")
|
NixArgs() : MultiCommand(RegisterCommand::getCommandsFor({})), MixCommonArgs("nix")
|
||||||
{
|
{
|
||||||
categories.clear();
|
categories.clear();
|
||||||
categories[Command::catDefault] = "Main commands";
|
categories[Command::catDefault] = "Main commands";
|
||||||
|
|
Loading…
Reference in a new issue