The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

MooX::Role::CliOptions - Wrapper to simplify using Moo with Getopt::Long

VERSION

Version 0.01

SYNOPSIS

This is a minimal script that composes MooX::Role::CliOptions.

    #!perl!
    package My::CliOptions;
  
    use Moo;
    with 'MooX::Role::CliOptions';
  
    # initialize script attributes/variables
    has option1 => (
        is => 'ro',
        isa => sub {
            die 'Illegal value for option1'
              unless $_[0] =~ /^foo|bar$/;
        },
    );
  
    ...
  
    # this is what makes the script a modulino
    do {
        my $app = __PACKAGE__->init(
            argv     => \@ARGV,
            add_opts => [ 'option1=s' ],
        );
        exit $app->run;
    } unless caller();
  
    sub run {
        my $self = shift;
  
        ...
  
        return 0;
    }
  
    1; # must be present to satisfy "require" when testing
    __END__
  

DESCRIPTION

This role was written to help standardize command line script behavior and greatly improve their testability.

EXPORTS

None.

ATTRIBUTES

Three attributes are provided for the composing package, two of which are accepted as command line arguments and the third being created from the final @ARGV values after processing by Getopt::Long.

NOTE: Both --debug and --verbose can be disabled by setting the environment variable MRC_NO_STDOPTS to a "true" value before composing MooX::Role::CliOptions into you script. This allows you to completely remove them or redefine them to suit your needs if so desired. I.e. you might want --debug to be "off" by default. If you decide to redefine them you must supply a suitable attribute in your script. This does NOT affect --help or --man.

 #!perl!
  
 # redefine --debug to be off by default and --verbose to indicate a level
 # between 0 and 5
 BEGIN {
    $ENV{MRC_NO_STDOPTS} = 1;
 }
  
 has debug => (
    is => 'ro',
    default => 0,
 );
  
 has verbose => (
    is => 'ro',
    isa => sub {
        die 'illegal value for --verbose'
          unless $_[0] >= 0 && $_[0] <= 5;
    },
    default => 0,
 );
  
 use Moo;
 with 'MooX::Role::CliOptions';
  
 do {
    my $app = __PACKAGE__->init(
        argv => \@ARGV,
        add_opts => [
            'debug',
            'verbose=i',
        ],
    );
  
    exit $app->run;
 } unless caller();
  
 ...
  

debug (Boolean read-only)

Commonly used to either enable extra reports and/or disable potentially dangerous operations such as database modifications.

Default: ON. Is turned off with --nodebug on the command line.

Note: Implies the setting for verbose if --verbose or --noverbose is not explicitly set on the command line.

verbose (Boolean read-only)

Tyically used to add extra information to the output. Often used in conjunction with CL--debug>.

Default: Will be the same as debug if not explicitly set with either --verbose or --noverbose. This behaviour was chosen since that is the most common usage in the author's experience.

The most likely patter would be

 # in a crontab where no visible output would be desired
 /my_script --nodebug
  
 # manually run from the cli if screen output is desired
 /my_script --nodebug --verbose

argv (read-only)

Returns an arrayref to the contents of @ARGV after processing by Getopt::Long.

OTHER COMMAND LINE ARGUMENTS

--help

Will use pod2usage to display the SYNOPSIS or USAGE POD section if available.

--man

Will use pod2usage to display the full POD if available.

METHODS

init

This is the workhorse that performs necessary actions and makes the actual call to the composing package's new constructor. Its return value is the resulting object of the composing package type.

Parameters

argv (required)

Typically passed in as follows:

 my $app = __PACKAGE__->init( argv => \@ARGV );
  

This will be passed to Getopt::Long for processing. Any remaining elements will be left in @ARGV. They can also be accessed via $app->argv.

add_opts (optional)

You can add your own command line options by using this. Simply place the specifications for any additional options that you want in an array ref as shown below and be sure to declare an attribute to hold the option data as processed by Getopt::Long. (See the example script to make things clear.)

 # in your script
 has custom1 => (
    is => 'ro',
    isa => sub { ... },
 );
  
 do {
    my $app = __PACKAGE__->init(
        argv => \@ARGV,
        add_opts => [
            'custom1=s',
        ],
    );
    exit ($app->run || 0);
 } unless caller();
  

The above snippet would tell Getopt::Long to accept a command line option named custom1 that must be a string and place it in the custom1 attribute that was declared. You may use any kind of isa or coerce test that you deem are needed as well as a default.

SEE ALSO

examples/moodulino.pl for a fully functional script,

AUTHOR

Jim Bacon, <boftx at cpan.org>

BUGS

Please report any bugs or feature requests to bug-moox-role-modulino at rt.cpan.org, or through the web interface at https://rt.cpan.org/NoAuth/ReportBug.html?Queue=MooX-Role-CliOptions. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

You can find documentation for this module with the perldoc command.

    perldoc MooX::Role::CliOptions

You can also look for information at:

LICENSE AND COPYRIGHT

Copyright 2019 Jim Bacon.

This program is free software; you can redistribute it and/or modify it under the terms of the the Artistic License (2.0). You may obtain a copy of the full license at:

http://www.perlfoundation.org/artistic_license_2_0

Any use, modification, and distribution of the Standard or Modified Versions is governed by this Artistic License. By using, modifying or distributing the Package, you accept this license. Do not use, modify, or distribute the Package, if you do not accept this license.

If your Modified Version has been derived from a Modified Version made by someone other than you, you are nevertheless required to ensure that your Modified Version complies with the requirements of this license.

This license does not grant you the right to use any trademark, service mark, tradename, or logo of the Copyright Holder.

This license includes the non-exclusive, worldwide, free-of-charge patent license to make, have made, use, offer to sell, sell, import and otherwise transfer the Package with respect to any patent claims licensable by the Copyright Holder that are necessarily infringed by the Package. If you institute patent litigation (including a cross-claim or counterclaim) against any party alleging that the Package constitutes direct or contributory patent infringement, then this Artistic License to you shall terminate on the date that such litigation is filed.

Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.