File Coverage

blib/lib/Config/Layered/Source/Getopt.pm
Criterion Covered Total %
statement 35 36 97.2
branch 11 12 91.6
condition n/a
subroutine 8 8 100.0
pod 0 1 0.0
total 54 57 94.7


line stmt bran cond sub pod time code
1             package Config::Layered::Source::Getopt;
2 3     3   14 use warnings;
  3         5  
  3         133  
3 3     3   17 use strict;
  3         6  
  3         92  
4 3     3   13 use Storable qw( dclone );
  3         5  
  3         129  
5 3     3   3870 use Getopt::Long;
  3         38127  
  3         20  
6 3     3   533 use Scalar::Util qw( looks_like_number );
  3         6  
  3         246  
7 3     3   19 use base 'Config::Layered::Source';
  3         5  
  3         902  
8              
9             sub get_config {
10 42     42 0 54 my ( $self ) = @_;
11 42         52 my @want;
12              
13 42         113 my $struct = dclone($self->layered->default);
14              
15 42         64 for my $key ( keys %{$struct} ) {
  42         130  
16 109 100       439 if ( ref $struct->{$key} eq 'ARRAY' ) {
    100          
    100          
17 11         25 push @want, "$key=s@";
18             } elsif ( ref $struct->{$key} eq 'HASH' ) {
19 3         36 push @want, "$key=s%"
20             } elsif ( _is_bool($struct->{$key}) ) {
21 52         143 push @want, "$key!";
22             } else {
23 43         115 push @want, "$key=s";
24             }
25             }
26              
27 42         74 my %config;
28 42         145 GetOptions( \%config, @want );
29 42         12678 return { %config };
30             }
31              
32             sub _is_bool {
33 95     95   130 my ( $any ) = @_;
34 95 100       340 return 0 unless looks_like_number($any);
35 52 100       146 return 1 if $any == 1;
36 24 50       77 return 1 if $any == 0;
37 0           return 0;
38             }
39              
40             1;
41              
42             =head1 NAME
43              
44             Config::Layered::Source::Getopt - The Command Line Source
45              
46             =head1 DESCRIPTION
47              
48             The Getopt source provides access to Getopt::Long and will configure
49             it based on the default data structure.
50              
51             The configuration of the Getopt::Long options is done in the following
52             way:
53              
54             =over 4
55              
56             =item * If the default value of a key is 0 or 1, it is treated as
57             a boolean, and the C directive is used. This will enable C<--no*>
58             options to work as expected.
59              
60             =item * If the value is a hash reference, the C directive is used,
61             and options are configured as C<--key name=value>. New hash keys will
62             be added, previously used hash keys (i.e. default configuration, previously
63             run sources) will be replaced.
64              
65             =item * If the value if an array reference, the C directive is used,
66             and options are configured as C<--key value --key value>. An array entered
67             by this source will replace a previously entered array (i.e. default
68             configuration, previous run sources).
69              
70             =item * All other situations will result in a simple string, C.
71              
72             =head1 EXAMPLE
73              
74             my $config = Config::Layered->load_config(
75             sources => [ 'ConfigAny' => { file => "/etc/myapp" } ],
76             default => {
77             foo => "bar",
78             blee => 1,
79             size => 20,
80             bax => { chicken => "eggs", }
81             baz => [ wq( foo bar blee ) ]
82             }
83             );
84              
85             The above data structure would create the following Getopt::Long
86             configuration:
87              
88             Getopts( \%config,
89             "foo=s",
90             "blee!",
91             "size",
92             "bax%",
93             "baz@",
94             );
95            
96             =head1 SOURCE ARGUMENTS
97              
98             =over 4
99              
100             =item * None
101              
102             =back
103              
104             =cut