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

NAME

Getopt::CommandLineExports - Allow suroutines within a script to export comand line options with bash auto completion

VERSION

Version 0.04

SYNOPSIS

Example Code:

    use strict;
    use warnings;
    use Getopt::CommandLineExports qw(&regAC &parseArgsByPosition &parseArgs
        &checkArgs $scriptName @exportedSubs %cmdLines);

    $scriptName = qq[TestCommandLineExports];
    %cmdLines = (
        twoScalars          => [qw/ ONE=s TWO=s /],
        oneHash         => [qw/ ONE=s% /],
        oneList         => [qw/ ONE=s@ /],
    );
    sub twoScalars
    {
        my %h = (
            ONE => undef,
            TWO => undef,
            ( parseArgs \@_, @{$cmdLines{twoScalars}}),
        );
        print "twoScalars missing required argument:\n"
            . join( "\n", checkArgs \%h ) . "\n"
            if ( checkArgs \%h );
        return " $h{ONE} , $h{TWO} \n";
    }

    sub oneHash
    {
        my %h = (
            ONE => undef,
            ( parseArgs \@_, @{$cmdLines{oneHash}}),
        );
        print "oneHash missing required argument:\n"
            . join( "\n", checkArgs \%h ) . "\n"
            if ( checkArgs \%h );
        print "oneHash\n";
        print join("\n", (%{$h{ONE}}));
    }

    sub oneList
    {
        my %h = (
            ONE => undef,
            ( parseArgs \@_, @{$cmdLines{oneList}}),
        );
        print "oneList missing required argument:\n"
            . join( "\n", checkArgs \%h ) . "\n"
            if ( checkArgs \%h );
        print "oneList\n";
        print join("\n",@{$h{ONE}});
    }

    # The "Main" subroutine. Not included in package, must be added manually to a script

    if ( defined $ARGV[0] )
    {
        if ( defined( &{ $ARGV[0] } ) )
        {
            no strict 'refs';
            my $subRef = shift @ARGV;
            print join( "\n", &$subRef(@ARGV) ) . "\n" unless $subRef =~ /regAC/ ;
            &$subRef($scriptName, \@exportedSubs, \%cmdLines) if $subRef =~ /regAC/ ;
            exit 0;
        }
    }

    # some unit test examples:
    twoScalars "Hello1", "Hello2";
    twoScalars {ONE => "Hello1", TWO => "Hello2"};
    twoScalars "--ONE Hello1 --TWO Hello2";
    twoScalars "--ONE", "Hello1", "--TWO", "Hello2";
    twoScalars "--ONE", "Hello1", "--TWO", "Hello2", "--THREE", "Hello3"; # complains about "unknown option: three"

PURPOSE

This module is intended to provide the capability to have a single script export many subcommands in a consistant manner.

In the example above, the script is named "TestCommandLineExports". On a bash style command line, the following commands would work:

    TestCommandLineExports twoScalars --ONE "Arg1" --TWO "Arg2"

and would print:

    Arg1, Arg2

while

    TestCommandLineExports twoScalars --TWO "Arg2"
    

would print:

    twoScalars missing required argument:
    --ONE

TestCommandLineExports twoScalars may also be called through a CGI interface as well.

The principle use of this was to provide an easy, consistant, method to provide unit test ability for scripts. It also allows for a single script to export multiple subcommands and, with the included bash auto completion function, allows for the subcommands and options to integrate nicely with the bash shell.

EXPORT

A list of functions that can be exported. You can delete this section if you don't export anything, such as for a purely object-oriented module.

SUBROUTINES/METHODS

regAC

Print a bash auto completion script. Returns a script roughly sutiable for the bash_autocompletion functions:

Include roughly the following in your script:

    # this hash uses perl's Getopt::Long format 
    my %cmdLines = (
        regAC => [qw//],
        SubCommandOne => [qw/DIRECTORY=s YES_OR_NO=s ANY_FILE=s/],
        SubCommandTwo => {qw/INT=i/],
    )
    my @exportedSubs = keys %cmdLines;

    #you can use bash completion words here ("__directory__") to complete with directories
    # The default is filename completion
    my %additionalWordCompletions = (
        SubCommandOne => {
            DIRECTORY => [qw/__directory__/],
            YES_OR_NO => [qw/yes no/],
        },
    );

    if ( defined $ARGV[0] )
    {
        if ( defined( &{ $ARGV[0] } ) )
        {
            no strict 'refs';
            my $subRef = shift @ARGV;
            print join( "\n", &$subRef(@ARGV) ) . "\n" unless $subRef =~ /regAC/ ;
            &$subRef($scriptName, \@exportedSubs, \%cmdLines, \%additionalWordCompletions) if $subRef =~ /regAC/ ;
            exit 0;
        }
    }

Run from the commandline as:

    ScriptName regAC > /etc/bash_completion.d/ScriptName
    source /etc/bash_completion.d/ScriptName

or

    sudo ScriptName regAC
    source /etc/bash_completion.d/ScriptName

and the script should be registered with all the commands in:

    @Getopt::CommandLineExports::exportedSubs

and the command lines from:

    %Getopt::CommandLineExports::cmdLines

parseArgs

parse and argument list according to a command line spec in the Getopt::Long format. Returns a hash of arguments and values.

    %cmdLines = (
        function   => [qw/ REQUIRED_ARGUMENT=s OPTIONAL_ARGUMENT_ONE=s OPTIONAL_ARGUMENT_TWO=s  /],
    );

    my %h = (
        REQUIRED_ARGUMENT     => undef, # undef means the argument is required
        OPTIONAL_ARGUMENT_TWO => 'default value',  # a default value is provided
        # no mention of OPTIONAL_ARGUMENT_ONE means that it could be provided or could be undefined
        # checkArgs below will NOT include this in the missing argument list
        (   parseArgs \@_, @{$cmdLines{function}})
    );

parseArgsByPosition

parse an argument list according to a command line spec in the Getopt::Long format.

        parseArgsByPosition( \@argv, \%args, @ComSpec);

The first argument is the standard argv list. The second is a reference to a hash to receive the arguments parsed from argv (a reference is passed to allow for default values to be set. The last argument is a reference to the argument spec in Getopt::Long format

as an example:

    my %args = (ARG1 => "Default Value", ARG2 => undef);

    parseArgsByPosition( ["One", "Two", "Three"], \%args, qw/ARG1=s ARG2=s ARG3=s ARG4=s/);

should set %args to be (ARG1 => "One", ARG2 => "Two", ARG3 => "Three")

checkArgs

checkArgs will return a list of arguments that are undefined. This can be used to identify required arguments with:

    my %h = (
        REQUIRED_ARGUMENT     => undef,
        (   parseArgs \@_, @{$cmdLines{function}})
    );
    print "function missing required argument:\n"
        . join( "\n", checkArgs \%h ) . "\n"
        if ( checkArgs \%h );

AUTHOR

Robert Haxton, <robert.haxton at gmail.com>

BUGS

Please report any bugs or feature requests to bug-getopt-commandlineexports at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Getopt-CommandLineExports. 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 Getopt::CommandLineExports

You can also look for information at:

ACKNOWLEDGEMENTS

LICENSE AND COPYRIGHT

Copyright 2008-2012 Robert Haxton.

This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.

See http://dev.perl.org/licenses/ for more information.