die() instead of silently skip files with extensions we can't handle
[catagits/Catalyst-Plugin-ConfigLoader.git] / lib / Catalyst / Plugin / ConfigLoader.pm
index 5462f27..04ac7e3 100644 (file)
@@ -8,7 +8,7 @@ use NEXT;
 use Data::Visitor::Callback;
 use Catalyst::Utils ();
 
-our $VERSION = '0.16';
+our $VERSION = '0.20';
 
 =head1 NAME
 
@@ -24,13 +24,23 @@ Catalyst::Plugin::ConfigLoader - Load config files of various types
     
     # by default myapp.* will be loaded
     # you can specify a file if you'd like
-    __PACKAGE__->config( file => 'config.yaml' );    
+    __PACKAGE__->config( 'Plugin::ConfigLoader' => { file => 'config.yaml' } );    
+
+  In the file, assuming it's in YAML format:
+
+    foo: bar
+
+  Accessible through the context object, or the class itself
+
+   $c->config->{foo}    # bar
+   MyApp->config->{foo} # bar
 
 =head1 DESCRIPTION
 
 This module will attempt to load find and load a configuration
 file of various types. Currently it supports YAML, JSON, XML,
-INI and Perl formats.
+INI and Perl formats. Special configuration for a particular driver format can
+be stored in C<MyApp-E<gt>config-E<gt>{ 'Plugin::ConfigLoader' }-E<gt>{ driver }>.
 
 To support the distinction between development and production environments,
 this module will also attemp to load a local config (e.g. myapp_local.yaml)
@@ -49,26 +59,32 @@ loaded, set the C<config()> section.
 sub setup {
     my $c     = shift;
     my @files = $c->find_files;
-    my $cfg   = Config::Any->load_files( {
-        files   => \@files, 
-        filter  => \&_fix_syntax,
-        use_ext => 1
-    } );
+    my $cfg   = Config::Any->load_files(
+        {   files       => \@files,
+            filter      => \&_fix_syntax,
+            use_ext     => 1,
+            driver_args => $c->config->{ 'Plugin::ConfigLoader' }->{ driver }
+                || {},
+        }
+    );
+    # map the array of hashrefs to a simple hash
+    my %configs = map { %$_ } @$cfg;
 
     # split the responses into normal and local cfg
     my $local_suffix = $c->get_config_local_suffix;
-    my( @cfg, @localcfg );
-    for( @$cfg ) {
-        if( ( keys %$_ )[ 0 ] =~ m{ $local_suffix \. }xms ) {
-            push @localcfg, $_;
-        } else {
-            push @cfg, $_;
+    my ( @main, @locals );
+    for ( sort keys %configs ) {
+        if ( m{$local_suffix\.}ms ) {
+            push @locals, $_;
+        }
+        else {
+            push @main, $_;
         }
     }
-    
+
     # load all the normal cfgs, then the local cfgs last so they can override
     # normal cfgs
-    $c->load_config( $_ ) for @cfg, @localcfg;
+    $c->load_config( { $_ => $configs{ $_ } } ) for @main, @locals;
 
     $c->finalize_config;
     $c->NEXT::setup( @_ );
@@ -84,9 +100,9 @@ context object. It does not return a value.
 sub load_config {
     my $c   = shift;
     my $ref = shift;
-    
-    my( $file, $config ) = each %$ref;
-    
+
+    my ( $file, $config ) = %$ref;
+
     $c->config( $config );
     $c->log->debug( qq(Loaded Config "$file") )
         if $c->debug;
@@ -104,18 +120,20 @@ L<Config::Any|Config::Any> for loading.
 
 sub find_files {
     my $c = shift;
-    my( $path, $extension ) = $c->get_config_path;
+    my ( $path, $extension ) = $c->get_config_path;
     my $suffix     = $c->get_config_local_suffix;
     my @extensions = @{ Config::Any->extensions };
-    
+
     my @files;
-    if ($extension) {
-        next unless grep { $_ eq $extension } @extensions;
-        push @files, $path, "${path}_${suffix}";
-    } else {
+    if ( $extension ) {
+        die "Unable to handle files with the extension '${extension}'"
+            unless grep { $_ eq $extension } @extensions;
+        ( my $local = $path ) =~ s{\.$extension}{_$suffix.$extension};
+        push @files, $path, $local;
+    }
+    else {
         @files = map { ( "$path.$_", "${path}_${suffix}.$_" ) } @extensions;
     }
-
     @files;
 }
 
@@ -133,7 +151,7 @@ The order of preference is specified as:
 
 =item * C<$ENV{ CATALYST_CONFIG }>
 
-=item * C<$c-E<gt>config-E<gt>{ file }>
+=item * C<$c-E<gt>config-E<gt>{ 'Plugin::ConfigLoader' }-E<gt>{ file }>
 
 =item * C<$c-E<gt>path_to( $application_prefix )>
 
@@ -142,24 +160,37 @@ The order of preference is specified as:
 If either of the first two user-specified options are directories, the
 application prefix will be added on to the end of the path.
 
+DEPRECATION NOTICE: C<$c-E<gt>config-E<gt>{ file }> is deprecated
+and will be removed in the next release.
+
 =cut
 
 sub get_config_path {
-    my $c       = shift;
+    my $c = shift;
+
+    # deprecation notice
+    if ( exists $c->config->{ file } ) {
+        $c->log->warn(
+            q(*** "file" config parameter has been deprecated in favor of "$c->config->{ 'Plugin::ConfigLoader' }->{ file }")
+        );
+        sleep( 3 );
+    }
+
     my $appname = ref $c || $c;
     my $prefix  = Catalyst::Utils::appprefix( $appname );
     my $path    = Catalyst::Utils::env_value( $c, 'CONFIG' )
-        || $c->config->{ file }
+        || $c->config->{ 'Plugin::ConfigLoader' }->{ file }
+        || $c->config->{ file }    # to be removed next release
         || $c->path_to( $prefix );
 
-    my( $extension ) = ( $path =~ m{\.(.{1,4})$} );
-    
-    if( -d $path ) {
-        $path  =~ s{[\/\\]$}{};
+    my ( $extension ) = ( $path =~ m{\.(.{1,4})$} );
+
+    if ( -d $path ) {
+        $path =~ s{[\/\\]$}{};
         $path .= "/$prefix";
     }
-    
-    return( $path, $extension );
+
+    return ( $path, $extension );
 }
 
 =head2 get_config_local_suffix
@@ -173,17 +204,31 @@ this value is C<local>, but it can be specified in the following order of prefer
 
 =item * C<$ENV{ CATALYST_CONFIG_LOCAL_SUFFIX }>
 
-=item * C<$c-E<gt>config-E<gt>{ config_local_suffix }>
+=item * C<$c-E<gt>config-E<gt>{ 'Plugin::ConfigLoader' }-E<gt>{ config_local_suffix }>
 
 =back
 
+DEPRECATION NOTICE: C<$c-E<gt>config-E<gt>{ config_local_suffix }> is deprecated
+and will be removed in the next release.
+
 =cut
 
 sub get_config_local_suffix {
-    my $c       = shift;
+    my $c = shift;
+
+    # deprecation notice
+    if ( exists $c->config->{ config_local_suffix } ) {
+        $c->log->warn(
+            q(*** "config_local_suffix" config parameter has been deprecated in favor of "$c->config->{ 'Plugin::ConfigLoader' }->{ config_local_suffix }")
+        );
+        sleep( 3 );
+    }
+
     my $appname = ref $c || $c;
-    my $suffix  = Catalyst::Utils::env_value( $c, 'CONFIG_LOCAL_SUFFIX' )
-        || $c->config->{ config_local_suffix }
+    my $suffix = Catalyst::Utils::env_value( $c, 'CONFIG_LOCAL_SUFFIX' )
+        || $c->config->{ 'Plugin::ConfigLoader' }->{ config_local_suffix }
+        || $c->config
+        ->{ config_local_suffix }    # to be remove in the next release
         || 'local';
 
     return $suffix;
@@ -196,10 +241,8 @@ sub _fix_syntax {
             prefix => $_ eq 'Component' ? '' : $_ . '::',
             values => delete $config->{ lc $_ } || delete $config->{ $_ }
         },
-        grep {
-            ref $config->{ lc $_ } || ref $config->{ $_ }
-        }
-        qw( Component Model M View V Controller C )
+        grep { ref $config->{ lc $_ } || ref $config->{ $_ } }
+            qw( Component Model M View V Controller C )
     );
 
     foreach my $comp ( @components ) {
@@ -251,9 +294,10 @@ C<__DATA__> as a config value, for example)
 
 The parameter list is split on comma (C<,>). You can override this method to
 do your own string munging, or you can define your own macros in
-C<MyApp->config->{ substitutions }>. Example:
+C<MyApp-E<gt>config-E<gt>{ 'Plugin::ConfigLoader' }-E<gt>{ substitutions }>.
+Example:
 
-    MyApp->config->{ substitutions } = {
+    MyApp->config->{ 'Plugin::ConfigLoader' }->{ substitutions } = {
         baz => sub { my $c = shift; qux( @_ ); }
     }
 
@@ -262,9 +306,10 @@ The above will respond to C<__baz(x,y)__> in config strings.
 =cut
 
 sub config_substitutions {
-    my $c = shift;
-    my $subs = $c->config->{ substitutions } || {};
-    $subs->{ HOME } ||= sub { shift->path_to( '' ); };
+    my $c    = shift;
+    my $subs = $c->config->{ 'Plugin::ConfigLoader' }->{ substitutions }
+        || {};
+    $subs->{ HOME }    ||= sub { shift->path_to( '' ); };
     $subs->{ path_to } ||= sub { shift->path_to( @_ ); };
     $subs->{ literal } ||= sub { return $_[ 1 ]; };
     my $subsre = join( '|', keys %$subs );
@@ -274,7 +319,6 @@ sub config_substitutions {
     }
 }
 
-
 =head1 AUTHOR
 
 Brian Cassidy E<lt>bricas@cpan.orgE<gt>
@@ -302,7 +346,7 @@ Work to this module has been generously sponsored by:
 
 =head1 COPYRIGHT AND LICENSE
 
-Copyright 2007 by Brian Cassidy
+Copyright 2008 by Brian Cassidy
 
 This library is free software; you can redistribute it and/or modify
 it under the same terms as Perl itself.