Provided by: libmoosex-app-perl_1.43-1_all bug

NAME

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

GETTING STARTED

       To create a simple command-line application with MooseX::App you need

       •   A base class

       •   Multiple command classes (unless you use MooseX::App::Simple)

       •   and an invocation script

BASE CLASS

       The  simplest  possible  base  class  just  contains  a  single  use  statement which loads all roles and
       metaclasses you need to get started as well as Moose and hence strictures as well as warnings.

         package MyApp;
         use MooseX::App;
         1;

       The base class can be customized by

       •   adding MooseX-App plugins

       •   changing the command-class namespace

       •   defining global options/parameters used by all command classes (only if command classes inherit  from
           the base class)

       •   add documentation (either POD or via the app_usage and app_description functions)

       •   and changing MooseX-App flags (eg. turn fuzzy matching off)

       •   Adding Moose attribute documentation and type constraints.

       It  is  also  possible  to  add global options and parameters to your base class and inherit your command
       classes from the base class (inheriting your command classes from your base class is purely optional).

         package MyApp;
         use MooseX::App qw(Config Color); # Loads the Config and Color plugin

         # This attribute will be available at the command line
         option 'some_global_option' => (
             is                => 'rw',
             isa               => 'Str',
             required          => 1,
             documentation     => q[Some important global option],
         );

         # This attribute will not be exposed
         has 'private_option' => (
             is              => 'rw',
             isa             => 'Str',
         );

         1;

       When adding attributes make sure to include a documentation and possibly a  type  constraint.  MooseX-App
       will  use  this  information  to build a user documentation for each attribute and command. The attribute
       documentation     can     be     customized      by      providing      additional      options      (see
       MooseX::App::Meta::Role::Attribute::Option)

COMMAND CLASSES

       After  you  created  a  base  class  it  is time to create one class for each command you want to provide
       (unless you are using MooseX::App::Simple). The command classes must reside in the namespace of the  base
       class  (eg.  'MyApp::SomeCommand').   You  can  also  deeply nest classes in the main namespace to create
       subcommand.  The namespace for the command  classes  however  can  be  changed  via  the  'app_namespace'
       function in the base class, or by simply registering command classes manually via 'app_command_register'.
       Use 'app_exclude' to exclude certain sub namespaces.

       All command classes must use MooseX::App::Command, which will also load Moose.

         package MyApp::SomeCommand;
         use MooseX::App::Command;

       If you want to use global options defined in the base class you can optionally extend the base class with
       your command class.

         package MyApp::SomeCommand;
         use MooseX::App::Command;
         extends qw(MyApp);

       To   provide   a   description  for  each  command  you  need  to  set  the  "command_short_description",
       "command_long_description" and optionally  "command_usage"  information.  The  command  descriptions  may
       contain linebreaks.

        command_short_description q[This command is awesome];
        command_long_description q[This command is so awesome, yadda yadda yadda];

       If  not provided, MooseX-App will try to parse the command description from the POD. The NAME or ABSTRACT
       section will become the short description and the DESCRIPTION or OVERVIEW section the long description.

       The usage header can either be set by adding "command_usage"

        command_usage q[script some_command --some_option NUMBER];

       or by adding a SYNOPSIS or USAGE section to the module' POD. If neither command_usage nor  SYNOPSIS/USAGE
       are set, then the usage header will be autogenerated.

       Attributes  can  be  documented  using  the  Moose built-in "documentation" option as well as "cmd_tags",
       "cmd_flag"      and      "cmd_aliases"      which      are      defined      by      MooseX-App      (see
       MooseX::App::Meta::Role::Attribute::Option)

         option 'some_option' => (
             is                => 'rw',
             isa               => 'Integer',
             required          => 1,
             documentation     => q[Some important option],
             cmd_tags          => [qw(Important!)], # Extra tags. Displayed in square brackets
             cmd_aliases       => [qw(any)], # Alternative option name
             cmd_flag          => 'some', # Option should be called 'some' instead of 'some_option'
         );

       It is also possible to define positional parameters with the 'parameter' keyword

         # This attribute will become a positional parameter
         parameter 'id' => (
             is                => 'rw',
             isa               => 'Int',
             documentation     => q[Some ID],
             required          => 1,
         );

       The help for this command would look something like this (with autogenerated usage headers):

         usage:
           my_app some_command <ID> [long options...]
           my_app help
           my_app some_command --help

         description:
           This command is awesome, yadda yadda yadda

         parameter:
           ID                 Some ID [Integer; Required]

         options:
           --config           Path to command config file
           --some -s          Some important option [Required; Integer; Important!]
           --help --usage -?  Prints this usage information. [Flag]

       In  case you want to include an attribute not defined with the 'option' or 'parameter' keyword (eg from a
       Role)    you    can    use    the    'AppOption'     trait     and     'cmd_type'     attribute.     (see
       MooseX::App::Meta::Attribute::Option).

         has 'myoption' => (
             is                => 'rw',
             traits            => ['AppOption'], # only required if not definded in base or command class
             cmd_type          => 'option', # or 'parameter'
         );

       Finally  your  command classes will need a method which should be called if the command is invoked by the
       user.

        sub run {
           my ($self) = @_;
           # do something
        }

       If you need to implement only a single command you should use MooseX::App::Simple instead of MooseX::App,
       and omit command classes.  In this case of course you have to  declare  all  options  and  implement  the
       application logic in the base class:

         package MyApp;
         use MooseX::App::Simple qw(Config); # Loads the Config plugin

         option 'some_option' => (
             is                => 'rw',
             isa               => 'Str',
             documentation     => q[Some important option],
         );

         sub run {
            my ($self) = @_;
            # do something
         }

         1;

INVOCATION SCRIPT

       Once you have the base and command classes ready, you need to write a small invocation script:

        #!/usr/bin/env perl
        use MyApp;
        MyApp->new_with_command->run();

       "MyApp->new_with_command"  will  try  to  instantiate  a  command  class.  If  it  fails it will return a
       MooseX::App::Message::Envelope object possibly containing an error message and  a  usage  message.  Since
       MooseX::App::Message::Envelope  follows  the  Null  object  pattern you can call any method on it without
       checking the object type. Note that MooseX::App::Message::Envelope objects may also have an exitcode set.
       In this case whenever the object gets stringified, it prints on STDERR/STDOUT and exits the program using
       the specified exitcode. Don't use the ovleroaded stingification if you don't want this behaviour.

       You can also pass default/fallback values to the constructor

        #!/usr/bin/env perl
        use MyApp;
        MyApp->new_with_command( some_global_option => 'something' )->run();

       If using MooseX::App::Simple your invocation script needs some modification and  call  "new_with_options"
       instead of "new_with_command".

        #!/usr/bin/env perl
        use MyApp;
        MyApp->new_with_options->run();

HOW TO CONTINUE

       Once  you  have  a  basic  working application you can make it more user friendly by adding documentation
       (either by using the app_description, app_usage, command_short_description, ... functions or  by  writing
       POD), Moose type constraints and additional plugins (eg. colorise the output).

       Make  sure  to  invoke  your script with APP_DEVELOPER=1 during development. This will come with a starup
       penalty but perform additional checks for detecting wrong attribute/type  constraint  combinations,  name
       clashes, ...

       If you want custom behaviour you could start writing your own MooseX::App::WritingPlugins.

perl v5.36.0                                       2023-10-22                         MooseX::App::Tutorial(3pm)