1App::Cmd::Tutorial(3) User Contributed Perl DocumentationApp::Cmd::Tutorial(3)
2
3
4
6 App::Cmd::Tutorial - getting started with App::Cmd
7
9 version 0.331
10
12 App::Cmd is a set of tools designed to make it simple to write
13 sophisticated command line programs. It handles commands with multiple
14 subcommands, generates usage text, validates options, and lets you
15 write your program as easy-to-test classes.
16
17 An App::Cmd-based application is made up of three main parts: the
18 script, the application class, and the command classes.
19
20 The Script
21 The script is the actual executable file run at the command line. It
22 can generally consist of just a few lines:
23
24 #!/usr/bin/perl
25 use YourApp;
26 YourApp->run;
27
28 The Application Class
29 All the work of argument parsing, validation, and dispatch is taken
30 care of by your application class. The application class can also be
31 pretty simple, and might look like this:
32
33 package YourApp;
34 use App::Cmd::Setup -app;
35 1;
36
37 When a new application instance is created, it loads all of the command
38 classes it can find, looking for modules under the Command namespace
39 under its own name. In the above snippet, for example, YourApp will
40 look for any module with a name starting with "YourApp::Command::".
41
42 The Command Classes
43 We can set up a simple command class like this:
44
45 # ABSTRACT: set up YourApp
46 package YourApp::Command::initialize;
47 use YourApp -command;
48 1;
49
50 Now, a user can run this command, but he'll get an error:
51
52 $ yourcmd initialize
53 YourApp::Command::initialize does not implement mandatory method 'execute'
54
55 Oops! This dies because we haven't told the command class what it
56 should do when executed. This is easy, we just add some code:
57
58 sub execute {
59 my ($self, $opt, $args) = @_;
60
61 print "Everything has been initialized. (Not really.)\n";
62 }
63
64 Now it works:
65
66 $ yourcmd initialize
67 Everything has been initialized. (Not really.)
68
69 Default Commands
70 By default applications made with App::Cmd know two commands:
71 "commands" and "help".
72
73 commands
74 lists available commands.
75
76 $yourcmd commands
77 Available commands:
78
79 commands: list the application's commands
80 help: display a command's help screen
81
82 init: set up YourApp
83
84 Note that by default the commands receive a description from the "#
85 ABSTRACT" comment in the respective command's module, or from the
86 "=head1 NAME" Pod section.
87
88 help
89 allows one to query for details on command's specifics.
90
91 $yourcmd help initialize
92 yourcmd initialize [-z] [long options...]
93
94 -z --zero ignore zeros
95
96 Of course, it's possible to disable or change the default commands,
97 see App::Cmd.
98
99 Arguments and Options
100 In this example
101
102 $ yourcmd reset -zB --new-seed xyzxy foo.db bar.db
103
104 "-zB" and "--new-seed xyzxy" are "options" and "foo.db" and "bar.db"
105 are "arguments."
106
107 With a properly configured command class, the above invocation results
108 in nicely formatted data:
109
110 $opt = {
111 zero => 1,
112 no_backup => 1, #default value
113 new_seed => 'xyzzy',
114 };
115
116 $args = [ qw(foo.db bar.db) ];
117
118 Arguments are processed by Getopt::Long::Descriptive (GLD). To
119 customize its argument processing, a command class can implement a few
120 methods: "usage_desc" provides the usage format string; "opt_spec"
121 provides the option specification list; "validate_args" is run after
122 Getopt::Long::Descriptive, and is meant to validate the $args, which
123 GLD ignores. See Getopt::Long for format specifications.
124
125 The first two methods provide configuration passed to GLD's
126 "describe_options" routine. To improve our command class, we might add
127 the following code:
128
129 sub usage_desc { "yourcmd %o [dbfile ...]" }
130
131 sub opt_spec {
132 return (
133 [ "skip-refs|R", "skip reference checks during init", ],
134 [ "values|v=s@", "starting values", { default => [ 0, 1, 3 ] } ],
135 );
136 }
137
138 sub validate_args {
139 my ($self, $opt, $args) = @_;
140
141 # we need at least one argument beyond the options; die with that message
142 # and the complete "usage" text describing switches, etc
143 $self->usage_error("too few arguments") unless @$args;
144 }
145
146 Global Options
147 There are several ways of making options available everywhere
148 (globally). This recipe makes local options accessible in all commands.
149
150 To add a "--help" option to all your commands create a base class like:
151
152 package MyApp::Command;
153 use App::Cmd::Setup -command;
154
155 sub opt_spec {
156 my ( $class, $app ) = @_;
157 return (
158 [ 'help' => "this usage screen" ],
159 $class->options($app),
160 )
161 }
162
163 sub validate_args {
164 my ( $self, $opt, $args ) = @_;
165 if ( $opt->{help} ) {
166 my ($command) = $self->command_names;
167 $self->app->execute_command(
168 $self->app->prepare_command("help", $command)
169 );
170 exit;
171 }
172 $self->validate( $opt, $args );
173 }
174
175 Where "options" and "validate" are "inner" methods which your command
176 subclasses implement to provide command-specific options and
177 validation.
178
179 Note: this is a new file, previously not mentioned in this tutorial and
180 this tip does not recommend the use of global_opt_spec which offers an
181 alternative way of specifying global options.
182
184 · Delay using large modules using Class::Load, Module::Runtime or
185 "require" in your commands to save memory and make startup faster.
186 Since only one of these commands will be run anyway, there's no
187 need to preload the requirements for all of them.
188
189 · Add a "description" method to your commands for more verbose output
190 from the built-in help command.
191
192 sub description {
193 return "The initialize command prepares ...";
194 }
195
196 · To let your users configure default values for options, put a sub
197 like
198
199 sub config {
200 my $app = shift;
201 $app->{config} ||= TheLovelyConfigModule->load_config_file();
202 }
203
204 in your main app file, and then do something like:
205
206 package YourApp;
207 sub opt_spec {
208 my ( $class, $app ) = @_;
209 my ( $name ) = $class->command_names;
210 return (
211 [ 'blort=s' => "That special option",
212 { default => $app->config->{$name}{blort} || $fallback_default },
213 ],
214 );
215 }
216
217 Or better yet, put this logic in a superclass and process the
218 return value from an "inner" method:
219
220 package YourApp::Command;
221 sub opt_spec {
222 my ( $class, $app ) = @_;
223 return (
224 [ 'help' => "this usage screen" ],
225 $class->options($app),
226 )
227 }
228
229 · You need to activate "strict" and "warnings" as usual if you want
230 them. App::Cmd doesn't do that for you.
231
233 Some people find that for whatever reason, they wish to put Modules in
234 their "MyApp::Command::" namespace which are not commands, or not
235 commands intended for use by "MyApp".
236
237 Good examples include, but are not limited to, things like
238 "MyApp::Command::frobrinate::Plugin::Quietly", where "::Quietly" is
239 only useful for the "frobrinate" command.
240
241 The default behaviour is to treat such packages as errors, as for the
242 majority of use cases, things in "::Command" are expected to only be
243 commands, and thus, anything that, by our heuristics, is not a command,
244 is highly likely to be a mistake.
245
246 And as all commands are loaded simultaneously, an error in any one of
247 these commands will yield a fatal error.
248
249 There are a few ways to specify that you are sure you want to do this,
250 with varying ranges of scope and complexity.
251
252 Ignoring a Single Module.
253 This is the simplest approach, and most useful for one-offs.
254
255 package YourApp::Command::foo::NotACommand;
256
257 use YourApp -ignore;
258
259 <whatever you want here>
260
261 This will register this package's namespace with YourApp to be excluded
262 from its plugin validation magic. It otherwise makes no changes to
263 "::NotACommand"'s namespace, does nothing magical with @ISA, and
264 doesn't bolt any hidden functions on.
265
266 Its also probably good to notice that it is ignored only by "YourApp".
267 If for whatever reason you have two different "App::Cmd" systems under
268 which "::NotACommand" is visible, you'll need to set it ignored to
269 both.
270
271 This is probably a big big warning NOT to do that.
272
273 Ignoring Multiple modules from the App level.
274 If you really fancy it, you can override the "should_ignore" method
275 provided by "App::Cmd" to tweak its ignore logic. The most useful
276 example of this is as follows:
277
278 sub should_ignore {
279 my ( $self, $command_class ) = @_;
280 return 1 if not $command_class->isa( 'App::Cmd::Command' );
281 return;
282 }
283
284 This will prematurely mark for ignoring all packages that don't
285 subclass "App::Cmd::Command", which causes non-commands ( or perhaps
286 commands that are coded wrongly / broken ) to be silently skipped.
287
288 Note that by overriding this method, you will lose the effect of any of
289 the other ignore mechanisms completely. If you want to combine the
290 original "should_ignore" method with your own logic, you'll want to
291 steal "Moose"'s "around" method modifier.
292
293 use Moose::Util;
294
295 Moose::Util::add_method_modifier( __PACKAGE__, 'around', [
296 should_ignore => sub {
297 my $orig = shift;
298 my $self = shift;
299 return 1 if not $command_class->isa( 'App::Cmd::Command' );
300 return $self->$orig( @_ );
301 }]);
302
304 CPAN modules using App::Cmd <http://deps.cpantesters.org/depended-on-
305 by.pl?module=App%3A%3ACmd>
306
308 Ricardo Signes <rjbs@cpan.org>
309
311 This software is copyright (c) 2016 by Ricardo Signes.
312
313 This is free software; you can redistribute it and/or modify it under
314 the same terms as the Perl 5 programming language system itself.
315
316
317
318perl v5.32.0 2020-07-28 App::Cmd::Tutorial(3)