File Coverage

blib/lib/CBSSports/Getopt.pm
Criterion Covered Total %
statement 62 96 64.5
branch 16 36 44.4
condition 2 8 25.0
subroutine 12 17 70.5
pod 3 3 100.0
total 95 160 59.3


line stmt bran cond sub pod time code
1             package CBSSports::Getopt;
2 2     2   42599 use warnings;
  2         4  
  2         64  
3 2     2   10 use strict;
  2         4  
  2         62  
4 2     2   2417 use Getopt::Long qw();
  2         29856  
  2         69  
5 2     2   21 use File::Basename qw(basename);
  2         4  
  2         225  
6 2     2   14 use Exporter 'import';
  2         4  
  2         2371  
7             our @EXPORT = qw(GetOptions Usage Configure);
8             our $VERSION = '1.1';
9              
10             our $PRESET_OPTIONS = {
11             h => 'help',
12             help => 'help',
13             v => 'verbose',
14             verbose => 'verbose',
15             H => 'man',
16             man => 'man',
17             version => 'version',
18             };
19              
20             our $ALLOW_PRESET_OVERRIDE = 0;
21              
22             sub GetOptions {
23 6     6 1 4840 my (@option_args) = @_;
24 6         17 my %opts = ();
25 6         19 _merge_config_file_options();
26 6         26 Getopt::Long::Configure( 'no_auto_abbrev', 'no_ignore_case', 'bundling' );
27 6 50       380 Getopt::Long::GetOptions( _filter_options( \%opts, \@option_args ) ) || Usage( verbose => 0 );
28 6 50       2648 _print_version() if $opts{version};
29 6         16 _clean_options( \%opts );
30 6 100       28 return wantarray ? %opts : \%opts;
31             }
32              
33             sub Usage {
34 0     0 1 0 my %args = @_;
35 0 0       0 print $args{message}, "\n" if $args{message};
36 0 0 0     0 require Pod::Usage && Pod::Usage::pod2usage(
37             '-verbose' => $args{verbose} || 99,
38             '-sections' => '(?i:(Usage|Options))',
39             '-exitval' => 0,
40             );
41 0         0 return;
42             }
43              
44             sub Configure {
45 0     0 1 0 my @config = @_;
46 0         0 $ALLOW_PRESET_OVERRIDE = scalar grep { $_ eq 'allow_preset_override' } @_;
  0         0  
47 0         0 return Getopt::Long::Configure( grep { $_ ne 'allow_preset_override' } @_ );
  0         0  
48             }
49              
50             sub _clean_options {
51 6     6   11 my ( $opts ) = @_;
52 6         19 for my $option ( keys %$opts ) {
53 15 100       53 delete $opts->{$option} unless defined $opts->{$option}
54             }
55 6         13 return;
56             }
57              
58             sub _print_version {
59 0     0   0 my $script = basename($0);
60 0 0       0 my $version = $main::VERSION ? ( 'v' . $main::VERSION ) : '(unknown version)';
61 0         0 print "$script $version\n";
62 0         0 exit 1;
63             }
64              
65             sub _merge_config_file_options {
66 6     6   17 my $config_file = _default_config();
67 6 50 33     9180 if ( -e $config_file && open( my $fh, '<', $config_file ) ) {
68 0         0 my @options = ();
69 0         0 while ( my $line = <$fh> ) {
70 0         0 $line =~ s/\#.+$//;
71 0         0 $line =~ s/^\s+//;
72 0         0 $line =~ s/\s+$//;
73 0 0       0 next unless $line;
74 0         0 push @options, split( /\s+/, $line );
75             }
76 0         0 close $fh;
77 0         0 unshift @ARGV, @options;
78             }
79             }
80              
81             sub _default_config {
82 6     6   277 my $script = basename($0);
83 6         19 $script =~ s/\.pl$//;
84 6 50       1156 require File::HomeDir && return File::HomeDir->my_home . '/.' . $script . 'rc';
85 0         0 warn q|Can't load File::HomeDir|;
86 0         0 return;
87             }
88              
89             sub _filter_options {
90 6     6   12 my ( $opts, $option_args ) = @_;
91 6         11 my $getopt_long_options = {};
92              
93 6         11 my $found_presets = {};
94 6         9 my $illegal_preset_count = 0;
95 6         15 for my $opt (@$option_args) {
96 3         9 my ( $option_lookup, $hash_key ) = _cleanup_options($opt);
97 3         19 for my $option ( keys %$option_lookup ) {
98 6 50 33     31 if ( $PRESET_OPTIONS->{$option} && !$ALLOW_PRESET_OVERRIDE) {
    50          
99 0         0 print "By default, you may not override preset option '$option'\n"
100             . "To enable preset overriding use \"Configure( 'allow_preset_override' );\"\n";
101 0         0 $illegal_preset_count++;
102 0         0 next;
103             }
104             elsif ( $PRESET_OPTIONS->{$option} ) {
105 0         0 $found_presets->{ $PRESET_OPTIONS->{$option} }++;
106             }
107 6         29 $getopt_long_options->{$opt} = \$opts->{$hash_key};
108             }
109             }
110              
111 6 50       17 if ( $illegal_preset_count ) {
112 0         0 print "\n";
113 0         0 exit;
114             }
115              
116 0     0   0 $getopt_long_options->{'h|help'} = sub { Usage( verbose => 0 ) }
117 6 50       45 unless $found_presets->{help};
118 0     0   0 $getopt_long_options->{'H|man'} = sub { Usage( verbose => 2 ) }
119 6 50       33 unless $found_presets->{man};
120 6 50       27 $getopt_long_options->{'v|verbose+'} = \$opts->{verbose} unless $found_presets->{verbose};
121 6 50       23 $getopt_long_options->{'version'} = \$opts->{version} unless $found_presets->{version};
122              
123 6         51 return %$getopt_long_options;
124             }
125              
126             sub _cleanup_options {
127 3     3   6 my ( $opt ) = @_;
128 3         6 my $option_lookup = {};
129 3         13 my ( $option, @modifier ) = split( /([\!\+\=\:])/, $opt );
130 3         9 my $modifier = join( '', grep { $_ } @modifier );
  2         6  
131              
132 3 50       8 if ( length( $option ) == 1 ) {
133 0         0 print "Short option definition '$option' is invalid.\n"
134             . "A descriptive long option is required when defining short option (ie 'h|help')\n\n";
135 0         0 exit;
136             }
137              
138 3         11 my @alt_options = split /\|/, $option;
139 3         17 $option_lookup->{$_} = 1 for @alt_options;
140              
141 3         12 return ( $option_lookup, _determine_key( \@alt_options ) );
142             }
143              
144             sub _determine_key {
145 3     3   6 my ( $alt_options ) = @_;
146 3         60 my @keys = sort { length($b) <=> length($a) } @$alt_options;
  3         15  
147 3         6 my $key = $keys[0];
148 3         7 $key =~ s/\-/\_/g;
149 3         14 return $key;
150             }
151              
152             1;
153              
154             __END__