The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Getopt::Valid - Extended processing and validation of command line options

DESCRIPTION

Implements an extended getopt mechanism relying on Getopt::Long but provides extended validation and filtering capabilities.

Useful for shell scripts.

I wrote this, because i need input validation / processing in most of my scripts. This keeps it formal and readable while not making me re-implement the wheel over and over again.

The dependency footprint is rather small (only Getopt::Long).

SYNOPSIS

#!/usr/bin/perl

use strict;
use warnings;
use Getopt::Valid;

#
# VALIDATION DEFINITION
#

my $validation_ref = {
    
    # name of the program
    name => 'MyScript', # fallback to $0, if not set
    
    # version info
    version => '1.0.1', # fallback to $main::VERSION or "unknown", if not set
    
    # the struct of the params
    struct => [
        
        # extended example
        'somestring|s=s' => {
            description => 'The description of somestring',
            constraint  => sub { my ( $val ) = @_; return index( $val, '123' ) > -1 },
            required    => 1,
        },
        
        # Example using only validator and fallback to default description.
        # This value is optional (mind: no "!")
        'otherstring|o=s' => qr/^([a-z]+)$/, # all lowercase words
        
        # Example of using integer key with customized description.
        # This value is optional (mind the "!")
        'someint|i=i!' => 'The description of someint',
        
        # Bool value using the default description
        'somebool|b' => undefm
        
        # the following is implicit, prints out the usag and exists.. can be overwritten
        #'help|h' => 'Show this help'
    ]
};

#
# FUNCTIONAL USAGE
#

my $validated_args_ref = GetOptionsValid( $validation_ref )
    || die "Failed to validate input\n".
        join( "\nERRORS:\n", @Getopt::Valid::ERRORS, "\n\nUSAGE:\n", $Getopt::Valid::USAGE );

# acces the user input
print "Got $validated_args_ref->{ somestring }\n";


#
# OBJECT USAGE
#

my $opt = Getopt::Valid->new( $validation_ref );

# collect data from @ARGV.. you could manipulate @ARGV and run again..
$opt->collect_argv;

# whether validates
if ( $opt->validate ) {
    
    # acces valid input data
    print "Got ". $opt->valid_args->{ somestring }. "\n";
}

# oops, not valid
else {
    
    # print errors
    print "Oops ". $opt->errors( " ** " ). "\n";
    
    # print usage
    print $opt->usage();
}

VALIDATOR SYNTAX

  • name STRING

    Name of the program. Use in help output.

    Defaults to $0

  • version VERSION STRING

    Version of the program. Used in help output. Tries $main::VERSION, if not set.

    Defaults to "unknown"

  • underscore BOOL

    Whether "-" characters in arguments shall be rewritten to "_" in the result.

    Default: 0 (disabled)

  • struct ARRAYREF

    Structure of the arguments. The order will be respected in the help generation.

    Can be written in 4 styles

    • SCALAR

      $struct_ref = [
          'argument-name|a=s' => 'Description text for help',
          'other-arg' => 'Description text for help'
      ];
    • REGEXP

      $struct_ref = [
          'argument-name|a=s' => qr/(bla|blub),
      ];
    • CODE

      $struct_ref = [
          'argument-name|a=s' => sub {
              my ( $value, $name, $validator ) = @_;
              warn "Checking '$name' = '$value'\n";
              return $value eq 'ok';
          }
      ];
    • HASH

      $struct_ref = [
          'argument-name|a=s' => {
              
              # the description for the help
              description => 'Description text for help',
              
              # default value, if not given
              default => 'Some Default',
              
              # whether required (redundant for bool), default: 0
              required => 1|0,
              
              # constraint can be regexp or code-ref, see above
              constraint => sub { .. },
              
              # modify value before handing to constraint (if any)
              prefilter => sub {
                  my ( $value, $name, $validator ) = @_;
                  return "THE NEW $value\n";
              },
              
              # modify value after constraint check (if any). runs only if valid (or no constraint).
              postfilter => sub {
                  my ( $value, $name, $validator ) = @_;
                  return "THE NEW $value\n";
              },
              
              # trigger is called in any case, even if arg not given
              anytrigger => sub {
                  my ( $value, $name, $validator ) = @_;
                  return ; # ignored
              },
              
              # trigger is called if value is defined / given (independent if validated)
              settrigger => sub {
                  my ( $value, $name, $validator ) = @_;
                  return ; # ignored
              },
              
              # trigger is called if value is validated (or no validator is given)
              oktrigger => sub {
                  my ( $value, $name, $validator ) = @_;
                  return ; # ignored
              },
              
              # trigger is called if value is invalid (or no validator is given)
              oktrigger => sub {
                  my ( $value, $name, $validator ) = @_;
                  return ; # ignored
              },
          }
      ];

EXPORTED METHODS

In functional context, you can access the errors via @Getopt::Valid::ERRORS and the usage via $Getopt::Valid::USAGE

GetOptionsValid $validator_ref

See "VALIDATOR SYNTAX"

CLASS METHODS

new $validator_ref

Constructor. See "VALIDATOR SYNTAX"

collect_argv

Collect args found in @ARGV using Getopt::Long#GetOptions

args

Set/get args.

validate

Performs validation of the input. Returns differently in array- or scalar-context.

  • Array context

    Returns ( has_errors, hashref_of_valid_input )

    my ( $valid, $input_ref ) = $obj->validate();
    if ( $valid ) {
        print "All good, got arg 'some_arg': $input_ref->{ some_arg }\n";
    }
  • Scalar context

    Returns whether validation was successfull (or any error ocurred)

    if ( scalar $obj->validate() ) {
        print "All good, got arg 'some_arg': ". $opt->valid_args->{ some_arg }. "\n";
    }

valid_args

Returns validated args

usage

Returns usage as string

errors

Returns errors as joined string or array of strings of the last valid-run

SEE ALSO

AUTHOR

  • Ulrich Kautz <uk@fortrabbit.de>

COPYRIGHT AND WARRANTY

Copyright (c) 2012 the "AUTHOR" as listed above.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

LICENCSE

This library is free software and may be distributed under the same terms as perl itself.