File Coverage

blib/lib/Config/JFDI/Source/Loader.pm
Criterion Covered Total %
statement 104 105 99.0
branch 29 36 80.5
condition 4 9 44.4
subroutine 17 17 100.0
pod 0 3 0.0
total 154 170 90.5


line stmt bran cond sub pod time code
1             package Config::JFDI::Source::Loader;
2              
3 14     14   58557 use Moose;
  14         383024  
  14         73  
4 14     14   75843 use MooseX::AttributeHelpers;
  14         4857265  
  14         581  
5              
6 14     14   7838 use Config::Any;
  14         106152  
  14         480  
7 14     14   115 use Carp;
  14         22  
  14         1065  
8 14     14   7767 use List::MoreUtils qw/any/;
  14         112306  
  14         105  
9              
10             has name => qw/is ro required 0 isa Str|ScalarRef/;
11              
12             has path => qw/is ro default ./;
13              
14             has driver => qw/is ro lazy_build 1/;
15             sub _build_driver {
16 23     23   784 return {};
17             }
18              
19             has local_suffix => qw/is ro required 1 lazy 1 default local/;
20              
21             has no_env => qw/is ro required 1/, default => 0;
22              
23             has no_local => qw/is ro required 1/, default => 0;
24              
25             has env_lookup => qw/is ro/, default => sub { [] };
26              
27             has path_is_file => qw/is ro default 0/;
28              
29             has _found => qw/metaclass Collection::Array is rw isa ArrayRef/, provides => {qw/
30             elements found
31             /};
32              
33             sub _env(@) {
34 56     56   214 my $key = uc join "_", @_;
35 56         130 $key =~ s/::/_/g;
36 56         140 $key =~ s/\W/_/g;
37 56         130 return $ENV{$key};
38             }
39              
40             sub BUILD {
41 23     23 0 27739 my $self = shift;
42 23         48 my $given = shift;
43              
44 23 100       821 if (defined( my $name = $self->name )) {
45 16 50       90 if (ref $name eq "SCALAR") {
46 0         0 $name = $$name;
47             }
48             else {
49 16         65 $name =~ s/::/_/g;
50 16         57 $name = lc $name;
51             }
52 16         42 $self->{name} = $name;
53             }
54              
55 23 50       782 if (defined $self->env_lookup) {
56 23 100       841 $self->{env_lookup} = [ $self->env_lookup ] unless ref $self->env_lookup eq "ARRAY";
57             }
58              
59             }
60              
61             sub read {
62 29     29 0 94 my $self = shift;
63              
64 29         123 my @files = $self->_find_files;
65 29         132 my $cfg_files = $self->_load_files(\@files);
66 29         312919 my %cfg_files = map { (%$_)[0] => $_ } reverse @$cfg_files;
  33         242  
67 29         266 $self->_found( [ map { (%$_)[0] } @$cfg_files ] );
  33         1810  
68              
69 29         63 my (@cfg, @local_cfg);
70             {
71             # Anything that is local takes precedence
72 29         55 my $local_suffix = $self->_get_local_suffix;
  29         180  
73 29         182 for (sort keys %cfg_files) {
74              
75 33         76 my $cfg = $cfg_files{$_};
76              
77 33 100       517 if (m{$local_suffix\.}ms) {
78 8         36 push @local_cfg, $cfg;
79             }
80             else {
81 25         152 push @cfg, $cfg;
82             }
83             }
84             }
85              
86 29 50       1185 return $self->no_local ? @cfg : (@cfg, @local_cfg);
87             }
88              
89             around found => sub {
90             my $inner = shift;
91             my $self = shift;
92            
93             $self->read unless $self->{_found};
94              
95             return $inner->( $self, @_ );
96             };
97              
98             sub _load_files {
99 29     29   52 my $self = shift;
100 29         107 my $files = shift;
101 29         1062 return Config::Any->load_files({
102             files => $files,
103             use_ext => 1,
104             driver_args => $self->driver,
105             });
106             }
107              
108             sub _find_files { # Doesn't really find files...hurm...
109 29     29   52 my $self = shift;
110              
111 29 100       1027 if ($self->path_is_file) {
112 10         17 my $path;
113 10 50       345 $path = $self->_env_lookup('CONFIG') unless $self->no_env;
114 10   33     357 $path ||= $self->path;
115 10         31 return ($path);
116             }
117             else {
118 19         135 my ($path, $extension) = $self->_get_path;
119 19         80 my $local_suffix = $self->_get_local_suffix;
120 19         69 my @extensions = $self->_get_extensions;
121 19         121930 my $no_local = $self->no_local;
122            
123 19         33 my @files;
124 19 100       56 if ($extension) {
125 4 50   24   58 croak "Can't handle file extension $extension" unless any { $_ eq $extension } @extensions;
  24         31  
126 4         17 push @files, $path;
127 4 50       12 unless ($no_local) {
128 4         62 (my $local_path = $path) =~ s{\.$extension$}{_$local_suffix.$extension};
129 4         12 push @files, $local_path;
130             }
131             }
132             else {
133 15         34 push @files, map { "$path.$_" } @extensions;
  150         273  
134 15 50       66 push @files, map { "${path}_${local_suffix}.$_" } @extensions unless $no_local;
  150         281  
135             }
136              
137 19         185 return @files;
138             }
139             }
140              
141             sub _env_lookup {
142 74     74   110 my $self = shift;
143 74         214 my @suffix = @_;
144              
145 74         2255 my $name = $self->name;
146 74         2657 my $env_lookup = $self->env_lookup;
147 74         109 my @lookup;
148 74 100       216 push @lookup, $name if $name;
149 74         123 push @lookup, @$env_lookup;
150              
151 74         195 for my $prefix (@lookup) {
152 56         140 my $value = _env($prefix, @suffix);
153 56 100       288 return $value if defined $value;
154             }
155            
156 70         169 return;
157             }
158              
159             sub _get_local_suffix {
160 48     48   111 my $self = shift;
161              
162 48         3298 my $name = $self->name;
163 48         92 my $suffix;
164 48 100       1633 $suffix = $self->_env_lookup('CONFIG_LOCAL_SUFFIX') unless $self->no_env;
165             # $suffix = _env($self->name, 'CONFIG_LOCAL_SUFFIX') if $name && ! $self->no_env;
166 48   33     1811 $suffix ||= $self->local_suffix;
167              
168 48         112 return $suffix;
169             }
170              
171             sub _get_extensions {
172 19     19   26 return @{ Config::Any->extensions }
  19         208  
173             }
174              
175             sub file_extension ($) {
176 25     25 0 417 my $path = shift;
177 25 100       584 return if -d $path;
178 7         48 my ($extension) = $path =~ m{\.([^/\.]{1,4})$};
179 7         25 return $extension;
180             }
181              
182             sub _get_path {
183 19     19   29 my $self = shift;
184              
185 19         616 my $name = $self->name;
186 19         35 my $path;
187             # $path = _env($name, 'CONFIG') if $name && ! $self->no_env;
188 19 100       585 $path = $self->_env_lookup('CONFIG') unless $self->no_env;
189 19   66     575 $path ||= $self->path;
190              
191 19         61 my $extension = file_extension $path;
192              
193 19 100       164 if (-d $path) {
194 15         85 $path =~ s{[\/\\]$}{}; # Remove any trailing slash, e.g. apple/ or apple\ => apple
195 15         54 $path .= "/$name"; # Look for a file in path with $self->name, e.g. apple => apple/name
196             }
197              
198 19         74 return ($path, $extension);
199             }
200              
201              
202             1;