1MooX::Cmd(3) User Contributed Perl Documentation MooX::Cmd(3)
2
3
4
6 MooX::Cmd - Giving an easy Moo style way to make command organized CLI
7 apps
8
10 package MyApp;
11
12 use Moo;
13 use MooX::Cmd;
14
15 sub execute {
16 my ( $self, $args_ref, $chain_ref ) = @_;
17 my @extra_argv = @{$args_ref};
18 my @chain = @{$chain_ref} # in this case only ( $myapp )
19 # where $myapp == $self
20 }
21
22 1;
23
24 package MyApp::Cmd::Command;
25 # for "myapp command"
26
27 use Moo;
28 use MooX::Cmd;
29
30 # gets executed on "myapp command" but not on "myapp command command"
31 # there MyApp::Cmd::Command still gets instantiated and for the chain
32 sub execute {
33 my ( $self, $args_ref, $chain_ref ) = @_;
34 my @chain = @{$chain_ref} # in this case ( $myapp, $myapp_cmd_command )
35 # where $myapp_cmd_command == $self
36 }
37
38 1;
39
40 package MyApp::Cmd::Command::Cmd::Command;
41 # for "myapp command command"
42
43 use Moo;
44 use MooX::Cmd;
45
46 # gets executed on "myapp command command" and will not get instantiated
47 # on "myapp command" cause it doesnt appear in the chain there
48 sub execute {
49 my ( $self, $args_ref, $chain_ref ) = @_;
50 my @chain = @{$chain_ref} # in this case ( $myapp, $myapp_cmd_command,
51 # $myapp_cmd_command_cmd_command )
52 # where $myapp_cmd_command_cmd_command == $self
53 }
54
55 package MyZapp;
56
57 use Moo;
58 use MooX::Cmd execute_from_new => 0;
59
60 sub execute {
61 my ( $self ) = @_;
62 my @extra_argv = @{$self->command_args};
63 my @chain = @{$self->command_chain} # in this case only ( $myzapp )
64 # where $myzapp == $self
65 }
66
67 1;
68
69 package MyZapp::Cmd::Command;
70 # for "myapp command"
71
72 use Moo;
73 use MooX::Cmd execute_from_new => 0;
74
75 # gets executed on "myapp command" but not on "myapp command command"
76 # there MyApp::Cmd::Command still gets instantiated and for the chain
77 sub execute {
78 my ( $self ) = @_;
79 my @extra_argv = @{$self->command_args};
80 my @chain = @{$self->command_chain} # in this case ( $myzapp, $myzapp_cmd_command )
81 # where $myzapp_cmd_command == $self
82 }
83
84 1;
85 package main;
86
87 use MyApp;
88
89 MyZapp->new_with_cmd->execute();
90 MyApp->new_with_cmd;
91
92 1;
93
95 Eases the writing of command line utilities, accepting commands and
96 subcommands and so on. These commands can form a tree, which is
97 mirrored in the package structure. On invocation each command along the
98 path through the tree (starting from the toplevel command through to
99 the most specific one) is instanciated.
100
101 Each command needs to have an "execute" function, accepting three
102 parameters:
103
104 "self"
105 A reference to the specific MooX::Cmd object that is executing.
106
107 "args"
108 An ArrayRef of arguments passed to "self". This only encompasses
109 arguments of the most specific (read: right-most) command.
110
111 "chain"
112 An ArrayRef of "MooX::Cmd"s along the tree path, as specified on
113 the command line.
114
115 Note that only the execute function of the most specific command is
116 executed.
117
118 MooX::Cmd Attributes
119
120 Each command has some attributes set by MooX::Cmd during
121 initialization:
122
123 "command_chain"
124 Same as "chain" argument to "execute".
125
126 "command_name"
127 TODO
128
129 "command_commands"
130 TODO
131
132 "command_args"
133 TODO
134
135 "command_base"
136 TODO
137
138 Examples
139 A Single Toplevel Command
140
141 #!/usr/bin/env perl
142 package MyApp;
143 use Moo;
144 use MooX::Cmd;
145
146 sub execute {
147 my ($self,$args,$chain) = @_;
148 printf("%s.execute(\$self,[%s],[%s])\n",
149 ref($self), # which command is executing?
150 join(", ", @$args ), # what where the arguments?
151 join(", ", map { ref } @$chain) # what's in the command chain?
152 );
153 }
154
155 package main;
156 MyApp->new_with_cmd();
157
158 Some sample invocations:
159
160 $ ./MyApp.pl
161 MyApp.execute($self,[],[MyApp])
162
163 $./MyApp.pl --opt1
164 MyApp.execute($self,[--opt1],[MyApp])
165
166 $ ./MyApp.pl --opt1 arg
167 MyApp.execute($self,[--opt1, arg],[MyApp])
168
169 Toplevel Command with Subcommand
170
171 #!/usr/bin/env perl
172 # let's define a base class containing our generic execute
173 # function to save some typing...
174 package CmdBase;
175 use Moo;
176
177 sub execute {
178 my ($self,$args,$chain) = @_;
179 printf("%s.execute(\$self,[%s],[%s])\n",
180 ref($self),
181 join(", ", @$args ),
182 join(", ", map { ref } @$chain)
183 );
184 }
185
186 package MyApp;
187 # toplevel command/app
188 use Moo;
189 use MooX::Cmd;
190 extends 'CmdBase';
191
192 package MyApp::Cmd::frobnicate;
193 # can be called via ./MyApp.pl frobnicate
194 use Moo;
195 use MooX::Cmd;
196 extends 'CmdBase';
197
198 package main;
199 MyApp->new_with_cmd();
200
201 And some sample invocations:
202
203 $ ./MyApp.pl frobnicate
204 MyApp::Cmd::frobnicate.execute($self,[],[MyApp, MyApp::Cmd::frobnicate])
205
206 As you can see the chain contains our toplevel command object and then
207 the specififc one.
208
209 $ ./MyApp.pl frobnicate arg1
210 MyApp::Cmd::frobnicate.execute($self,[arg1],[MyApp, MyApp::Cmd::frobnicate])
211
212 Arguments are passed via the "args" parameter.
213
214 $ ./MyApp.pl some --stuff frobnicate arg1
215 MyApp::Cmd::frobnicate.execute($self,[arg1],[MyApp, MyApp::Cmd::frobnicate])
216
217 Arguments to commands higher in the tree get ignored if they don't
218 match a command.
219
220 Access Toplevel Attributes via Chain
221
222 #!/usr/bin/env perl
223 package CmdBase;
224 use Moo;
225
226 sub execute {
227 my ($self,$args,$chain) = @_;
228 printf("%s.execute(\$self,[%s],[%s])\n",
229 ref($self),
230 join(", ", @$args ),
231 join(", ", map { ref } @$chain)
232 );
233 }
234
235 package MyApp;
236 use Moo;
237 use MooX::Cmd;
238 extends 'CmdBase';
239
240 has somevar => ( is => 'ro', default => 'someval' );
241
242 package MyApp::Cmd::frobnicate;
243 use Moo;
244 use MooX::Cmd;
245 extends 'CmdBase';
246
247 around execute => sub {
248 my ($orig,$self,$args,$chain) = @_;
249 $self->$orig($args,$chain);
250 # we can access toplevel attributes via the chain...
251 printf("MyApp->somevar = '%s'\n", $chain->[0]->somevar);
252 };
253
254 package main;
255 MyApp->new_with_cmd();
256
257 A sample invocation
258
259 $ ./MyApp.pl some --stuff frobnicate arg1
260 MyApp::Cmd::frobnicate.execute($self,[arg1],[MyApp, MyApp::Cmd::frobnicate])
261 MyApp->somevar = someval
262
263 MooX::Options integration
264 You can integrate MooX::Options simply by using it and declaring some
265 options, like so:
266
267 #!/usr/bin/env perl
268 package MyApp;
269 use Moo;
270 use MooX::Cmd;
271 use MooX::Options;
272
273 option debug => ( is => 'ro' );
274
275 sub execute {
276 my ($self,$args,$chain) = @_;
277 print "debugging enabled!\n" if $self->{debug};
278 }
279
280 package main;
281 MyApp->new_with_cmd();
282
283 A sample invocation
284
285 $ ./MyApp-Options.pl --debug
286 debugging enabled!
287
288 Note, that each command and subcommand has its own options., so options
289 are parsed for the specific context and used for the instantiation:
290
291 $ ./MyApp.pl --argformyapp command --argformyappcmdcommand ...
292
294 Repository
295
296 http://github.com/Getty/p5-moox-cmd
297 Pull request and additional contributors are welcome
298
299 Issue Tracker
300
301 http://github.com/Getty/p5-moox-cmd/issues
302 http://rt.cpan.org/NoAuth/Bugs.html?Dist=MooX-Cmd
303 bug-moox-cmd at rt.cpan.org
304
306 Lukas Mai (mauke), Toby Inkster (tobyink)
307 Gave some helpful advice for solving difficult issues
308
309 Celogeek San
310 Integration into MooX::Options for better help messages and suit
311 team play
312
313 Torsten Raudssus (Getty)
314 did the initial work and brought it to CPAN
315
317 Copyright 2012-2013 Torsten Raudssus, Copyright 2013-2017 Jens Rehsack.
318
319 This program is free software; you can redistribute it and/or modify it
320 under the terms of either: the GNU General Public License as published
321 by the Free Software Foundation; or the Artistic License.
322
323 See <http://dev.perl.org/licenses/> for more information.
324
325
326
327perl v5.30.1 2020-01-30 MooX::Cmd(3)