made the local suffix overrideable as per robkinyon's suggestion
[catagits/Catalyst-Plugin-ConfigLoader.git] / lib / Catalyst / Plugin / ConfigLoader.pm
index f073ccf..ab332da 100644 (file)
@@ -4,13 +4,10 @@ use strict;
 use warnings;\r
 \r
 use NEXT;\r
-use Module::Pluggable::Fast\r
-    name    => '_config_loaders',\r
-    search  => [ __PACKAGE__ ],\r
-    require => 1;\r
+use Module::Pluggable::Object ();\r
 use Data::Visitor::Callback;\r
 \r
-our $VERSION = '0.05';\r
+our $VERSION = '0.12';\r
 \r
 =head1 NAME\r
 \r
@@ -23,10 +20,10 @@ Catalyst::Plugin::ConfigLoader - Load config files of various types
     # ConfigLoader should be first in your list so\r
     # other plugins can get the config information\r
     use Catalyst qw( ConfigLoader ... );\r
-       \r
+    \r
     # by default myapp.* will be loaded\r
     # you can specify a file if you'd like\r
-    __PACKAGE__->config( file = > 'config.yaml' );    \r
+    __PACKAGE__->config( file => 'config.yaml' );    \r
 \r
 =head1 DESCRIPTION\r
 \r
@@ -49,12 +46,16 @@ loaded, set the C<config()> section.
 =cut\r
 \r
 sub setup {\r
-    my $c    = shift;\r
-    my $path = $c->config->{ file } || $c->path_to( Catalyst::Utils::appprefix( ref $c || $c ) );\r
+    my $c = shift;\r
+    my( $path, $extension ) = $c->get_config_path;\r
+    my $suffix = $c->get_config_local_suffix;\r
 \r
-    my( $extension ) = ( $path =~ /\.(.{1,4})$/ );\r
-    \r
-    for my $loader ( $c->_config_loaders ) {\r
+    my $finder = Module::Pluggable::Object->new(\r
+        search_path => [ __PACKAGE__ ],\r
+        require     => 1\r
+    );\r
+\r
+    for my $loader ( $finder->plugins ) {\r
         my @files;\r
         my @extensions = $loader->extensions;\r
         if( $extension ) {\r
@@ -62,16 +63,20 @@ sub setup {
             push @files, $path;\r
         }\r
         else {\r
-            @files = map { ( "$path.$_", "${path}_local.$_" ) } @extensions;\r
+            @files = map { ( "$path.$_", "${path}_${suffix}.$_" ) } @extensions;\r
         }\r
 \r
         for( @files ) {\r
             next unless -f $_;\r
             my $config = $loader->load( $_ );\r
-            if( $config ) {\r
-                $c->config( $config );\r
-                last;\r
-            }\r
+\r
+            $c->log->debug( qq(Loaded Config "$_") ) if $c->debug;\r
+            \r
+            next if !$config;\r
+\r
+            _fix_syntax( $config );\r
+            \r
+            $c->config( $config );\r
         }\r
     }\r
 \r
@@ -90,7 +95,7 @@ ConfigLoader provides a default finalize_config method which
 walks through the loaded config hash and replaces any strings\r
 beginning containing C<__HOME__> with the full path to\r
 app's home directory (i.e. C<$c-E<gt>path_to('')> ).\r
-You can also use C<__path_to('foo/bar')__> which translates to\r
+You can also use C<__path_to(foo/bar)__> which translates to\r
 C<$c-E<gt>path_to('foo', 'bar')> \r
 \r
 =cut\r
@@ -100,13 +105,104 @@ sub finalize_config {
     my $v = Data::Visitor::Callback->new(\r
         plain_value => sub {\r
             return unless defined $_;\r
-            s[__HOME__][ $c->path_to( '' ) ]e;\r
-            s[__path_to\((.+)\)__][ $c->path_to( split( '/', $1 ) ) ]e;\r
+            s{__HOME__}{ $c->path_to( '' ) }e;\r
+            s{__path_to\((.+)\)__}{ $c->path_to( split( '/', $1 ) ) }e;\r
         }\r
     );\r
     $v->visit( $c->config );\r
 }\r
 \r
+=head2 get_config_path\r
+\r
+This method determines the path, filename prefix and file extension to be used\r
+for config loading. It returns the path (up to the filename less the\r
+extension) to check and the specific extension to use (if it was specified).\r
+\r
+The order of preference is specified as:\r
+\r
+=over 4\r
+\r
+=item * C<$ENV{ MYAPP_CONFIG }>\r
+\r
+=item * C<$c-E<gt>config-E<gt>{ file }>\r
+\r
+=item * C<$c-E<gt>path_to( $application_prefix )>\r
+\r
+=back\r
+\r
+If either of the first two user-specified options are directories, the\r
+application prefix will be added on to the end of the path.\r
+\r
+=cut\r
+\r
+sub get_config_path {\r
+    my $c       = shift;\r
+    my $appname = ref $c || $c;\r
+    my $prefix  = Catalyst::Utils::appprefix( $appname );\r
+    my $path    = $ENV{ Catalyst::Utils::class2env( $appname ) . '_CONFIG' }\r
+        || $c->config->{ file }\r
+        || $c->path_to( $prefix );\r
+\r
+    my( $extension ) = ( $path =~ m{\.(.{1,4})$} );\r
+    \r
+    if( -d $path ) {\r
+        $path  =~ s{[\/\\]$}{};\r
+        $path .= "/$prefix";\r
+    }\r
+    \r
+    return( $path, $extension );\r
+}\r
+\r
+=head2 get_config_local_suffix\r
+\r
+Determines the suffix of files used to override the main config. By default\r
+this value is C<local>, but it can be specified in the following order of preference:\r
+\r
+=over 4\r
+\r
+=item * C<$ENV{ CATALYST_CONFIG_LOCAL_SUFFIX }>\r
+\r
+=item * C<$ENV{ MYAPP_CONFIG_LOCAL_SUFFIX }>\r
+\r
+=item * C<$c-E<gt>config-E<gt>{ config_local_suffix }>\r
+\r
+\r
+=back\r
+\r
+=cut\r
+\r
+sub get_config_local_suffix {\r
+    my $c       = shift;\r
+    my $appname = ref $c || $c;\r
+    my $suffix  = $ENV{ CATALYST_CONFIG_LOCAL_SUFFIX }\r
+        || $ENV{ Catalyst::Utils::class2env( $appname ) . '_CONFIG_LOCAL_SUFFIX' }\r
+        || $c->config->{ config_local_suffix }\r
+        || 'local';\r
+\r
+    return $suffix;\r
+}\r
+\r
+sub _fix_syntax {\r
+    my $config     = shift;\r
+    my @components = (\r
+        map +{\r
+            prefix => $_ eq 'Component' ? '' : $_ . '::',\r
+            values => delete $config->{ lc $_ } || delete $config->{ $_ }\r
+        },\r
+        grep {\r
+            ref $config->{ lc $_ } || ref $config->{ $_ }\r
+        }\r
+        qw( Component Model M View V Controller C )\r
+    );\r
+\r
+    foreach my $comp ( @components ) {\r
+        my $prefix = $comp->{ prefix };\r
+        foreach my $element ( keys %{ $comp->{ values } } ) {\r
+            $config->{ "$prefix$element" } = $comp->{ values }->{ $element };\r
+        }\r
+    }\r
+}\r
+\r
 =head1 AUTHOR\r
 \r
 =over 4 \r