File Coverage

lib/CHI/Config.pm
Criterion Covered Total %
statement 71 86 82.5
branch 14 28 50.0
condition 2 6 33.3
subroutine 16 18 88.8
pod 0 2 0.0
total 103 140 73.5


line stmt bran cond sub pod time code
1 3     3   150843 use 5.006;
  3         10  
  3         135  
2 3     3   18 use strict;
  3         4  
  3         121  
3 3     3   15 use warnings;
  3         6  
  3         234  
4              
5             package CHI::Config;
6              
7             our $VERSION = '0.001001'; # TRIAL
8              
9             # ABSTRACT: Define CHI configuration outside your code
10              
11             our $AUTHORITY = 'cpan:KENTNL'; # AUTHORITY
12              
13 3     3   19 use Carp qw( croak );
  3         4  
  3         358  
14 3     3   2116 use Moo qw( has around );
  3         48053  
  3         19  
15              
16             has '_constructor_caller' => (
17             is => 'ro',
18             required => 1,
19             );
20              
21             has '_config_paths' => (
22             init_arg => 'config_paths',
23             is => 'ro',
24             lazy => 1,
25             builder => '_build_config_paths',
26             );
27              
28             has '_config_files' => (
29             init_arg => 'config_files',
30             is => 'ro',
31             lazy => 1,
32             builder => '_build_config_files',
33             );
34              
35             has '_config' => (
36             init_arg => undef,
37             is => 'ro',
38             lazy => 1,
39             builder => '_build_config',
40             );
41              
42             has '_defaults' => (
43             init_arg => 'defaults',
44             is => ro =>,
45             lazy => 1,
46             builder => '_build_defaults',
47             );
48              
49             has '_drivers' => (
50             is => 'ro',
51             init_arg => undef,
52             lazy => 1,
53             builder => '_build_drivers',
54             handles => {
55             '_add_driver' => 'add_driver',
56             '_get_driver' => 'get_driver',
57             'get_cache' => 'get_cache',
58             },
59             );
60              
61             sub BUILDARGS {
62 2     2 0 45325 my ( undef, @args ) = @_;
63 2         27 my (@caller) = caller 1; # +1 for Moo
64 2 50 33     16 if ( 1 == @args and ref $args[0] ) {
65 0         0 $args[0]->{_constructor_caller} = $caller[1];
66 0         0 return $args[0];
67             }
68 2         71 return { @args, _constructor_caller => $caller[1] };
69             }
70              
71             sub BUILD {
72 2     2 0 68 my ($self) = @_;
73             ## no critic (Variables::ProhibitPackageVars)
74 2         9 local $Carp::CarpLevel = $Carp::CarpLevel + 1;
75 2         13 $self->_load_config;
76 2         10 $self->_load_defaults;
77 2         63 return;
78             }
79              
80             sub _build_config_paths {
81 0     0   0 require File::HomeDir;
82 0 0       0 my (@scan_paths) = (
83             ( exists $ENV{CHI_CONFIG_DIR} ? $ENV{CHI_CONFIG_DIR} . '/config' : () ), # From ENV
84             './chi_config', # ./
85             File::HomeDir->my_home . '/.chi/config', # ~/.chi/
86             '/etc/chi/config', # /etc/chi/
87             );
88 0         0 return \@scan_paths;
89             }
90              
91 2     2   1532 sub _build_config_files { return [] }
92              
93             sub _build_config {
94 2     2   1150 my ($self) = @_;
95 2         1778 require Config::Any;
96 2         26403 my %extras = ( use_ext => 1 );
97 2 50       7 return Config::Any->load_files( { files => $self->_config_files, %extras } ) if @{ $self->_config_files };
  2         20  
98 2         15 return Config::Any->load_stems( { stems => $self->_config_paths, %extras } );
99             }
100              
101             sub _build_defaults {
102 0     0   0 return [];
103             }
104              
105             sub _build_drivers {
106 2     2   4318 require CHI::Config::DriverPool;
107 2         15 return CHI::Config::DriverPool->new();
108             }
109              
110             sub _load_version {
111 2     2   11 my ( undef, %entry ) = @_;
112              
113 2         5 my $spec = '0.1.0';
114 2         11 my $entry_msg = "$entry{file} ( entry #$entry{entry_no} )";
115              
116 2 50 33     14 if ( $entry{spec} and $entry{spec} ne $spec ) {
117 0         0 croak "Spec version required by $entry_msg is ==$entry{spec}, this is $spec";
118             }
119 2 50       9 if ( $entry{min} ) {
120 2         1790 require version;
121 2         4631 my $min = version->parse( $entry{min} );
122 2 50       120 if ( $min > $VERSION ) {
123 0         0 croak "Minimum version required by $entry_msg is $min, we have $VERSION";
124             }
125             }
126 2 50       12 if ( $entry{max} ) {
127 0         0 require version;
128 0         0 my $max = version->parse( $entry{max} );
129 0 0       0 if ( $max < $VERSION ) {
130 0         0 croak "Maximum version required by $entry_msg is $max, we have $VERSION";
131             }
132             }
133 2         22 return;
134             }
135              
136             sub _load_entry {
137 10     10   56 my ( $self, %entry ) = @_;
138 10         67 my $context = sprintf q[%s ( entry #%s )], $entry{file}, $entry{entry_no};
139 10 100       102 my $name = ( $entry{name} ? q[ named ] . $entry{name} : q[ ] );
140 10 50       36 croak "No type specified for entry$name in $context" unless defined $entry{type};
141 10 100       128 return $self->_load_version(%entry) if 'version' eq $entry{type};
142 8 50       251 return $self->_add_driver(%entry) if 'driver' eq $entry{type};
143 0         0 croak "Unknown type $entry{type} in $context";
144             }
145              
146             sub _load_array {
147 6     6   1294 my ( $self, $array, $file ) = @_;
148 6 50       37 if ( not 'ARRAY' eq ref $array ) {
149 0         0 return croak "Payload in $file should be an ARRAY of HASH";
150             }
151 6         13 my $entry_no = 1;
152 6         13 for my $entry ( @{$array} ) {
  6         16  
153 10 50       43 if ( not 'HASH' eq ref $entry ) {
154 0         0 return croak "Entry $entry_no in $file is not a HASH";
155             }
156             $self->_load_entry(
157 10         19 %{$entry},
  10         67  
158             file => $file, #
159             entry_no => $entry_no, #
160             );
161 10         44 $entry_no++;
162             }
163 6         30 return;
164             }
165              
166             sub _load_config {
167 2     2   5 my ( $self, ) = @_;
168              
169             # Load from config first.
170 2         3 for my $result ( @{ $self->_config } ) {
  2         13  
171 4         60794 for my $file ( keys %{$result} ) {
  4         24  
172 4         27 $self->_load_array( $result->{$file}, $file );
173             }
174             }
175 2         24 return;
176             }
177              
178             sub _load_defaults {
179 2     2   4 my ( $self, ) = @_;
180 2         15 return $self->_load_array( $self->_defaults, $self->_constructor_caller );
181             }
182              
183 3     3   10603 no Moo;
  3         7  
  3         23  
184              
185             1;
186              
187             __END__