File Coverage

blib/lib/Getopt/Mini.pm
Criterion Covered Total %
statement 56 74 75.6
branch 29 36 80.5
condition 8 12 66.6
subroutine 7 9 77.7
pod 0 3 0.0
total 100 134 74.6


line stmt bran cond sub pod time code
1             #
2             # This file is part of Getopt-Mini
3             #
4             # This software is copyright (c) 2013 by Rodrigo de Oliveira.
5             #
6             # This is free software; you can redistribute it and/or modify it under
7             # the same terms as the Perl 5 programming language system itself.
8             #
9             package Getopt::Mini;
10 2     2   80675 use strict;
  2         7  
  2         124  
11 2     2   11 use warnings;
  2         3  
  2         82  
12 2     2   314453 use utf8::all;
  2         383084  
  2         16  
13            
14             our $VERSION = '0.02';
15            
16             sub import {
17 2     2   40 my $class = shift;
18 2         6 my %args = @_;
19 2 50       15 if( defined $args{var} ) {
    100          
20 0 0       0 if( $args{var} !~ /::/ ) {
21 0         0 my $where = caller(0);
22 0         0 $args{var} = $where . '::' . $args{var};
23             }
24 0         0 my %hash = getopt( arrays=>0 );
25 2     2   8105 no strict 'refs';
  2         4  
  2         172  
26 0         0 *{ $args{var} } = \%hash;
  0         0  
27             }
28             elsif( defined $args{later} ) {
29             # import getopt() so that user can call it
30 1         3 my $where = caller(0);
31 2     2   9 no strict 'refs';
  2         4  
  2         2704  
32 1         2 *{ $where . '::getopt' } = \&getopt;
  1         6  
33             }
34             else {
35             # into %ARGV
36 1         2 getopt( arrays=>0 );
37             }
38             #unshift @ARGV, @barewords;
39 2         2112 return;
40             }
41              
42             sub getopt_array {
43 0     0 0 0 getopt( arrays=>1 , @_ );
44             }
45              
46             sub getopt {
47 6     6 0 2659 my ( $last_opt, $last_done, %hash );
48 0         0 my %opts;
49             # get my own opts
50             my @argv = @_ == 0
51             ? @ARGV
52 6 50       16 : do {
53 6         16 %opts = @_;
54 6 100       8 @{ delete $opts{argv} || [] };
  6         40  
55             };
56 6 100       19 @argv = @ARGV unless @argv > 0;
57 6 100       18 return () unless @argv;
58 5         13 $hash{_argv} = [ @argv ];
59 5         11 while(@argv) {
60 28         36 my $arg = shift @argv;
61 28 100       96 if ( $arg =~ m/^-(\w)$/ ) { # single letter
    100          
62 7         12 my $flag = $1;
63 7 100 66     35 if( $opts{hungry_flags} && defined $argv[0] && $argv[0] !~ /^-/ ) {
      66        
64 2         4 $hash{$flag} = shift @argv;
65             } else {
66 5         11 $hash{$flag} ++;
67             }
68 7         17 $last_done= 1;
69             }
70             elsif ( $arg =~ m/^-+(.+)/ ) {
71 9         20 $last_opt = $1;
72 9         12 $last_done=0;
73 9 50       15 if( $last_opt =~ m/^(.*)\=(.*)$/ ) {
74 0         0 push @{ $hash{$1} }, $2 ;
  0         0  
75 0         0 $last_done= 1;
76             } else {
77 9 100       40 $hash{$last_opt} = [] unless ref $hash{$last_opt};
78             }
79             }
80             else {
81             #$arg = Encode::encode_utf8($arg) if Encode::is_utf8($arg);
82 12 100 100     67 $last_opt ='' if !$opts{arrays} && ( $last_done || ! defined $last_opt );
      33        
83 12         12 push @{ $hash{$last_opt} }, $arg;
  12         27  
84 12         30 $last_done = 1;
85             }
86             }
87             # convert single option => scalar
88 5         15 for( keys %hash ) {
89 23 100       54 next unless ref( $hash{$_} ) eq 'ARRAY';
90 17 100       18 if( @{ $hash{$_} } == 0 ) {
  17 100       35  
  15         34  
91 2 50       8 $hash{$_} = $opts{define} ? 1 : ();
92             } elsif( @{ $hash{$_} } == 1 ) {
93 8         24 $hash{$_} = $hash{$_}->[0];
94             }
95             }
96 5 50       12 if( defined wantarray ) {
97 5         37 return %hash;
98             } else {
99 0           %ARGV = %hash;
100             }
101             }
102              
103             sub getopt_validate {
104 0     0 0   my %args = @_;
105 0           $args{''}={isa=>'Any'}; # ignores this
106 0           require Data::Validator;
107 0           my $rule = Data::Validator->new( %args );
108 0           @_ = ($rule, %ARGV );
109 0           goto \&Data::Validator::validate;
110             }
111            
112             1;
113              
114             __END__
115              
116             =pod
117              
118             =head1 NAME
119              
120             Getopt::Mini
121              
122             =head1 VERSION
123              
124             version 0.02
125              
126             =head1 SYNOPSIS
127              
128             use Getopt::Mini;
129             say $ARGV{'flag'};
130              
131             =head1 DESCRIPTION
132              
133             This is, yup, yet another Getopt module, a very lightweight one. It's not declarative
134             in any way, ie, it does not support specs, like L<Getopt::Long> et al do.
135              
136             On the other hand, it can validate your parameters using the L<Data::Validator> syntax.
137             But that's a hidden feature for now (you'll need to install L<Data::Validator> yourself
138             and find a way to run it by reading this source code).
139              
140             =head1 NAME
141              
142             Getopt::Mini - yet another yet-another Getopt module
143              
144             =head1 VERSION
145              
146             version 0.02
147              
148             =head1 USAGE
149              
150             The rules:
151              
152             * -<char>
153             does not consume barewords (ie. -f, -h, ...)
154             unless you set hungry_flags=>1
155              
156             * -<str> <bareword>
157             * --<str> <bareword>
158             will eat up the next bare word (-type f, --file f.txt)
159              
160             * -<char|str>=<val> and --<str>=<val>
161             consumes its value and nothing more
162              
163             * <str>
164             gets pushed into an array in $ARGV{''}
165              
166             Some code examples:
167              
168             perl myprog.pl -h -file foo --file bar
169             use Getopt::Mini; # parses the @ARGV into %ARGV
170             say YAML::Dump \%ARGV;
171             ---
172             h: 1
173             file:
174             - foo
175             - bar
176            
177             # single flags like -h are checked with exists:
178            
179             say 'help...' if exists $ARGV{'h'};
180              
181             # barewords are pushed into the key '_'
182            
183             perl myprog.pl file1.c file2.c
184             say "file: $_" for @{ $ARGV{''} };
185              
186             Or you can just use a modular version:
187              
188             use Getopt::Mini later=>1; # nothing happens
189              
190             getopt; # imports into %ARGV
191             my %argv = getopt; # imports into %argv instead
192              
193             =head3 array mode
194              
195             There's also a special mode that can be set with C<array => 1> that will
196             make a flag consume all following barewords:
197              
198             perl myprog.pl -a -b --files f1.txt f2.txt
199             use Getopt::Mini array => 1;
200             say YAML::Dump \%ARGV;
201             ---
202             h: ~
203             file:
204             - foo
205             - bar
206              
207             =head1 BUGS
208              
209             This is *ALPHA* software. And despite its small footprint,
210             this is lurking with nasty bugs and potential api changes.
211              
212             Complaints should be filed to the Getopt Foundation, which
213             has been treating severe NIH syndrome since 1980.
214              
215             =head1 SEE ALSO
216              
217             L<Getopt::Whatever> - no declarative spec like this module,
218             but the options in %ARGV and @ARGV are not where I expect them
219             to be.
220              
221             L<Getopt::Casual> - similar to this module, but very keen on
222             turning entries into single param options.
223              
224             =head1 AUTHOR
225              
226             Rodrigo de Oliveira <rodrigolive@gmail.com>
227              
228             =head1 COPYRIGHT AND LICENSE
229              
230             This software is copyright (c) 2013 by Rodrigo de Oliveira.
231              
232             This is free software; you can redistribute it and/or modify it under
233             the same terms as the Perl 5 programming language system itself.
234              
235             =cut