NAME

Sub::Spec::CmdLine - Access Perl subs via command line

VERSION

version 0.22

SYNOPSIS

In your module:

package YourModule;
our %SPEC;

$SPEC{foo} = {
    summary => 'Foo!',
    args => {
        arg  => ...,
        arg2 => ...
    },
    ...
};
sub foo {
   ...
}

...
1;

In your script:

#!/usr/bin/perl
use Sub::Spec::CmdLine qw(run);
run(module=>'YourModule', sub=>'foo');

In the command-line:

% script.pl --help
% script.pl --arg value --arg2 '[an, array, in, yaml, syntax]' ...

For running multiple subs, in your script:

use Sub::Spec::CmdLine qw(run);
run(subcommands => {
    foo => { module=>'YourModule', sub=>'foo'},
    bar => { module=>'YourModule', sub=>'bar'},
    ...
});

In the command-line:

% script.pl --help
% script.pl --list
% script.pl foo --help
% script.pl foo --arg value --arg2 ...
% script.pl bar --blah ...

DESCRIPTION

This module utilize sub specs (as defined by Sub::Spec) to let your subs be accessible from the command-line.

This module uses Log::Any logging framework. Use something like Log::Any::App, etc to see more logging statements for debugging.

NOTE: This module is not ready for public consumption yet. It will be after Data::Sah and Sub::Spec is released.

FUNCTIONS

None of the functions are exported by default, but they are exportable.

parse_argv(\@argv, $sub_spec[, \%opts]) => \%args

Using information in spec's args clause, parse command line argument @argv into hash %args, suitable for passing into subs.

Uses Getopt::Long to parse the result.

As with GetOptions, this function modifies its argument, @argv.

Why would one use this function instead of using Getopt::Long directly? Among other reasons, we want YAML parsing (ability to pass data structures via command line) and parsing of arg_pos and arg_greedy.

Options in %opts:

  • strict => BOOL (default 1)

    If set to 0, will still return parsed argv even if there are errors.

How parse_argv() translates the args spec clause

Bool types can be specified using

--argname

or

--noargname

All the other types can be specified using

--argname VALUE

or

--argname=VALUE

where VALUE is assumed to be in YAML markup, except when YAML loading failed then it will be assumed to be a string literal. Example:

--argname '[1, 2, 3]'

then $args{argname} will contain a hashref [1, 2, 3]. But with:

--argname '[1, 2, 3'

then $args{argname} will contain a string '[1, 2, 3' since YAML parsing failed.

parse_argv() also takes arg_pos and arg_greedy type clause in schema into account, for example:

$SPEC{multiply2} = {
    summary => 'Multiply 2 numbers (a & b)',
    args => {
        a => ['num*' => {arg_pos=>0}],
        b => ['num*' => {arg_pos=>1}],
    }
}

then on the command-line any of below is valid:

% multiply2 --a 2 --b 3
% multiply2 2 --b 3; # first non-option argument is fed into a (arg_pos=0)
% multiply2 2 3;     # first argument is fed into a, second into b (arg_pos=1)

gen_usage($sub_spec) => TEXT

Generate usage information for a sub (typically used for --help).

format_result($sub_res[, \%opts]) => TEXT

Format result from sub into various formats

Options:

  • format => FORMAT (optional, default 'text')

    Format can be 'text' (pretty text or nonpretty text), 'pretty' (pretty text, generated by Data::Format::Pretty::Console under interactive=1), 'nopretty' (also generated by Data::Format::Pretty::Console under interactive=0), 'yaml', 'json', 'php' (generated by PHP::Serialization's serialize()).

  • default_success_message => STR (optional, default none)

    If output format is text ('text', 'pretty', 'nopretty') and result code is 200 and there is no data returned, this default_success_message is used. Example: 'Success'.

run(%args)

Run subroutine(s) from the command line, which essentially comprises these steps:

  • Parse command-line options in @ARGV (using parse_argv())

    Also, display help using gen_usage() if given '--help' or '-h' or '-?'.

  • Call sub

  • Format the return value from sub (using format_result())

  • Exit with appropriate exit code

    0 if 200, or CODE-300.

Arguments:

  • summary => STR

  • module => STR

    Currently this must be supplied if you want --version, even if you use subcommands. --version gets $VERSION from the main module.

  • sub => STR

  • spec => HASH | CODEREF

    Instead of trying to look for the spec using module and sub, use the supplied spec.

  • help => STRING | CODEREF

    Instead of generating help using gen_usage() from the spec, use the supplied help message (or help code, which is expected to return help text).

  • subcommands => {NAME => {ARGUMENT=>...}, ...} | CODEREF

    module and sub should be specified if you only have one sub to run. If you have several subs to run, assign each of them to a subcommand, e.g.:

    summary     => 'Maintain a directory containing git repos',
    module      => 'Git::Bunch',
    subcommands => {
      check   => { },
      backup  => { }, # module defaults to main module argument,
      sync    => { }, # sub defaults to the same name as subcommand name
    },

    Available argument for each subcommand: module (defaults to main module argument), sub (defaults to subcommand name), summary, help, category (for arrangement when listing commands), run, complete_arg, complete_args.

    Subcommand argument can be a code reference, in which case it will be called with %args containing: name (subcommand name), args (arguments to run()). The code is expected to return structure for argument with specified name, or, when name is not specified, a hashref containing all subcommand arguments.

  • run => CODEREF

    Instead of running command by invoking subroutine specified by module and sub, run this code instead. Code is expected to return a response structure ([CODE, MESSAGE, DATA]).

  • exit => BOOL (optional, default 1)

    If set to 0, instead of exiting with exit(), return the exit code instead.

  • load => BOOL (optional, default 1)

    If set to 0, do not try to load (require()) the module.

  • allow_unknown_args => BOOL (optional, default 0)

  • complete_arg => {ARGNAME => CODEREF, ...}

    Under bash completion, when completing argument value, you can supply a code to provide its completion. Code will be called with %args containing word, words, arg, args.

  • complete_args => CODEREF

    Under bash completion, when completing argument value, you can supply a code to provide its completion. Code will be called with %args containing word, words, arg, args.

  • custom_completer => CODEREF

    To be passed to BashComplete's bash_complete_spec_arg(). This can be used e.g. to change bash completion code (e.g. calling bash_complete_spec_arg() recursively) based on context.

run() can also perform completion for bash (if Sub::Spec::BashComplete is available). To get bash completion for your perlprog, just type this in bash:

% complete -C /path/to/perlprog perlprog

You can add that line in bash startup file (~/.bashrc, /etc/bash.bashrc, etc).

SEE ALSO

Sub::Spec

Sub::Spec::Pod

MooseX::Getopt

AUTHOR

Steven Haryanto <stevenharyanto@gmail.com>

COPYRIGHT AND LICENSE

This software is copyright (c) 2011 by Steven Haryanto.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.