1MooseX::App::Tutorial(3U)ser Contributed Perl DocumentatiMoonoseX::App::Tutorial(3)
2
3
4

NAME

6       MooseX::App::Tutorial - getting started with MooseX::App
7

GETTING STARTED

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

BASE CLASS

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

COMMAND CLASSES

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

INVOCATION SCRIPT

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

HOW TO CONTINUE

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)
Impressum