X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FCatalyst%2FHelper.pm;h=4ce00710745c7278578a789615f043fef1658438;hb=620dd287c46cbbf331bab2fa244db3008a46b483;hp=ea69f712e93e15c9fa3fa883cd22c62e940e0ff6;hpb=f6f81470d8057b113cb7ef981e6853e60e326ce9;p=catagits%2FCatalyst-Devel.git diff --git a/lib/Catalyst/Helper.pm b/lib/Catalyst/Helper.pm index ea69f71..4ce0071 100644 --- a/lib/Catalyst/Helper.pm +++ b/lib/Catalyst/Helper.pm @@ -1,8 +1,5 @@ package Catalyst::Helper; - -use strict; -use warnings; -use base 'Class::Accessor::Fast'; +use Moose; use Config; use File::Spec; use File::Path; @@ -13,6 +10,10 @@ use Template; use Catalyst::Devel; use Catalyst::Utils; use Catalyst::Exception; +use Path::Class qw/dir file/; +use File::ShareDir qw/dist_dir/; +use aliased 'Path::Class::Dir'; +use namespace::autoclean; my %cache; @@ -26,6 +27,25 @@ Catalyst::Helper - Bootstrap a Catalyst application =cut + + +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); + my $contents = $file->slurp; + return $contents; +} + +# Do not touch this method, *EVER*, it is needed for back compat. sub get_file { my ( $self, $class, $file ) = @_; unless ( $cache{$class} ) { @@ -33,6 +53,8 @@ sub get_file { $cache{$class} = eval "package $class; "; } my $data = $cache{$class}; + Carp::confess("Could not get data from __DATA__ segment for $class") + unless $data; my @files = split /^__(.+)__\r?\n/m, $data; shift @files; while (@files) { @@ -42,13 +64,14 @@ sub get_file { return 0; } + sub mk_app { my ( $self, $name ) = @_; # Needs to be here for PAR require Catalyst; - if ( $name =~ /[^\w\:]/ ) { + if ( $name =~ /[^\w:]/ || $name =~ /^\d/ || $name =~ /\b:\b|:{3,}/) { warn "Error: Invalid application name.\n"; return 0; } @@ -58,7 +81,9 @@ sub mk_app { $self->{script } = File::Spec->catdir( $self->{dir}, 'script' ); $self->{appprefix } = Catalyst::Utils::appprefix($name); $self->{appenv } = Catalyst::Utils::class2env($name); - $self->{startperl } = "#!$Config{perlpath} -w"; + $self->{startperl } = -r '/usr/bin/env' + ? '#!/usr/bin/env perl' + : "#!$Config{perlpath} -w"; $self->{scriptgen } = $Catalyst::Devel::CATALYST_SCRIPT_GEN || 4; $self->{catalyst_version} = $Catalyst::VERSION; $self->{author } = $self->{author} = $ENV{'AUTHOR'} @@ -89,6 +114,7 @@ sub mk_app { $self->_mk_server; $self->_mk_test; $self->_mk_create; + $self->_mk_information; } return $self->{dir}; } @@ -199,7 +225,7 @@ sub mk_dir { sub mk_file { my ( $self, $file, $content ) = @_; - if ( -e $file ) { + if ( -e $file && -s _ ) { print qq/ exists "$file"\n/; return 0 unless ( $self->{'.newfiles'} @@ -213,6 +239,7 @@ sub mk_file { $file .= '.new'; } } + if ( my $f = IO::File->new("> $file") ) { binmode $f; print $f $content; @@ -243,19 +270,39 @@ sub next_test { return File::Spec->catfile( $dir, "$type\_$tname" ); } +# Do not touch this method, *EVER*, it is needed for back compat. +## addendum: we had to split this method so we could have backwards +## compatability. otherwise, we'd have no way to pass stuff from __DATA__ + sub render_file { my ( $self, $file, $path, $vars ) = @_; + my $template = $self->get_file( ( caller(0) )[0], $file ); + $self->render_file_contents($template, $path, $vars); +} + +sub render_sharedir_file { + my ( $self, $file, $path, $vars ) = @_; + my $template = $self->get_sharedir_file( $file ); + $self->render_file_contents($template, $path, $vars); +} + +sub render_file_contents { + my ( $self, $template, $path, $vars ) = @_; $vars ||= {}; my $t = Template->new; - my $template = $self->get_file( ( caller(0) )[0], $file ); return 0 unless $template; my $output; $t->process( \$template, { %{$self}, %$vars }, \$output ) || Catalyst::Exception->throw( - message => qq/Couldn't process "$file", / . $t->error() ); + message => qq/Couldn't process "$template", / . $t->error() ); $self->mk_file( $path, $output ); } +sub _mk_information { + my $self = shift; + print qq/Change to application directory and Run "perl Makefile.PL" to make sure your install is complete\n/; +} + sub _mk_dirs { my $self = shift; $self->mk_dir( $self->{dir} ); @@ -300,12 +347,12 @@ sub _mk_dirs { sub _mk_appclass { my $self = shift; my $mod = $self->{mod}; - $self->render_file( 'appclass', "$mod.pm" ); + $self->render_sharedir_file( File::Spec->catfile('lib', 'MyApp.pm.tt'), "$mod.pm" ); } sub _mk_rootclass { my $self = shift; - $self->render_file( 'rootclass', + $self->render_sharedir_file( File::Spec->catfile('lib', 'MyApp', 'Controller', 'Root.pm.tt'), File::Spec->catfile( $self->{c}, "Root.pm" ) ); } @@ -314,7 +361,7 @@ sub _mk_makefile { $self->{path} = File::Spec->catfile( 'lib', split( '::', $self->{name} ) ); $self->{path} .= '.pm'; my $dir = $self->{dir}; - $self->render_file( 'makefile', "$dir\/Makefile.PL" ); + $self->render_sharedir_file( 'Makefile.PL.tt', "$dir\/Makefile.PL" ); if ( $self->{makefile} ) { @@ -328,36 +375,36 @@ sub _mk_config { my $self = shift; my $dir = $self->{dir}; my $appprefix = $self->{appprefix}; - $self->render_file( 'config', + $self->render_sharedir_file( 'myapp.conf.tt', File::Spec->catfile( $dir, "$appprefix.conf" ) ); } sub _mk_readme { my $self = shift; my $dir = $self->{dir}; - $self->render_file( 'readme', "$dir\/README" ); + $self->render_sharedir_file( 'README.tt', "$dir\/README" ); } sub _mk_changes { my $self = shift; my $dir = $self->{dir}; my $time = strftime('%Y-%m-%d %H:%M:%S', localtime time); - $self->render_file( 'changes', "$dir\/Changes", { time => $time } ); + $self->render_sharedir_file( 'Changes.tt', "$dir\/Changes", { time => $time } ); } sub _mk_apptest { my $self = shift; my $t = $self->{t}; - $self->render_file( 'apptest', "$t\/01app.t" ); - $self->render_file( 'podtest', "$t\/02pod.t" ); - $self->render_file( 'podcoveragetest', "$t\/03podcoverage.t" ); + $self->render_sharedir_file( File::Spec->catfile('t', '01app.t.tt'), "$t\/01app.t" ); + $self->render_sharedir_file( File::Spec->catfile('t', '02pod.t.tt'), "$t\/02pod.t" ); + $self->render_sharedir_file( File::Spec->catfile('t', '03podcoverage.t.tt'), "$t\/03podcoverage.t" ); } sub _mk_cgi { my $self = shift; my $script = $self->{script}; my $appprefix = $self->{appprefix}; - $self->render_file( 'cgi', "$script\/$appprefix\_cgi.pl" ); + $self->render_sharedir_file( File::Spec->catfile('script', 'myapp_cgi.pl.tt'), "$script\/$appprefix\_cgi.pl" ); chmod 0700, "$script/$appprefix\_cgi.pl"; } @@ -365,7 +412,7 @@ sub _mk_fastcgi { my $self = shift; my $script = $self->{script}; my $appprefix = $self->{appprefix}; - $self->render_file( 'fastcgi', "$script\/$appprefix\_fastcgi.pl" ); + $self->render_sharedir_file( File::Spec->catfile('script', 'myapp_fastcgi.pl.tt'), "$script\/$appprefix\_fastcgi.pl" ); chmod 0700, "$script/$appprefix\_fastcgi.pl"; } @@ -373,7 +420,7 @@ sub _mk_server { my $self = shift; my $script = $self->{script}; my $appprefix = $self->{appprefix}; - $self->render_file( 'server', "$script\/$appprefix\_server.pl" ); + $self->render_sharedir_file( File::Spec->catfile('script', 'myapp_server.pl.tt'), "$script\/$appprefix\_server.pl" ); chmod 0700, "$script/$appprefix\_server.pl"; } @@ -381,7 +428,7 @@ sub _mk_test { my $self = shift; my $script = $self->{script}; my $appprefix = $self->{appprefix}; - $self->render_file( 'test', "$script/$appprefix\_test.pl" ); + $self->render_sharedir_file( File::Spec->catfile('script', 'myapp_test.pl.tt'), "$script/$appprefix\_test.pl" ); chmod 0700, "$script/$appprefix\_test.pl"; } @@ -389,20 +436,20 @@ sub _mk_create { my $self = shift; my $script = $self->{script}; my $appprefix = $self->{appprefix}; - $self->render_file( 'create', "$script\/$appprefix\_create.pl" ); + $self->render_sharedir_file( File::Spec->catfile('script', 'myapp_create.pl.tt'), "$script\/$appprefix\_create.pl" ); chmod 0700, "$script/$appprefix\_create.pl"; } sub _mk_compclass { my $self = shift; my $file = $self->{file}; - return $self->render_file( 'compclass', "$file" ); + return $self->render_sharedir_file( 'lib', 'Helper', 'compclass.tt', "$file" ); } sub _mk_comptest { my $self = shift; my $test = $self->{test}; - $self->render_file( 'comptest', "$test" ); + $self->render_sharedir_file( 't', 'comptest.tt', "$test" ); ## wtf do i rename this to? } sub _mk_images { @@ -413,8 +460,7 @@ sub _mk_images { btn_120x50_powered btn_120x50_powered_shadow btn_88x31_built btn_88x31_built_shadow btn_88x31_powered btn_88x31_powered_shadow/; for my $name (@images) { - my $hex = $self->get_file( ( caller(0) )[0], $name ); - my $image = pack "H*", $hex; + my $image = $self->get_sharedir_file("root", "static", "images", "$name.png.bin"); $self->mk_file( File::Spec->catfile( $images, "$name.png" ), $image ); } } @@ -422,9 +468,9 @@ sub _mk_images { sub _mk_favicon { my $self = shift; my $root = $self->{root}; - my $hex = $self->get_file( ( caller(0) )[0], 'favicon' ); - my $favicon = pack "H*", $hex; - $self->mk_file( File::Spec->catfile( $root, "favicon.ico" ), $favicon ); + my $favicon = $self->get_sharedir_file( 'root', 'favicon.ico.bin' ); + my $dest = File::Spec->catfile( $root, "favicon.ico" ); + $self->mk_file( $dest, $favicon ); } @@ -449,6 +495,7 @@ sub _deprecate_file { } } + =head1 DESCRIPTION This module is used by B to create a set of scripts for a @@ -499,8 +546,8 @@ So when you call C, create will try to execute Catalyst::Helper::View::TT->mk_compclass and Catalyst::Helper::View::TT->mk_comptest. -See L and L for -examples. +See L and +L for examples. All helper classes should be under one of the following namespaces. @@ -508,6 +555,34 @@ All helper classes should be under one of the following namespaces. Catalyst::Helper::View:: Catalyst::Helper::Controller:: +=head2 COMMON HELPERS + +=over + +=item * + +L - DBIx::Class models + +=item * + +L - Template Toolkit view + +=item * + +L + +=item * + +L - wrap any class into a Catalyst model + +=back + +=head3 NOTE + +The helpers will read author name from /etc/passwd by default. + To override, please export the AUTHOR variable. + +=head1 METHODS + =head2 mk_compclass This method in your Helper module is called with C<$helper> @@ -539,703 +614,94 @@ arguments the user typed. There is no fallback for this method. -=head1 METHODS +=head1 INTERNAL METHODS These are the methods that the Helper classes can call on the <$helper> object passed to them. -=head2 render_file +=head2 render_file ($file, $path, $vars) -Render and create a file from a template in DATA using -Template Toolkit. +Render and create a file from a template in DATA using Template +Toolkit. $file is the relevent chunk of the __DATA__ section, $path is +the path to the file and $vars is the hashref as expected by +L