Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Make subcommand construction in MultiCommand lazy
  • Loading branch information
edolstra committed Jun 18, 2019
1 parent d6c4fe5 commit df3fcb7
Show file tree
Hide file tree
Showing 29 changed files with 73 additions and 286 deletions.
15 changes: 7 additions & 8 deletions src/libutil/args.cc
Expand Up @@ -215,17 +215,15 @@ void Command::printHelp(const string & programName, std::ostream & out)
}
}

MultiCommand::MultiCommand(const std::vector<ref<Command>> & _commands)
MultiCommand::MultiCommand(const Commands & commands)
: commands(commands)
{
for (auto & command : _commands)
commands.emplace(command->name(), command);

expectedArgs.push_back(ExpectedArg{"command", 1, true, [=](std::vector<std::string> ss) {
assert(!command);
auto i = commands.find(ss[0]);
if (i == commands.end())
throw UsageError("'%s' is not a recognised command", ss[0]);
command = i->second;
command = i->second();
}});
}

Expand All @@ -246,10 +244,11 @@ void MultiCommand::printHelp(const string & programName, std::ostream & out)
out << "Available commands:\n";

Table2 table;
for (auto & command : commands) {
auto descr = command.second->description();
for (auto & i : commands) {
auto command = i.second();
auto descr = command->description();
if (!descr.empty())
table.push_back(std::make_pair(command.second->name(), descr));
table.push_back(std::make_pair(command->name(), descr));
}
printTable(out, table);
}
Expand Down
11 changes: 8 additions & 3 deletions src/libutil/args.hh
Expand Up @@ -192,7 +192,12 @@ public:
run() method. */
struct Command : virtual Args
{
virtual std::string name() = 0;
private:
std::string _name;

public:
std::string name() { return _name; }

virtual void prepare() { };
virtual void run() = 0;

Expand All @@ -209,7 +214,7 @@ struct Command : virtual Args
void printHelp(const string & programName, std::ostream & out) override;
};

typedef std::map<std::string, ref<Command>> Commands;
typedef std::map<std::string, std::function<ref<Command>()>> Commands;

/* An argument parser that supports multiple subcommands,
i.e. ‘<command> <subcommand>’. */
Expand All @@ -220,7 +225,7 @@ public:

std::shared_ptr<Command> command;

MultiCommand(const std::vector<ref<Command>> & commands);
MultiCommand(const Commands & commands);

void printHelp(const string & programName, std::ostream & out) override;

Expand Down
7 changes: 1 addition & 6 deletions src/nix/add-to-store.cc
Expand Up @@ -22,11 +22,6 @@ struct CmdAddToStore : MixDryRun, StoreCommand
.dest(&namePart);
}

std::string name() override
{
return "add-to-store";
}

std::string description() override
{
return "add a path to the Nix store";
Expand Down Expand Up @@ -58,4 +53,4 @@ struct CmdAddToStore : MixDryRun, StoreCommand
}
};

static RegisterCommand r1(make_ref<CmdAddToStore>());
static auto r1 = registerCommand<CmdAddToStore>("add-to-store");
7 changes: 1 addition & 6 deletions src/nix/build.cc
Expand Up @@ -25,11 +25,6 @@ struct CmdBuild : MixDryRun, InstallablesCommand
.set(&outLink, Path(""));
}

std::string name() override
{
return "build";
}

std::string description() override
{
return "build a derivation or fetch a store path";
Expand Down Expand Up @@ -72,4 +67,4 @@ struct CmdBuild : MixDryRun, InstallablesCommand
}
};

static RegisterCommand r1(make_ref<CmdBuild>());
static auto r1 = registerCommand<CmdBuild>("build");
14 changes: 2 additions & 12 deletions src/nix/cat.cc
Expand Up @@ -28,11 +28,6 @@ struct CmdCatStore : StoreCommand, MixCat
expectArg("path", &path);
}

std::string name() override
{
return "cat-store";
}

std::string description() override
{
return "print the contents of a store file on stdout";
Expand All @@ -54,11 +49,6 @@ struct CmdCatNar : StoreCommand, MixCat
expectArg("path", &path);
}

std::string name() override
{
return "cat-nar";
}

std::string description() override
{
return "print the contents of a file inside a NAR file";
Expand All @@ -70,5 +60,5 @@ struct CmdCatNar : StoreCommand, MixCat
}
};

static RegisterCommand r1(make_ref<CmdCatStore>());
static RegisterCommand r2(make_ref<CmdCatNar>());
static auto r1 = registerCommand<CmdCatStore>("cat-store");
static auto r2 = registerCommand<CmdCatNar>("cat-nar");
2 changes: 1 addition & 1 deletion src/nix/command.cc
Expand Up @@ -4,7 +4,7 @@

namespace nix {

std::vector<ref<Command>> * RegisterCommand::commands = 0;
Commands * RegisterCommand::commands = nullptr;

StoreCommand::StoreCommand()
{
Expand Down
15 changes: 11 additions & 4 deletions src/nix/command.hh
Expand Up @@ -176,15 +176,22 @@ struct StorePathCommand : public InstallablesCommand
/* A helper class for registering commands globally. */
struct RegisterCommand
{
static std::vector<ref<Command>> * commands;
static Commands * commands;

RegisterCommand(ref<Command> command)
RegisterCommand(const std::string & name,
std::function<ref<Command>()> command)
{
if (!commands) commands = new std::vector<ref<Command>>;
commands->push_back(command);
if (!commands) commands = new Commands;
commands->emplace(name, command);
}
};

template<class T>
static RegisterCommand registerCommand(const std::string & name)
{
return RegisterCommand(name, [](){ return make_ref<T>(); });
}

Buildables build(ref<Store> store, RealiseMode mode,
std::vector<std::shared_ptr<Installable>> installables);

Expand Down
7 changes: 1 addition & 6 deletions src/nix/copy.cc
Expand Up @@ -42,11 +42,6 @@ struct CmdCopy : StorePathsCommand
.set(&substitute, Substitute);
}

std::string name() override
{
return "copy";
}

std::string description() override
{
return "copy paths between Nix stores";
Expand Down Expand Up @@ -97,4 +92,4 @@ struct CmdCopy : StorePathsCommand
}
};

static RegisterCommand r1(make_ref<CmdCopy>());
static auto r1 = registerCommand<CmdCopy>("copy");
7 changes: 1 addition & 6 deletions src/nix/doctor.cc
Expand Up @@ -20,11 +20,6 @@ struct CmdDoctor : StoreCommand
{
bool success = true;

std::string name() override
{
return "doctor";
}

std::string description() override
{
return "check your system for potential problems";
Expand Down Expand Up @@ -121,4 +116,4 @@ struct CmdDoctor : StoreCommand
}
};

static RegisterCommand r1(make_ref<CmdDoctor>());
static auto r1 = registerCommand<CmdDoctor>("doctore");
7 changes: 1 addition & 6 deletions src/nix/dump-path.cc
Expand Up @@ -5,11 +5,6 @@ using namespace nix;

struct CmdDumpPath : StorePathCommand
{
std::string name() override
{
return "dump-path";
}

std::string description() override
{
return "dump a store path to stdout (in NAR format)";
Expand All @@ -33,4 +28,4 @@ struct CmdDumpPath : StorePathCommand
}
};

static RegisterCommand r1(make_ref<CmdDumpPath>());
static auto r1 = registerCommand<CmdDumpPath>("dump-path");
7 changes: 1 addition & 6 deletions src/nix/edit.cc
Expand Up @@ -10,11 +10,6 @@ using namespace nix;

struct CmdEdit : InstallableCommand
{
std::string name() override
{
return "edit";
}

std::string description() override
{
return "open the Nix expression of a Nix package in $EDITOR";
Expand Down Expand Up @@ -78,4 +73,4 @@ struct CmdEdit : InstallableCommand
}
};

static RegisterCommand r1(make_ref<CmdEdit>());
static auto r1 = registerCommand<CmdEdit>("edit");
7 changes: 1 addition & 6 deletions src/nix/eval.cc
Expand Up @@ -18,11 +18,6 @@ struct CmdEval : MixJSON, InstallableCommand
mkFlag(0, "raw", "print strings unquoted", &raw);
}

std::string name() override
{
return "eval";
}

std::string description() override
{
return "evaluate a Nix expression";
Expand Down Expand Up @@ -74,4 +69,4 @@ struct CmdEval : MixJSON, InstallableCommand
}
};

static RegisterCommand r1(make_ref<CmdEval>());
static auto r1 = registerCommand<CmdEval>("build");

0 comments on commit df3fcb7

Please sign in to comment.