Clean up share path search:
[catagits/Catalyst-Devel.git] / lib / Catalyst / Helper.pm
index 6a6e09b..ca4f974 100644 (file)
@@ -1,6 +1,5 @@
 package Catalyst::Helper;
 use Moose;
-use Moose::Util::TypeConstraints;
 use Config;
 use File::Spec;
 use File::Spec::Unix;
@@ -14,8 +13,16 @@ use Catalyst::Utils;
 use Catalyst::Exception;
 use Path::Class qw/dir file/;
 use File::ShareDir qw/dist_dir/;
+use File::HomeDir;
+use Path::Resolver::Resolver::Mux::Ordered;
+use Path::Resolver::Resolver::FileSystem;
 use namespace::autoclean;
 
+with 'MooseX::Emulate::Class::Accessor::Fast';
+
+# Change Catalyst/Devel.pm also
+our $VERSION = '1.23';
+
 my %cache;
 
 =head1 NAME
@@ -28,21 +35,58 @@ Catalyst::Helper - Bootstrap a Catalyst application
 
 =cut
 
+# Return the (cached) path resolver
+{
+    my $resolver;
+
+    sub get_resolver {
+        my $self = shift;
+
+        # Avoid typing this over and over
+        my $fs_path = sub {
+            Path::Resolver::Resolver::FileSystem->new({ root => shift })
+        };
+
+        unless ($resolver) {
+            my @resolvers;
+            # Search path: first try the environment variable
+            if (exists $ENV{CATALYST_DEVEL_SHAREDIR}) {
+                push @resolvers, $fs_path->($ENV{CATALYST_DEVEL_SHAREDIR});
+            }
+            # Then the application's "helper" directory
+            if (exists $self->{base}) {
+                push @resolvers, $fs_path->(dir($self->{base}, "helper"));
+            }
+            # Then ~/.catalyst/helper
+            push @resolvers, $fs_path->(
+                dir(File::HomeDir->my_home, ".catalyst", "helper")
+            );
+            # Finally the Catalyst default
+            if (-d "inc/.author" && -f "lib/Catalyst/Helper.pm"
+                    ) { # Can't use sharedir if we're in a checkout
+                        # this feels horrible, better ideas?
+                push @resolvers, $fs_path->('share');
+            }
+            else {
+                push @resolvers, $fs_path->(dist_dir('Catalyst-Devel'));
+            }
+
+            $resolver = Path::Resolver::Resolver::Mux::Ordered->new({
+                resolvers => \@resolvers
+            });
+        }
+
+        return $resolver;
+    }
+}
+
 sub get_sharedir_file {
     my ($self, @filename) = @_;
-    my $dist_dir;
-    if (-d "inc/.author" && -f "lib/Catalyst/Helper.pm"
-            ) { # Can't use sharedir if we're in a checkout
-                # this feels horrible, better ideas?
-        $dist_dir = 'share';
-    }
-    else {
-        $dist_dir = dist_dir('Catalyst-Devel');
-    }
-    my $file = file( $dist_dir, @filename);
-    Carp::confess("Cannot find $file") unless -r $file;
-    my $contents = $file->slurp;
-    return $contents;
+
+    my $filepath = file(@filename);
+    my $file = $self->get_resolver->entity_at("$filepath") # doesn't like object
+        or Carp::confess("Cannot find $filepath");
+    return $file->content;
 }
 
 # Do not touch this method, *EVER*, it is needed for back compat.
@@ -64,27 +108,23 @@ sub get_file {
     return 0;
 }
 
-my $appname = subtype 'Str',
-    where { /[^\w:]/ or /^\d/ or /\b:\b|:{3,}/ },
-    message { "Error: Invalid application name." };
-
-has name => ( is => 'ro', isa => $appname, required => 1 );
-
-foreach my $name (qw/ dir script appprefix appenv author /) {
-    has $name => ( is => 'ro', isa => 'Str', init_arg => undef, lazy => 1, builder => "_build_$name" );
-}
-
-sub _build_dir { my $dir = shift->name; $dir =~ s/\:\:/-/g; return $dir; }
-sub _build_script { dir( shift->dir, 'script' ) }
-sub _build_appprefix { Catalyst::Utils::appprefix(shift->name) }
-sub _build_appenv { Catalyst::Utils::appenv(shift->name) }
 
 sub mk_app {
-    my ( $self ) = @_;
+    my ( $self, $name ) = @_;
 
     # Needs to be here for PAR
     require Catalyst;
 
+    if ( $name =~ /[^\w:]/ || $name =~ /^\d/ || $name =~ /\b:\b|:{3,}/) {
+        warn "Error: Invalid application name.\n";
+        return 0;
+    }
+    $self->{name            } = $name;
+    $self->{dir             } = $name;
+    $self->{dir             } =~ s/\:\:/-/g;
+    $self->{script          } = dir( $self->{dir}, 'script' );
+    $self->{appprefix       } = Catalyst::Utils::appprefix($name);
+    $self->{appenv          } = Catalyst::Utils::class2env($name);
     $self->{startperl       } = -r '/usr/bin/env'
                                 ? '#!/usr/bin/env perl'
                                 : "#!$Config{perlpath} -w";
@@ -328,15 +368,25 @@ sub _mk_dirs {
     $self->{mod} = dir( $self->{lib}, $self->{class} );
     $self->mk_dir( $self->{mod} );
 
-    $self->{m} = dir( $self->{mod}, 'Model' );
-    $self->mk_dir( $self->{m} );
-    $self->{v} = dir( $self->{mod}, 'View' );
-    $self->mk_dir( $self->{v} );
-    $self->{c} = dir( $self->{mod}, 'Controller' );
-    $self->mk_dir( $self->{c} );
-
+    if ( $self->{short} ) {
+        $self->{m} = dir( $self->{mod}, 'M' );
+        $self->mk_dir( $self->{m} );
+        $self->{v} = dir( $self->{mod}, 'V' );
+        $self->mk_dir( $self->{v} );
+        $self->{c} = dir( $self->{mod}, 'C' );
+        $self->mk_dir( $self->{c} );
+    }
+    else {
+        $self->{m} = dir( $self->{mod}, 'Model' );
+        $self->mk_dir( $self->{m} );
+        $self->{v} = dir( $self->{mod}, 'View' );
+        $self->mk_dir( $self->{v} );
+        $self->{c} = dir( $self->{mod}, 'Controller' );
+        $self->mk_dir( $self->{c} );
+    }
     my $name = $self->{name};
-    $self->{rootname} = "$name\::Controller::Root";
+    $self->{rootname} =
+      $self->{short} ? "$name\::C::Root" : "$name\::Controller::Root";
     $self->{base} = dir( $self->{dir} )->absolute;
 }
 
@@ -693,4 +743,3 @@ it under the same terms as Perl itself.
 =cut
 
 1;
-