1MooseX::App::Tutorial(3U)ser Contributed Perl DocumentatiMoonoseX::App::Tutorial(3)
2
3
4
6 MooseX::App::Tutorial - getting started with MooseX::App
7
9 To create a simple command-line application with MooseX::App you need
10
11 • A base class
12
13 • Multiple command classes (unless you use MooseX::App::Simple)
14
15 • and an invocation script
16
18 The simplest possible base class just contains a single use statement
19 which loads all roles and metaclasses you need to get started as well
20 as Moose.
21
22 package MyApp;
23 use MooseX::App;
24 1;
25
26 The base class can be customized by
27
28 • adding MooseX-App plugins
29
30 • changing the command-class namespace
31
32 • defining global options/parameters used by all command classes
33 (only if command classes inherit from the base class)
34
35 • add documentation (either POD or via the app_usage and
36 app_description functions)
37
38 • and changing MooseX-App flags (eg. turn fuzzy matching off)
39
40 • Adding Moose attribute documentation and type constraints.
41
42 It is also possible to add global options and parameters to your base
43 class and inherit your command classes from the base class (inheriting
44 your command classes from your base class is purely optional).
45
46 package MyApp;
47 use MooseX::App qw(Config Color); # Loads the Config and Color plugin
48
49 # This attribute will be available at the command line
50 option 'some_global_option' => (
51 is => 'rw',
52 isa => 'Str',
53 required => 1,
54 documentation => q[Some important global option],
55 );
56
57 # This attribute will not be exposed
58 has 'private_option' => (
59 is => 'rw',
60 isa => 'Str',
61 );
62
63 1;
64
65 When adding attributes make sure to include a documentation and
66 possibly a type constraint. MooseX-App will use this information to
67 build a user documentation for each attribute and command. The
68 attribute documentation can be customized by providing additional
69 options (see MooseX::App::Meta::Role::Attribute::Option)
70
72 After you created a base class it is time to create one class for each
73 command you want to provide (unless you are using MooseX::App::Simple).
74 The command classes must reside in the namespace of the base class (eg.
75 'MyApp::SomeCommand'). You can also deeply nest classes in the main
76 namespace to create subcommand. The namespace for the command classes
77 however can be changed via the 'app_namespace' function in the base
78 class, or by simply registering command classes manually via
79 'app_command_register'. Use 'app_exclude' to exclude certain sub
80 namespaces.
81
82 All command classes must use MooseX::App::Command, which will also load
83 Moose.
84
85 package MyApp::SomeCommand;
86 use MooseX::App::Command;
87
88 If you want to use global options defined in the base class you can
89 optionally extend the base class with your command class.
90
91 package MyApp::SomeCommand;
92 use MooseX::App::Command;
93 extends qw(MyApp);
94
95 To provide a description for each command you need to set the
96 "command_short_description", "command_long_description" and optionally
97 "command_usage" information. The command descriptions may contain
98 linebreaks.
99
100 command_short_description q[This command is awesome];
101 command_long_description q[This command is so awesome, yadda yadda yadda];
102
103 If not provided, MooseX-App will try to parse the command description
104 from the POD. The NAME or ABSTRACT section will become the short
105 description and the DESCRIPTION or OVERVIEW section the long
106 description.
107
108 The usage header can either be set by adding "command_usage"
109
110 command_usage q[script some_command --some_option NUMBER];
111
112 or by adding a SYNOPSIS or USAGE section to the module' POD. If neither
113 command_usage nor SYNOPSIS/USAGE are set, then the usage header will be
114 autogenerated.
115
116 Attributes can be documented using the Moose built-in "documentation"
117 option as well as "cmd_tags", "cmd_flag" and "cmd_aliases" which are
118 defined by MooseX-App (see MooseX::App::Meta::Role::Attribute::Option)
119
120 option 'some_option' => (
121 is => 'rw',
122 isa => 'Integer',
123 required => 1,
124 documentation => q[Some important option],
125 cmd_tags => [qw(Important!)], # Extra tags. Displayed in square brackets
126 cmd_aliases => [qw(s)], # Alternative option name
127 cmd_flag => 'some', # Option should be called 'some' instead of 'some_option'
128 );
129
130 It is also possible to define positional parameters with the
131 'parameter' keyword
132
133 # This attribute will become a positional parameter
134 parameter 'id' => (
135 is => 'rw',
136 isa => 'Int',
137 documentation => q[Some ID],
138 required => 1,
139 );
140
141 The help for this command would look something like this (with
142 autogenerated usage headers):
143
144 usage:
145 my_app some_command <ID> [long options...]
146 my_app help
147 my_app some_command --help
148
149 description:
150 This command is awesome, yadda yadda yadda
151
152 parameter:
153 ID Some ID [Integer; Required]
154
155 options:
156 --config Path to command config file
157 --some -s Some important option [Required; Integer; Important!]
158 --help --usage -? Prints this usage information. [Flag]
159
160 In case you want to include an attribute not defined with the 'option'
161 or 'parameter' keyword you can use the 'AppOption' trait and 'cmd_type'
162 attribute. (see MooseX::App::Meta::Attribute::Option).
163
164 has 'myoption' => (
165 is => 'rw',
166 traits => ['AppOption'], # only required if not definded in base or command class
167 cmd_type => 'option', # or 'parameter'
168 );
169
170 Finally your command classes will need a method which should be called
171 if the command is invoked by the user.
172
173 sub run {
174 my ($self) = @_;
175 # do something
176 }
177
178 If you need to implement only a single command you should use
179 MooseX::App::Simple instead of MooseX::App, and omit command classes.
180 In this case of course you have to declare all options and implement
181 the application logic in the base class:
182
183 package MyApp;
184 use MooseX::App::Simple qw(Config); # Loads the Config plugin
185
186 option 'some_global_option' => (
187 is => 'rw',
188 isa => 'Str',
189 documentation => q[Some important global option],
190 );
191
192 sub run {
193 my ($self) = @_;
194 # do something
195 }
196
197 1;
198
200 Once you have the base and command classes ready, you need to write a
201 small invocation script:
202
203 #!/usr/bin/env perl
204 use MyApp;
205 MyApp->new_with_command->run();
206
207 "MyApp->new_with_command" will try to instantiate a command class. If
208 it fails it will return a MooseX::App::Message::Envelope object
209 possibly containing an error message and a usage message. Since
210 MooseX::App::Message::Envelope follows the Null object pattern you can
211 call any method on it without checking the object type. Note that
212 MooseX::App::Message::Envelope objects may also have an exitcode set.
213 In this case whenever the object gets stringified, it prints on
214 STDERR/STDOUT and exits the program using the specified exitcode. Don't
215 use the ovleroaded stingification if you don't want this behaviour.
216
217 You can also pass default/fallback values to the constructor
218
219 #!/usr/bin/env perl
220 use MyApp;
221 MyApp->new_with_command( some_global_option => 'something' )->run();
222
223 If using MooseX::App::Simple your invocation script needs some
224 modification and call "new_with_options" instead of "new_with_command".
225
226 #!/usr/bin/env perl
227 use MyApp;
228 MyApp->new_with_options->run();
229
231 Once you have a basic working application you can make it more user
232 friendly by adding documentation (either by using the app_description,
233 app_usage, command_short_description, ... functions or by writing POD),
234 Moose type constraints and additional plugins (eg. colorise the
235 output).
236
237 Make sure to invoke your script with APP_DEVELOPER=1 during
238 development. This will perform additional checks for detecting wrong
239 attribute/type constraint combinations, name clashes, ...
240
241 If you want custom behaviour you could start writing your own
242 MooseX::App::WritingPlugins.
243
244 Make sure to run your application in the APP_DEVELOPER=1 environment.
245 In this mode additional sanity checks will be performed upon startup.
246
247
248
249perl v5.32.1 2021-02-28 MooseX::App::Tutorial(3)