pericmd 043: Generating CLI applications (App::GenPericmdScript)

Most Perinci::CmdLine-based CLI scripts are basically a variation of:

#!perl

use Perinci::CmdLine::Any;
Perinci::CmdLine->new(
    url => '/some/riap/url/to/function',
    ...
)->run;

Due to my laziness and strict adherence to the DRY principle, I create a script gen-pericmd-script (distributed with App::GenPericmdScript) to generate this boilerplate. To see it in action, first install Perinci::Examples (if you haven’t done so) and then run:

% gen-pericmd-script /Perinci/Examples/gen_array

The result is spewed to standard output:

#!/mnt/home/s1/perl5/perlbrew/perls/perl-5.18.4/bin/perl

# Note: This script is a CLI interface to Riap function /Perinci/Examples/gen_array
# and generated automatically using App::GenPericmdScript version 0.04

# DATE
# VERSION

use 5.010001;
use strict;
use warnings;

use Perinci::CmdLine::Any;

Perinci::CmdLine::Any->new(
    url => "/Perinci/Examples/gen_array",
)->run;

# ABSTRACT: Generate an array of specified length
# PODNAME: script

If you analyze the output, the abstract is also written for you. This is taken from the Rinci metadata which is retrieved by gen-pericmd-script via a Riap meta request.

If you specify -o option, e.g. -o /home/s1/bin/gen-array, the generated script is written to the specified path and also set chmod 0755 as well as tab completion is activated (if you have shcompgen installed). There are of course several options to customize the script, like the Perinci::CmdLine backend module to use, whether to activate logging, specify subcommands, whether to add some code before instantiating Perinci::CmdLine object, and so on.

App::GenPericmdScript is actually best used with Dist::Zilla. There’s a plugin called DZP:Rinci::ScriptFromFunc which uses to App::GenPericmdScript to generate scripts for you during build. If some have a dist.ini like this:

name=App-GenArray
version=0.01

[Rinci::ScriptFromFunc]
script= url=/Perinci/Examples/gen_array

[@Classic]

[PodWeaver]
config_plugin=-Rinci

After you run dzil build, you’ll get something like this in App-GenArray-0.01/bin/gen-array:

#!perl

# Note: This script is a CLI interface to Riap function /Perinci/Examples/gen_array
# and generated automatically using App::GenPericmdScript version 0.04

# DATE
# VERSION

use 5.010001;
use strict;
use warnings;

use Perinci::CmdLine::Any;

$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0;

Perinci::CmdLine::Any->new(
    url => "/Perinci/Examples/gen_array",
)->run;

# ABSTRACT: Generate an array of specified length
# PODNAME: gen-array

__END__

=pod

=head1 SYNOPSIS

Usage:

 % gen-array [options] <len>

=head1 DESCRIPTION

Also tests result schema.

=head1 OPTIONS

C<*> marks required options.

=over

=item B<--config-path>=I<s>

Set path to configuration file.

Can be specified multiple times.

=item B<--config-profile>=I<s>

Set configuration profile to use.

=item B<--format>=I<s>

Choose output format, e.g. json, text.

=item B<--help>, B<-h>, B<-?>

Display this help message.

=item B<--json>

Set output format to json.

=item B<--len>=I<i>*

Array length.

Default value:

 10

=item B<--naked-res>

When outputing as JSON, strip result envelope.

By default, when outputing as JSON, the full enveloped result is returned, e.g.:

    [200,"OK",[1,2,3],{"func.extra"=>4}]

The reason is so you can get the status (1st element), status message (2nd
element) as well as result metadata/extra result (4th element) instead of just
the result (3rd element). However, sometimes you want just the result, e.g. when
you want to pipe the result for more post-processing. In this case you can use
`--naked-res` so you just get:

    [1,2,3]


=item B<--no-config>

Do not use any configuration file.

=item B<--version>, B<-v>

=back

=head1 ENVIRONMENT

GEN_ARRAY_OPT

=head1 FILES

~/gen-array.conf

/etc/gen-array.conf

=cut

When you run perldoc on this script, you’ll get something like:

GEN-ARRAY(1)               User Contributed Perl Documentation               GEN-ARRAY(1)



SYNOPSIS
       Usage:

        % gen-array [options] <len>

DESCRIPTION
       Also tests result schema.

OPTIONS
       "*" marks required options.

       --config-path=s
           Set path to configuration file.

           Can be specified multiple times.

       --config-profile=s
           Set configuration profile to use.

       --format=s
           Choose output format, e.g. json, text.

       --help, -h, -?
           Display this help message.

       --json
           Set output format to json.

       --len=i*
           Array length.

           Default value:

            10

       --naked-res
           When outputing as JSON, strip result envelope.

           By default, when outputing as JSON, the full enveloped result is returned,
           e.g.:

               [200,"OK",[1,2,3],{"func.extra"=>4}]

           The reason is so you can get the status (1st element), status message (2nd
           element) as well as result metadata/extra result (4th element) instead of just
           the result (3rd element). However, sometimes you want just the result, e.g.
           when you want to pipe the result for more post-processing. In this case you
           can use `--naked-res` so you just get:

               [1,2,3]

       --no-config
           Do not use any configuration file.

       --version, -v

ENVIRONMENT
       GEN_ARRAY_OPT

FILES
       ~/gen-array.conf

       /etc/gen-array.conf

Advertisements

One thought on “pericmd 043: Generating CLI applications (App::GenPericmdScript)

  1. I know I should update the post instead, but the WordPress editor someitmes messes up the verbatim HTML tags (this has happened a few times). So:

    UPDATE: The Dist::Zilla plugin has been renamed to DZP:GenPericmdScript.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s