1package Config::MVP::Reader;
2# ABSTRACT: object to read config from storage into an assembler
3$Config::MVP::Reader::VERSION = '2.200012';
4use Moose;
5
6use Config::MVP::Assembler;
7use Cwd ();
8
9#pod =head1 SYNOPSIS
10#pod
11#pod   use Config::MVP::Reader::YAML; # this doesn't really exist
12#pod
13#pod   my $reader   = Config::MVP::Reader::YAML->new;
14#pod
15#pod   my $sequence = $reader->read_config('/etc/foobar.yml');
16#pod
17#pod =head1 DESCRIPTION
18#pod
19#pod A Config::MVP::Reader exists to read configuration data from storage (like a
20#pod file) and convert that data into instructions to a L<Config::MVP::Assembler>,
21#pod which will in turn convert them into a L<Config::MVP::Sequence>, the final
22#pod product.
23#pod
24#pod =attr add_cwd_to_lib
25#pod
26#pod If true (which it is by default) then the current working directly will be
27#pod locally added to C<@INC> during config loading.  This helps deal with changes
28#pod made in Perl v5.26.1.
29#pod
30#pod =cut
31
32has add_cwd_to_lib => (
33  is  => 'ro',
34  isa => 'Bool',
35  default => 1,
36);
37
38#pod =method read_config
39#pod
40#pod   my $sequence = $reader->read_config($location, \%arg);
41#pod
42#pod This method is passed a location, which has no set meaning, but should be the
43#pod mechanism by which the Reader is told how to locate configuration.  It might be
44#pod a file name, a hashref of parameters, a DBH, or anything else, depending on the
45#pod needs of the specific Reader subclass.
46#pod
47#pod It is also passed a hashref of arguments, of which there is only one valid
48#pod argument:
49#pod
50#pod  assembler - the Assembler object into which to read the config
51#pod
52#pod If no assembler argument is passed, one will be constructed by calling the
53#pod Reader's C<build_assembler> method.
54#pod
55#pod Subclasses should generally not override C<read_config>, but should instead
56#pod implement a C<read_into_assembler> method, described below.  If a subclass
57#pod I<does> override C<read_config> it should take care to respect the
58#pod C<add_cwd_to_lib> attribute, above.
59#pod
60#pod =cut
61
62sub read_config {
63  my ($self, $location, $arg) = @_;
64  $arg ||= {};
65
66  $self = $self->new unless blessed $self;
67
68  my $assembler = $arg->{assembler} || $self->build_assembler;
69
70  {
71    local @INC = @INC;
72    if ($self->add_cwd_to_lib) {
73      my $cwd = Cwd::getcwd();
74      push @INC, $cwd unless grep {; $_ eq $cwd } @INC;
75    }
76    $self->read_into_assembler($location, $assembler);
77  }
78
79  return $assembler->sequence;
80}
81
82#pod =method read_into_assembler
83#pod
84#pod This method should not be called directly.  It is called by C<read_config> with
85#pod the following parameters:
86#pod
87#pod   my $sequence = $reader->read_into_assembler( $location, $assembler );
88#pod
89#pod The method should read the configuration found at C<$location> and use it to
90#pod instruct the C<$assembler> (a L<Config::MVP::Assembler>) what configuration to
91#pod perform.
92#pod
93#pod The default implementation of this method will throw an exception complaining
94#pod that it should have been implemented by a subclass.
95#pod
96#pod =cut
97
98sub read_into_assembler {
99  confess 'required method read_into_assembler unimplemented'
100}
101
102#pod =method build_assembler
103#pod
104#pod If no Assembler is provided to C<read_config>'s C<assembler> parameter, this
105#pod method will be called on the Reader to construct one.
106#pod
107#pod It must return a Config::MVP::Assembler object, and by default will return an
108#pod entirely generic one.
109#pod
110#pod =cut
111
112sub build_assembler { Config::MVP::Assembler->new; }
113
114no Moose;
1151;
116
117__END__
118
119=pod
120
121=encoding UTF-8
122
123=head1 NAME
124
125Config::MVP::Reader - object to read config from storage into an assembler
126
127=head1 VERSION
128
129version 2.200012
130
131=head1 SYNOPSIS
132
133  use Config::MVP::Reader::YAML; # this doesn't really exist
134
135  my $reader   = Config::MVP::Reader::YAML->new;
136
137  my $sequence = $reader->read_config('/etc/foobar.yml');
138
139=head1 DESCRIPTION
140
141A Config::MVP::Reader exists to read configuration data from storage (like a
142file) and convert that data into instructions to a L<Config::MVP::Assembler>,
143which will in turn convert them into a L<Config::MVP::Sequence>, the final
144product.
145
146=head1 ATTRIBUTES
147
148=head2 add_cwd_to_lib
149
150If true (which it is by default) then the current working directly will be
151locally added to C<@INC> during config loading.  This helps deal with changes
152made in Perl v5.26.1.
153
154=head1 METHODS
155
156=head2 read_config
157
158  my $sequence = $reader->read_config($location, \%arg);
159
160This method is passed a location, which has no set meaning, but should be the
161mechanism by which the Reader is told how to locate configuration.  It might be
162a file name, a hashref of parameters, a DBH, or anything else, depending on the
163needs of the specific Reader subclass.
164
165It is also passed a hashref of arguments, of which there is only one valid
166argument:
167
168 assembler - the Assembler object into which to read the config
169
170If no assembler argument is passed, one will be constructed by calling the
171Reader's C<build_assembler> method.
172
173Subclasses should generally not override C<read_config>, but should instead
174implement a C<read_into_assembler> method, described below.  If a subclass
175I<does> override C<read_config> it should take care to respect the
176C<add_cwd_to_lib> attribute, above.
177
178=head2 read_into_assembler
179
180This method should not be called directly.  It is called by C<read_config> with
181the following parameters:
182
183  my $sequence = $reader->read_into_assembler( $location, $assembler );
184
185The method should read the configuration found at C<$location> and use it to
186instruct the C<$assembler> (a L<Config::MVP::Assembler>) what configuration to
187perform.
188
189The default implementation of this method will throw an exception complaining
190that it should have been implemented by a subclass.
191
192=head2 build_assembler
193
194If no Assembler is provided to C<read_config>'s C<assembler> parameter, this
195method will be called on the Reader to construct one.
196
197It must return a Config::MVP::Assembler object, and by default will return an
198entirely generic one.
199
200=head1 AUTHOR
201
202Ricardo Signes <rjbs@cpan.org>
203
204=head1 COPYRIGHT AND LICENSE
205
206This software is copyright (c) 2021 by Ricardo Signes.
207
208This is free software; you can redistribute it and/or modify it under
209the same terms as the Perl 5 programming language system itself.
210
211=cut
212