Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit df3fcb7

Browse files
committedJun 18, 2019
Make subcommand construction in MultiCommand lazy
1 parent d6c4fe5 commit df3fcb7

29 files changed

+73
-286
lines changed
 

Diff for: ‎src/libutil/args.cc

+7-8
Original file line numberDiff line numberDiff line change
@@ -215,17 +215,15 @@ void Command::printHelp(const string & programName, std::ostream & out)
215215
}
216216
}
217217

218-
MultiCommand::MultiCommand(const std::vector<ref<Command>> & _commands)
218+
MultiCommand::MultiCommand(const Commands & commands)
219+
: commands(commands)
219220
{
220-
for (auto & command : _commands)
221-
commands.emplace(command->name(), command);
222-
223221
expectedArgs.push_back(ExpectedArg{"command", 1, true, [=](std::vector<std::string> ss) {
224222
assert(!command);
225223
auto i = commands.find(ss[0]);
226224
if (i == commands.end())
227225
throw UsageError("'%s' is not a recognised command", ss[0]);
228-
command = i->second;
226+
command = i->second();
229227
}});
230228
}
231229

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

248246
Table2 table;
249-
for (auto & command : commands) {
250-
auto descr = command.second->description();
247+
for (auto & i : commands) {
248+
auto command = i.second();
249+
auto descr = command->description();
251250
if (!descr.empty())
252-
table.push_back(std::make_pair(command.second->name(), descr));
251+
table.push_back(std::make_pair(command->name(), descr));
253252
}
254253
printTable(out, table);
255254
}

Diff for: ‎src/libutil/args.hh

+8-3
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,12 @@ public:
192192
run() method. */
193193
struct Command : virtual Args
194194
{
195-
virtual std::string name() = 0;
195+
private:
196+
std::string _name;
197+
198+
public:
199+
std::string name() { return _name; }
200+
196201
virtual void prepare() { };
197202
virtual void run() = 0;
198203

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

212-
typedef std::map<std::string, ref<Command>> Commands;
217+
typedef std::map<std::string, std::function<ref<Command>()>> Commands;
213218

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

221226
std::shared_ptr<Command> command;
222227

223-
MultiCommand(const std::vector<ref<Command>> & commands);
228+
MultiCommand(const Commands & commands);
224229

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

Diff for: ‎src/nix/add-to-store.cc

+1-6
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,6 @@ struct CmdAddToStore : MixDryRun, StoreCommand
2222
.dest(&namePart);
2323
}
2424

25-
std::string name() override
26-
{
27-
return "add-to-store";
28-
}
29-
3025
std::string description() override
3126
{
3227
return "add a path to the Nix store";
@@ -58,4 +53,4 @@ struct CmdAddToStore : MixDryRun, StoreCommand
5853
}
5954
};
6055

61-
static RegisterCommand r1(make_ref<CmdAddToStore>());
56+
static auto r1 = registerCommand<CmdAddToStore>("add-to-store");

Diff for: ‎src/nix/build.cc

+1-6
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,6 @@ struct CmdBuild : MixDryRun, InstallablesCommand
2525
.set(&outLink, Path(""));
2626
}
2727

28-
std::string name() override
29-
{
30-
return "build";
31-
}
32-
3328
std::string description() override
3429
{
3530
return "build a derivation or fetch a store path";
@@ -72,4 +67,4 @@ struct CmdBuild : MixDryRun, InstallablesCommand
7267
}
7368
};
7469

75-
static RegisterCommand r1(make_ref<CmdBuild>());
70+
static auto r1 = registerCommand<CmdBuild>("build");

Diff for: ‎src/nix/cat.cc

+2-12
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,6 @@ struct CmdCatStore : StoreCommand, MixCat
2828
expectArg("path", &path);
2929
}
3030

31-
std::string name() override
32-
{
33-
return "cat-store";
34-
}
35-
3631
std::string description() override
3732
{
3833
return "print the contents of a store file on stdout";
@@ -54,11 +49,6 @@ struct CmdCatNar : StoreCommand, MixCat
5449
expectArg("path", &path);
5550
}
5651

57-
std::string name() override
58-
{
59-
return "cat-nar";
60-
}
61-
6252
std::string description() override
6353
{
6454
return "print the contents of a file inside a NAR file";
@@ -70,5 +60,5 @@ struct CmdCatNar : StoreCommand, MixCat
7060
}
7161
};
7262

73-
static RegisterCommand r1(make_ref<CmdCatStore>());
74-
static RegisterCommand r2(make_ref<CmdCatNar>());
63+
static auto r1 = registerCommand<CmdCatStore>("cat-store");
64+
static auto r2 = registerCommand<CmdCatNar>("cat-nar");

Diff for: ‎src/nix/command.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
namespace nix {
66

7-
std::vector<ref<Command>> * RegisterCommand::commands = 0;
7+
Commands * RegisterCommand::commands = nullptr;
88

99
StoreCommand::StoreCommand()
1010
{

Diff for: ‎src/nix/command.hh

+11-4
Original file line numberDiff line numberDiff line change
@@ -176,15 +176,22 @@ struct StorePathCommand : public InstallablesCommand
176176
/* A helper class for registering commands globally. */
177177
struct RegisterCommand
178178
{
179-
static std::vector<ref<Command>> * commands;
179+
static Commands * commands;
180180

181-
RegisterCommand(ref<Command> command)
181+
RegisterCommand(const std::string & name,
182+
std::function<ref<Command>()> command)
182183
{
183-
if (!commands) commands = new std::vector<ref<Command>>;
184-
commands->push_back(command);
184+
if (!commands) commands = new Commands;
185+
commands->emplace(name, command);
185186
}
186187
};
187188

189+
template<class T>
190+
static RegisterCommand registerCommand(const std::string & name)
191+
{
192+
return RegisterCommand(name, [](){ return make_ref<T>(); });
193+
}
194+
188195
Buildables build(ref<Store> store, RealiseMode mode,
189196
std::vector<std::shared_ptr<Installable>> installables);
190197

Diff for: ‎src/nix/copy.cc

+1-6
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,6 @@ struct CmdCopy : StorePathsCommand
4242
.set(&substitute, Substitute);
4343
}
4444

45-
std::string name() override
46-
{
47-
return "copy";
48-
}
49-
5045
std::string description() override
5146
{
5247
return "copy paths between Nix stores";
@@ -97,4 +92,4 @@ struct CmdCopy : StorePathsCommand
9792
}
9893
};
9994

100-
static RegisterCommand r1(make_ref<CmdCopy>());
95+
static auto r1 = registerCommand<CmdCopy>("copy");

Diff for: ‎src/nix/doctor.cc

+1-6
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,6 @@ struct CmdDoctor : StoreCommand
2020
{
2121
bool success = true;
2222

23-
std::string name() override
24-
{
25-
return "doctor";
26-
}
27-
2823
std::string description() override
2924
{
3025
return "check your system for potential problems";
@@ -121,4 +116,4 @@ struct CmdDoctor : StoreCommand
121116
}
122117
};
123118

124-
static RegisterCommand r1(make_ref<CmdDoctor>());
119+
static auto r1 = registerCommand<CmdDoctor>("doctore");

Diff for: ‎src/nix/dump-path.cc

+1-6
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,6 @@ using namespace nix;
55

66
struct CmdDumpPath : StorePathCommand
77
{
8-
std::string name() override
9-
{
10-
return "dump-path";
11-
}
12-
138
std::string description() override
149
{
1510
return "dump a store path to stdout (in NAR format)";
@@ -33,4 +28,4 @@ struct CmdDumpPath : StorePathCommand
3328
}
3429
};
3530

36-
static RegisterCommand r1(make_ref<CmdDumpPath>());
31+
static auto r1 = registerCommand<CmdDumpPath>("dump-path");

Diff for: ‎src/nix/edit.cc

+1-6
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,6 @@ using namespace nix;
1010

1111
struct CmdEdit : InstallableCommand
1212
{
13-
std::string name() override
14-
{
15-
return "edit";
16-
}
17-
1813
std::string description() override
1914
{
2015
return "open the Nix expression of a Nix package in $EDITOR";
@@ -78,4 +73,4 @@ struct CmdEdit : InstallableCommand
7873
}
7974
};
8075

81-
static RegisterCommand r1(make_ref<CmdEdit>());
76+
static auto r1 = registerCommand<CmdEdit>("edit");

Diff for: ‎src/nix/eval.cc

+1-6
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,6 @@ struct CmdEval : MixJSON, InstallableCommand
1818
mkFlag(0, "raw", "print strings unquoted", &raw);
1919
}
2020

21-
std::string name() override
22-
{
23-
return "eval";
24-
}
25-
2621
std::string description() override
2722
{
2823
return "evaluate a Nix expression";
@@ -74,4 +69,4 @@ struct CmdEval : MixJSON, InstallableCommand
7469
}
7570
};
7671

77-
static RegisterCommand r1(make_ref<CmdEval>());
72+
static auto r1 = registerCommand<CmdEval>("build");

0 commit comments

Comments
 (0)
Please sign in to comment.