File Coverage

blib/lib/Config/MVP/Reader/Finder.pm
Criterion Covered Total %
statement 37 41 90.2
branch 9 18 50.0
condition 2 5 40.0
subroutine 9 12 75.0
pod 4 4 100.0
total 61 80 76.2


line stmt bran cond sub pod time code
1             package Config::MVP::Reader::Finder 2.200013;
2             # ABSTRACT: a reader that finds an appropriate file
3              
4 1     1   3971 use Moose;
  1         2  
  1         6  
5             extends 'Config::MVP::Reader';
6              
7             #pod =head1 DESCRIPTION
8             #pod
9             #pod The Finder reader multiplexes many other readers that implement the
10             #pod L<Config::MVP::Reader::Findable> role. It uses L<Module::Pluggable> to search
11             #pod for modules, limits them to objects implementing the Findable role, and then
12             #pod selects the those which report that they are able to read a configuration file
13             #pod found in the config root directory. If exactly one findable configuration
14             #pod reader finds a file, it is used to read the file and the configuration sequence
15             #pod is returned. Otherwise, an exception is raised.
16             #pod
17             #pod Config::MVP::Reader::Finder's C<build_assembler> method will decline a new
18             #pod assembler, so if none was passed to C<read_config>, the Findable reader to
19             #pod which reading is delegated will be responsible for building the assembler,
20             #pod unless a Finder subclass overrides C<build_assembler> to set a default across
21             #pod all possible delegates.
22             #pod
23             #pod =cut
24              
25 1     1   5706 use Config::MVP::Error;
  1         2  
  1         32  
26 1     1   443 use Module::Pluggable::Object;
  1         5648  
  1         30  
27 1     1   7 use Try::Tiny;
  1         2  
  1         449  
28              
29             #pod =method default_search_path
30             #pod
31             #pod This is the default search path used to find configuration readers. This
32             #pod method should return a list, and by default returns:
33             #pod
34             #pod qw( Config::MVP::Reader )
35             #pod
36             #pod =cut
37              
38             sub default_search_path {
39 1     1 1 11 return qw(Config::MVP::Reader)
40             }
41              
42             our @DONT_FIND;
43              
44             has _module_pluggable_object => (
45             is => 'ro',
46             init_arg => undef,
47             default => sub {
48             my ($self) = @_;
49             Module::Pluggable::Object->new(
50             search_path => [ $self->default_search_path ],
51             inner => 0,
52             require => 1,
53              
54             # This facility here entirely for testing. -- rjbs, 2014-07-02
55             except => \@DONT_FIND,
56             );
57             },
58             );
59              
60             sub _which_reader {
61 1     1   4 my ($self, $location) = @_;
62              
63 1         1 my @options;
64              
65 1         32 for my $pkg ($self->_module_pluggable_object->plugins) {
66 5 100       2250 next unless $pkg->isa('Moose::Object');
67 3 100       18 next unless $pkg->does('Config::MVP::Reader::Findable');
68              
69 1         286 my $location = $pkg->refined_location($location);
70              
71 1 50       4 next unless defined $location;
72              
73 1         4 push @options, [ $pkg, $location ];
74             }
75              
76 1 50       4 Config::MVP::Error->throw("no viable configuration could be found")
77             unless @options;
78              
79             # XXX: Improve this error message -- rjbs, 2010-05-24
80 1 50       4 Config::MVP::Error->throw("multiple possible config plugins found")
81             if @options > 1;
82              
83             return {
84 1         8 'package' => $options[0][0],
85             'location' => $options[0][1],
86             };
87             }
88              
89             has if_none => (
90             is => 'ro',
91             isa => 'Maybe[Str|CodeRef]',
92             );
93              
94             sub read_config {
95 1     1 1 965 my ($self, $location, $arg) = @_;
96 1 50       33 $self = $self->new unless blessed($self);
97 1   50     703 $arg ||= {};
98              
99 1   33     6 local $arg->{assembler} = $arg->{assembler} || $self->build_assembler;
100              
101 1         1620 my $which;
102             my $instead;
103             try {
104 1     1   42 $which = $self->_which_reader($location);
105             } catch {
106 0 0   0   0 die $_ unless $_ =~ /^no viable configuration/;
107 0 0       0 die $_ unless defined (my $handler = $self->if_none);
108 0         0 $instead = $self->$handler($location, $arg);
109 1         10 };
110              
111 1 50       22 return $instead unless $which;
112              
113             my $reader = $which->{package}->new({
114 1         36 add_cwd_to_lib => $self->add_cwd_to_lib,
115             });
116              
117 1         638 return $reader->read_config( $which->{location}, $arg );
118             }
119              
120       0 1   sub build_assembler { }
121              
122             sub read_into_assembler {
123 0     0 1   confess "This method should never be called or reachable";
124             }
125              
126 1     1   8 no Moose;
  1         9  
  1         8  
127             __PACKAGE__->meta->make_immutable;
128             1;
129              
130             __END__
131              
132             =pod
133              
134             =encoding UTF-8
135              
136             =head1 NAME
137              
138             Config::MVP::Reader::Finder - a reader that finds an appropriate file
139              
140             =head1 VERSION
141              
142             version 2.200013
143              
144             =head1 DESCRIPTION
145              
146             The Finder reader multiplexes many other readers that implement the
147             L<Config::MVP::Reader::Findable> role. It uses L<Module::Pluggable> to search
148             for modules, limits them to objects implementing the Findable role, and then
149             selects the those which report that they are able to read a configuration file
150             found in the config root directory. If exactly one findable configuration
151             reader finds a file, it is used to read the file and the configuration sequence
152             is returned. Otherwise, an exception is raised.
153              
154             Config::MVP::Reader::Finder's C<build_assembler> method will decline a new
155             assembler, so if none was passed to C<read_config>, the Findable reader to
156             which reading is delegated will be responsible for building the assembler,
157             unless a Finder subclass overrides C<build_assembler> to set a default across
158             all possible delegates.
159              
160             =head1 PERL VERSION
161              
162             This module should work on any version of perl still receiving updates from
163             the Perl 5 Porters. This means it should work on any version of perl released
164             in the last two to three years. (That is, if the most recently released
165             version is v5.40, then this module should work on both v5.40 and v5.38.)
166              
167             Although it may work on older versions of perl, no guarantee is made that the
168             minimum required version will not be increased. The version may be increased
169             for any reason, and there is no promise that patches will be accepted to lower
170             the minimum required perl.
171              
172             =head1 METHODS
173              
174             =head2 default_search_path
175              
176             This is the default search path used to find configuration readers. This
177             method should return a list, and by default returns:
178              
179             qw( Config::MVP::Reader )
180              
181             =head1 AUTHOR
182              
183             Ricardo Signes <cpan@semiotic.systems>
184              
185             =head1 COPYRIGHT AND LICENSE
186              
187             This software is copyright (c) 2022 by Ricardo Signes.
188              
189             This is free software; you can redistribute it and/or modify it under
190             the same terms as the Perl 5 programming language system itself.
191              
192             =cut