File Coverage

blib/lib/Config/ZOMG/Source/Loader.pm
Criterion Covered Total %
statement 104 105 99.0
branch 30 36 83.3
condition 6 12 50.0
subroutine 17 17 100.0
pod 0 5 0.0
total 157 175 89.7


line stmt bran cond sub pod time code
1             package Config::ZOMG::Source::Loader;
2             {
3             $Config::ZOMG::Source::Loader::VERSION = '1.000000';
4             }
5              
6 12     12   24635 use Moo;
  12         17288  
  12         105  
7 12     12   6613 use Sub::Quote 'quote_sub';
  12         3704  
  12         598  
8              
9 12     12   16725 use Config::Any;
  12         176827  
  12         509  
10 12     12   134 use List::Util 'first';
  12         30  
  12         20136  
11              
12             has name => (
13             is => 'rw',
14             );
15              
16             has path => (
17             is => 'ro',
18             default => quote_sub q{ '.' },
19             );
20              
21             has driver => (
22             is => 'ro',
23             default => quote_sub q[ {} ],
24             );
25              
26             has local_suffix => (
27             is => 'ro',
28             default => quote_sub q{ 'local' },
29             );
30              
31             has no_env => (
32             is => 'ro',
33             default => quote_sub q{ 0 },
34             );
35              
36             has no_local => (
37             is => 'ro',
38             default => quote_sub q{ 0 },
39             );
40              
41             has env_lookup => (
42             is => 'ro',
43             default => quote_sub q{ [] },
44             );
45              
46             has path_is_file => (
47             is => 'ro',
48             default => quote_sub q{ 0 },
49             );
50              
51             has _found => (
52             is => 'rw',
53             );
54              
55             sub _env (@) {
56 34     34   113 my $key = uc join "_", @_;
57 34         122 $key =~ s/::/_/g;
58 34         76 $key =~ s/\W/_/g;
59 34         94 return $ENV{$key};
60             }
61              
62             sub BUILD {
63 19     19 0 34926 my $self = shift;
64 19         41 my $given = shift;
65              
66 19 100       219 if (defined( my $name = $self->name )) {
67 10 50       50 if (ref $name eq "SCALAR") {
68 0         0 $name = $$name;
69             }
70             else {
71 10         31 $name =~ s/::/_/g;
72 10         32 $name = lc $name;
73             }
74 10         45 $self->name($name);
75             }
76              
77 19 100 66     670 $self->{env_lookup} = [ $self->env_lookup ]
78             if defined $self->env_lookup && ref $self->env_lookup ne 'ARRAY';
79             }
80              
81             sub read {
82 18     18 0 37 my $self = shift;
83              
84 18         71 my @files = $self->_find_files;
85 18         84 my $cfg_files = $self->_load_files(\@files);
86 18         147171 my %cfg_files = map { (%$_)[0] => $_ } reverse @$cfg_files;
  20         117  
87 18         75 $self->_found( [ map { (%$_)[0] } @$cfg_files ] );
  20         139  
88              
89 18         158 my (@cfg, @local_cfg);
90             {
91             # Anything that is local takes precedence
92 18         37 my $local_suffix = $self->_get_local_suffix;
  18         96  
93 18         92 for (sort keys %cfg_files) {
94              
95 20         42 my $cfg = $cfg_files{$_};
96              
97 20 100       226 if (m{$local_suffix\.}ms) {
98 6         25 push @local_cfg, $cfg;
99             }
100             else {
101 14         57 push @cfg, $cfg;
102             }
103             }
104             }
105              
106 18 50       311 return $self->no_local ? @cfg : (@cfg, @local_cfg);
107             }
108              
109             sub found {
110 12     12 0 2435 my $self = shift;
111 12 100       57 return ( $self->_found ? @{ $self->_found } : () );
  11         85  
112             }
113              
114             sub find {
115 1     1 0 647 my $self = shift;
116 1         5 return grep { -f $_ } $self->_find_files;
  20         213  
117             }
118              
119             sub _load_files {
120 18     18   37 my $self = shift;
121 18         37 my $files = shift;
122 18         239 return Config::Any->load_files({
123             files => $files,
124             use_ext => 1,
125             driver_args => $self->driver,
126             });
127             }
128              
129             sub _find_files { # Doesn't really find files...hurm...
130 19     19   31 my $self = shift;
131              
132 19 100       95 if ($self->path_is_file) {
133 7 50       44 my $path = $self->_env_lookup('CONFIG') unless $self->no_env;
134 7   33     50 $path ||= $self->path;
135 7         23 return ($path);
136             }
137             else {
138 12         55 my ($path, $extension) = $self->_get_path;
139 12         46 my $local_suffix = $self->_get_local_suffix;
140 12         58 my @extensions = $self->_get_extensions;
141 12         123281 my $no_local = $self->no_local;
142              
143 12         33 my @files;
144 12 100       52 if ($extension) {
145 4 50   24   46 die "Can't handle file extension $extension" unless first { $_ eq $extension } @extensions;
  24         43  
146 4         18 push @files, $path;
147 4 50       29 unless ($no_local) {
148 4         75 (my $local_path = $path) =~ s{\.$extension$}{_$local_suffix.$extension};
149 4         14 push @files, $local_path;
150             }
151             }
152             else {
153 8         21 push @files, map { "$path.$_" } @extensions;
  80         163  
154 8 50       52 push @files, map { "${path}_${local_suffix}.$_" } @extensions unless $no_local;
  80         176  
155             }
156              
157 12         101 return @files;
158             }
159             }
160              
161             sub _env_lookup {
162 46     46   82 my $self = shift;
163 46         106 my @suffix = @_;
164              
165 46         123 my $name = $self->name;
166 46         118 my $env_lookup = $self->env_lookup;
167 46         66 my @lookup;
168 46 100       144 push @lookup, $name if $name;
169 46         86 push @lookup, @$env_lookup;
170              
171 46         93 for my $prefix (@lookup) {
172 34         89 my $value = _env($prefix, @suffix);
173 34 100       149 return $value if defined $value;
174             }
175              
176 42         122 return;
177             }
178              
179             sub _get_local_suffix {
180 30     30   61 my $self = shift;
181              
182 30         127 my $name = $self->name;
183 30         50 my $suffix;
184 30 100       237 $suffix = $self->_env_lookup('CONFIG_LOCAL_SUFFIX') unless $self->no_env;
185 30   33     322 $suffix ||= $self->local_suffix;
186              
187 30         78 return $suffix;
188             }
189              
190 12     12   21 sub _get_extensions { @{ Config::Any->extensions } }
  12         110  
191              
192             sub file_extension ($) {
193 18     18 0 42 my $path = shift;
194 18 100       422 return if -d $path;
195 7         44 my ($extension) = $path =~ m{\.([^/\.]{1,4})$};
196 7         24 return $extension;
197             }
198              
199             sub _get_path {
200 12     12   26 my $self = shift;
201              
202 12         70 my $name = $self->name;
203 12         29 my $path;
204 12 100       85 $path = $self->_env_lookup('CONFIG') unless $self->no_env;
205 12   66     75 $path ||= $self->path;
206              
207 12         46 my $extension = file_extension $path;
208              
209 12 100       166 if (-d $path) {
210 8         47 $path =~ s{[\/\\]$}{}; # Remove any trailing slash, e.g. apple/ or apple\ => apple
211 8         23 $path .= "/$name"; # Look for a file in path with $self->name, e.g. apple => apple/name
212             }
213              
214 12         42 return ($path, $extension);
215             }
216              
217              
218             1;
219              
220             __END__