Initial import of Config::Any (refactored from Catalyst::Plugin::ConfigLoader), and...
[p5sagit/Config-Any.git] / lib / Config / Any.pm
1 package Config::Any;
2 # $Id: $
3 use warnings;
4 use strict;
5 use Carp;
6 use Module::Pluggable::Object ();
7 our $VERSION = (qw$Rev: $)[-1];
8
9 sub load_files {
10     my ($class, $args) = @_;
11     croak "load_files requires a hashref argument" unless defined $args;
12     croak "no files specified!" unless defined $args->{files};
13     my $files = [ grep { -f $_ } @{$args->{files}} ];
14     my $filter_cb = delete $args->{filter};
15     return $class->_load($files, $filter_cb);
16 }
17
18 sub load_stems {
19     my ($class, $args) = @_;
20     croak "load_stems requires a hashref argument" unless defined $args;
21     croak "no stems specified!" unless defined $args->{stems};
22     my $filter_cb = delete $args->{filter};
23     my $stems = $args->{stems};
24     my @files;
25     STEM:
26     for my $s (@$stems) {
27         EXT:
28         for my $ext ($class->extensions) {
29             my $file = "$s.$ext";
30             next EXT unless -f $file;
31             push @files, $file;
32             last EXT;
33         }
34     }
35     return $class->_load(\@files, $filter_cb);
36 }
37
38 sub _load {
39     my ($class, $files_ref, $filter_cb) = @_;
40     croak "_load requires a arrayref of file paths" unless defined $files_ref;
41
42     my $final_configs = [];
43
44     for my $loader ( $class->plugins ) {
45         for my $filename (@$files_ref) {
46             my $config = $loader->load( $filename );
47             next if !$config;
48             $filter_cb->( $config ) if defined $filter_cb;
49             push @$final_configs, { $filename => $config };
50         }
51     }
52     $final_configs;
53 }
54
55 sub finder {
56     my $class = shift;
57     my $finder = Module::Pluggable::Object->new(
58         search_path => [ __PACKAGE__ ],
59         require     => 1
60     );
61     $finder;
62 }
63
64 sub plugins {
65     my $class = shift;
66     return $class->finder->plugins;
67 }
68
69 sub extensions {
70     my $class = shift;
71     return [ map { $_->extensions } $class->plugins ];
72 }
73
74 1; # Magic true value required at end of module
75 __END__
76
77 =head1 NAME
78
79 Config::Any - [One line description of module's purpose here]
80
81
82 =head1 VERSION
83
84 This document describes Config::Any version 0.0.4
85
86
87 =head1 SYNOPSIS
88
89     use Config::Any;
90
91         my $cfg = Config::Any->load_stems({stems => \@filepath_stems, ... });
92         # or
93         my $cfg = Config::Any->load_files({files => \@filepaths, ... });
94
95         for (@$cfg) {
96                 my ($filename, $config) = each %$_;
97                 $class->config($config);
98                 warn "loaded config from file: $filename";
99         }
100
101 =head1 DESCRIPTION
102
103 =for author to fill in:
104     Write a full description of the module and its features here.
105     Use subsections (=head2, =head3) as appropriate.
106
107
108 =head1 INTERFACE 
109
110 =for author to fill in:
111     Write a separate section listing the public components of the modules
112     interface. These normally consist of either subroutines that may be
113     exported, or methods that may be called on objects belonging to the
114     classes provided by the module.
115
116
117 =head1 DIAGNOSTICS
118
119 =for author to fill in:
120     List every single error and warning message that the module can
121     generate (even the ones that will "never happen"), with a full
122     explanation of each problem, one or more likely causes, and any
123     suggested remedies.
124
125 =over
126
127 =item C<< Error message here, perhaps with %s placeholders >>
128
129 [Description of error here]
130
131 =item C<< Another error message here >>
132
133 [Description of error here]
134
135 [Et cetera, et cetera]
136
137 =back
138
139
140 =head1 CONFIGURATION AND ENVIRONMENT
141
142 =for author to fill in:
143     A full explanation of any configuration system(s) used by the
144     module, including the names and locations of any configuration
145     files, and the meaning of any environment variables or properties
146     that can be set. These descriptions must also include details of any
147     configuration language used.
148   
149 Config::Any requires no configuration files or environment variables.
150
151
152 =head1 DEPENDENCIES
153
154 =for author to fill in:
155     A list of all the other modules that this module relies upon,
156     including any restrictions on versions, and an indication whether
157     the module is part of the standard Perl distribution, part of the
158     module's distribution, or must be installed separately. ]
159
160 None.
161
162
163 =head1 INCOMPATIBILITIES
164
165 =for author to fill in:
166     A list of any modules that this module cannot be used in conjunction
167     with. This may be due to name conflicts in the interface, or
168     competition for system or program resources, or due to internal
169     limitations of Perl (for example, many modules that use source code
170     filters are mutually incompatible).
171
172 None reported.
173
174
175 =head1 BUGS AND LIMITATIONS
176
177 =for author to fill in:
178     A list of known problems with the module, together with some
179     indication Whether they are likely to be fixed in an upcoming
180     release. Also a list of restrictions on the features the module
181     does provide: data types that cannot be handled, performance issues
182     and the circumstances in which they may arise, practical
183     limitations on the size of data sets, special cases that are not
184     (yet) handled, etc.
185
186 No bugs have been reported.
187
188 Please report any bugs or feature requests to
189 C<bug-config-any@rt.cpan.org>, or through the web interface at
190 L<http://rt.cpan.org>.
191
192
193 =head1 AUTHOR
194
195 Joel Bernstein  C<< <rataxis@cpan.org> >>
196
197
198 =head1 LICENCE AND COPYRIGHT
199
200 Copyright (c) 2006, Portugal Telecom C<< http://www.sapo.pt/ >>. All rights reserved.
201
202 This module is free software; you can redistribute it and/or
203 modify it under the same terms as Perl itself. See L<perlartistic>.
204
205
206 =head1 DISCLAIMER OF WARRANTY
207
208 BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
209 FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
210 OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
211 PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
212 EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
213 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
214 ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH
215 YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
216 NECESSARY SERVICING, REPAIR, OR CORRECTION.
217
218 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
219 WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
220 REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE
221 LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL,
222 OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
223 THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
224 RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
225 FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
226 SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
227 SUCH DAMAGES.