NAME Sub::Spec::CmdLine - Access Perl subs via command line VERSION version 0.31 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. And of course, if you already write subroutine spec, might as well use it. Options in %opts: * strict => BOOL (default 1) If set to 0, will still return parsed argv even if there are errors. * extra_getopts => HASHREF If specified, add extra Getopt::Long specification (as long as it doesn't clash with spec arg). This is used, for example, by run() to add general options --help, --version, --list, etc so it can mixed with spec arg options, for convenience. 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 VALUE will be parsed as YAML for nonscalar types. 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). FAQ Why is nonscalar arguments parsed as YAML instead of other markup (JSON, etc)? I think YAML is nicer in command-line because quotes are optional in a few places: $ cmd --array '[a, b, c]' --hash '{foo: bar}' versus: $ cmd --array '["a", "b", "c"]' --hash '{"foo": "bar"}' Though YAML requires spaces in some places where JSON does not. A flag to parse as JSON can be added upon request. SEE ALSO Sub::Spec Sub::Spec::Pod MooseX::Getopt AUTHOR Steven Haryanto 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.