File Coverage

blib/lib/Catalyst/Helper.pm
Criterion Covered Total %
statement 225 337 66.7
branch 41 108 37.9
condition 14 35 40.0
subroutine 43 48 89.5
pod 10 10 100.0
total 333 538 61.9


line stmt bran cond sub pod time code
1             package Catalyst::Helper;
2 6     6   168476 use Moose;
  6         2906244  
  6         48  
3 6     6   45972 use Config;
  6         19  
  6         285  
4 6     6   39 use File::Spec;
  6         13  
  6         190  
5 6     6   33 use File::Spec::Unix;
  6         13  
  6         312  
6 6     6   43 use File::Path;
  6         20  
  6         522  
7 6     6   4272 use FindBin;
  6         7441  
  6         277  
8 6     6   3076 use IO::File;
  6         39363  
  6         745  
9 6     6   2248 use POSIX 'strftime';
  6         27027  
  6         45  
10 6     6   12812 use Template;
  6         123661  
  6         241  
11 6     6   2813 use Catalyst::Devel;
  6         17  
  6         181  
12 6     6   3012 use Catalyst::Utils;
  6         358615  
  6         229  
13 6     6   2771 use Catalyst::Exception;
  6         534626  
  6         336  
14 6     6   62 use Path::Class qw/dir file/;
  6         14  
  6         529  
15 6     6   4372 use File::ShareDir qw/dist_dir/;
  6         132402  
  6         375  
16 6     6   3493 use YAML::Tiny;
  6         35073  
  6         441  
17 6     6   2934 use namespace::autoclean;
  6         9825  
  6         30  
18              
19             with 'MooseX::Emulate::Class::Accessor::Fast';
20              
21             our $VERSION = '1.42';
22             $VERSION =~ tr/_//d;
23              
24             my %cache;
25              
26             sub get_sharedir_file {
27 33     33 1 1803 my ($self, @filename) = @_;
28 33         62 my $dist_dir;
29 33 100 33     168 if (exists $ENV{CATALYST_DEVEL_SHAREDIR}) {
    50          
30 30         64 $dist_dir = $ENV{CATALYST_DEVEL_SHAREDIR};
31             }
32             elsif (-d "inc/.author" && -f "lib/Catalyst/Helper.pm"
33             ) { # Can't use sharedir if we're in a checkout
34             # this feels horrible, better ideas?
35 0         0 $dist_dir = 'share';
36             }
37             else {
38 3         25 $dist_dir = dist_dir('Catalyst-Devel');
39             }
40 33         510 my $file = file( $dist_dir, @filename);
41 33 100       3780 Carp::confess("Cannot find $file") unless -r $file;
42 32         1958 my $contents = $file->slurp(iomode => "<:raw");
43 32         7440 return $contents;
44             }
45              
46             # Do not touch this method, *EVER*, it is needed for back compat.
47             sub get_file {
48 3     3 1 139 my ( $self, $class, $file ) = @_;
49 3 100       11 unless ( $cache{$class} ) {
50 1         4 local $/;
51 1         51 $cache{$class} = eval "package $class; <DATA>";
52             }
53 3         9 my $data = $cache{$class};
54 3 50       9 Carp::confess("Could not get data from __DATA__ segment for $class")
55             unless $data;
56 3         25 my @files = split /^__(.+)__\r?\n/m, $data;
57 3         7 shift @files;
58 3         8 while (@files) {
59 4         11 my ( $name, $content ) = splice @files, 0, 2;
60 4 100       18 return $content if $name eq $file;
61             }
62 0         0 return 0;
63             }
64              
65              
66             sub mk_app {
67 2     2 1 14898 my ( $self, $name ) = @_;
68              
69             # Needs to be here for PAR
70 2         1009 require Catalyst;
71              
72 2 100       1021061 if($name eq '.') {
73 1 50       27 if(!-e 'META.yml') {
74 0 0       0 system perl => 'Makefile.PL'
75             and Catalyst::Exception->throw(message => q(
76             Failed to run "perl Makefile.PL".
77             ));
78             }
79              
80 1         26 $name = YAML::Tiny->read('META.yml')->[0]->{'name'};
81 1         2684 $name =~ s/-/::/g;
82 1         12 $self->{dir} = '.';
83             }
84              
85 2 50 33     39 if ( $name =~ /[^\w:]/ || $name =~ /^\d/ || $name =~ /\b:\b|:{3,}/) {
      33        
86 0         0 warn "Error: Invalid application name.\n";
87 0         0 return 0;
88             }
89              
90              
91 2 100       11 if(!defined $self->{'dir'}) {
92 1         4 $self->{dir} = $name;
93 1         3 $self->{dir} =~ s/\:\:/-/g;
94             }
95              
96 2         7 $self->{name } = $name;
97 2         16 $self->{script } = dir( $self->{dir}, 'script' );
98 2         273 $self->{appprefix } = Catalyst::Utils::appprefix($name);
99 2         42 $self->{appenv } = Catalyst::Utils::class2env($name);
100 2 50       131 $self->{startperl } = -r '/usr/bin/env'
101             ? '#!/usr/bin/env perl'
102             : "#!$Config{perlpath}";
103 2         9 $self->{scriptgen } = $Catalyst::Devel::CATALYST_SCRIPT_GEN;
104 2         9 $self->{catalyst_version} = $Catalyst::VERSION;
105             $self->{author } ||= $ENV{'AUTHOR'}
106 2   50     28 || eval { @{ [ getpwuid($<) ] }[6] }
      33        
107             || 'Catalyst developer';
108              
109 2 50       13 my $gen_scripts = ( $self->{makefile} ) ? 0 : 1;
110 2 100       11 my $gen_makefile = ( $self->{scripts} ) ? 0 : 1;
111 2 100 66     11 my $gen_app = ( $self->{scripts} || $self->{makefile} ) ? 0 : 1;
112              
113 2 100       10 if ($gen_app) {
114 1         5 for ( qw/ _mk_dirs _mk_config _mk_psgi _mk_appclass _mk_rootclass
115             _mk_readme _mk_changes _mk_apptest _mk_podtest _mk_podcoveragetest
116             _mk_images _mk_favicon/ ) {
117 12         688 $self->$_;
118             }
119             }
120 2 100       12 if ($gen_makefile) {
121 1         8 $self->_mk_makefile;
122             }
123 2 50       9 if ($gen_scripts) {
124 2         6 for ( qw/ _mk_cgi _mk_fastcgi _mk_server
125             _mk_test _mk_create _mk_information
126             / ) {
127 12         510 $self->$_;
128             }
129             }
130 2         36 return $self->{dir};
131             }
132              
133             ## not much of this can really be changed, mk_compclass must be left for
134             ## backcompat
135             sub mk_component {
136 0     0 1 0 my $self = shift;
137 0         0 my $app = shift;
138 0         0 $self->{app} = $app;
139             $self->{author} = $self->{author} = $ENV{'AUTHOR'}
140 0   0     0 || eval { @{ [ getpwuid($<) ] }[6] }
141             || 'A clever guy';
142 0   0     0 $self->{base} ||= dir( $FindBin::Bin, '..' );
143 0 0       0 unless ( $_[0] =~ /^(?:model|view|controller)$/i ) {
144 0         0 my $helper = shift;
145 0         0 my @args = @_;
146 0         0 my $class = "Catalyst::Helper::$helper";
147 0         0 eval "require $class";
148              
149 0 0       0 if ($@) {
150 0         0 Catalyst::Exception->throw(
151             message => qq/Couldn't load helper "$class", "$@"/ );
152             }
153              
154 0 0       0 if ( $class->can('mk_stuff') ) {
155 0 0       0 return 1 unless $class->mk_stuff( $self, @args );
156             }
157             }
158             else {
159 0         0 my $type = shift;
160 0   0     0 my $name = shift || "Missing name for model/view/controller";
161 0         0 my $helper = shift;
162 0         0 my @args = @_;
163 0 0       0 return 0 if $name =~ /[^\w\:]/;
164 0         0 $type = lc $type;
165 0         0 $self->{long_type} = ucfirst $type;
166 0 0       0 $type = 'M' if $type =~ /model/i;
167 0 0       0 $type = 'V' if $type =~ /view/i;
168 0 0       0 $type = 'C' if $type =~ /controller/i;
169 0         0 my $appdir = dir( split /\:\:/, $app );
170             my $test_path =
171 0         0 dir( $self->{base}, 'lib', $appdir, 'C' );
172 0 0       0 $type = $self->{long_type} unless -d $test_path;
173 0         0 $self->{type} = $type;
174 0         0 $self->{name} = $name;
175 0         0 $self->{class} = "$app\::$type\::$name";
176              
177             # Class
178             my $path =
179 0         0 dir( $self->{base}, 'lib', $appdir, $type );
180 0         0 my $file = $name;
181 0 0       0 if ( $name =~ /\:/ ) {
182 0         0 my @path = split /\:\:/, $name;
183 0         0 $file = pop @path;
184 0         0 $path = dir( $path, @path );
185             }
186 0         0 $self->mk_dir($path);
187 0         0 $file = file( $path, "$file.pm" );
188 0         0 $self->{file} = $file;
189              
190             # Test
191 0         0 $self->{test_dir} = dir( $self->{base}, 't' );
192 0         0 $self->{test} = $self->next_test;
193              
194             # Helper
195 0 0       0 if ($helper) {
196 0         0 my $comp = $self->{long_type};
197 0         0 my $class = "Catalyst::Helper::$comp\::$helper";
198 0         0 eval "require $class";
199              
200 0 0       0 if ($@) {
201 0         0 Catalyst::Exception->throw(
202             message => qq/Couldn't load helper "$class", "$@"/ );
203             }
204              
205 0 0       0 if ( $class->can('mk_compclass') ) {
206 0 0       0 return 1 unless $class->mk_compclass( $self, @args );
207             }
208             else {
209 0 0       0 return 1 unless $self->_mk_compclass
210             }
211              
212 0 0       0 if ( $class->can('mk_comptest') ) {
213 0         0 $class->mk_comptest( $self, @args );
214             }
215             else {
216 0         0 $self->_mk_comptest
217             }
218             }
219              
220             # Fallback
221             else {
222 0 0       0 return 1 unless $self->_mk_compclass;
223 0         0 $self->_mk_comptest;
224             }
225             }
226 0         0 return 1;
227             }
228              
229             sub mk_dir {
230 11     11 1 25 my ( $self, $dir ) = @_;
231 11 50       63 if ( -d $dir ) {
232 0         0 print qq/ exists "$dir"\n/;
233 0         0 return 0;
234             }
235 11 50       724 if ( mkpath [$dir] ) {
236 11         1870 print qq/created "$dir"\n/;
237 11         239 return 1;
238             }
239              
240 0         0 Catalyst::Exception->throw( message => qq/Couldn't create "$dir", "$!"/ );
241             }
242              
243             sub mk_file {
244 33     33 1 779 my ( $self, $file, $content ) = @_;
245 33 100 100     293 if ( -e $file && -s _ ) {
246 5         328 print qq/ exists "$file"\n/;
247             return 0
248             unless ( $self->{'.newfiles'}
249             || $self->{scripts}
250 5 0 33     450 || $self->{makefile} );
      33        
251 5 50       17 if ( $self->{'.newfiles'} ) {
252 0 0       0 if ( my $f = IO::File->new("< $file") ) {
253 0         0 my $oldcontent = join( '', (<$f>) );
254 0 0       0 return 0 if $content eq $oldcontent;
255             }
256 0         0 $file .= '.new';
257             }
258             }
259              
260 33 50       1705 if ( my $f = IO::File->new("> $file") ) {
261 33         4827 binmode $f;
262 33         290 print $f $content;
263 33         336 print qq/created "$file"\n/;
264 33         3044 return $file;
265             }
266              
267 0         0 Catalyst::Exception->throw( message => qq/Couldn't create "$file", "$!"/ );
268             }
269              
270             sub next_test {
271 0     0 1 0 my ( $self, $tname ) = @_;
272 0 0       0 if ($tname) { $tname = "$tname.t" }
  0         0  
273             else {
274 0         0 my $name = $self->{name};
275 0         0 my $prefix = $name;
276 0         0 $prefix =~ s/::/-/g;
277 0         0 $prefix = $prefix;
278 0         0 $tname = $prefix . '.t';
279 0         0 $self->{prefix} = $prefix;
280 0         0 $prefix = lc $prefix;
281 0         0 $prefix =~ s/-/\//g;
282 0         0 $self->{uri} = "/$prefix";
283             }
284 0         0 my $dir = $self->{test_dir};
285 0         0 my $type = lc $self->{type};
286 0         0 $self->mk_dir($dir);
287 0         0 return file( $dir, "$type\_$tname" );
288             }
289              
290             # Do not touch this method, *EVER*, it is needed for back compat.
291             ## addendum: we had to split this method so we could have backwards
292             ## compatibility. otherwise, we'd have no way to pass stuff from __DATA__
293              
294             sub render_file {
295 1     1 1 2097 my ( $self, $file, $path, $vars, $perms ) = @_;
296 1         9 my $template = $self->get_file( ( caller(0) )[0], $file );
297 1         7 $self->render_file_contents($template, $path, $vars, $perms);
298             }
299              
300             sub render_sharedir_file {
301 21     21 1 3745 my ( $self, $file, $path, $vars, $perms ) = @_;
302 21         76 my $template = $self->get_sharedir_file( $file );
303 21 50       69 die("Cannot get template from $file for $self\n") unless $template;
304 21         74 $self->render_file_contents($template, $path, $vars, $perms);
305             }
306              
307             sub render_file_contents {
308 23     23 1 847 my ( $self, $template, $path, $vars, $perms ) = @_;
309 23   100     143 $vars ||= {};
310 23         209 my $t = Template->new;
311 23 50       105782 return 0 unless $template;
312 23         43 my $output;
313 23 50       47 $t->process( \$template, { %{$self}, %$vars }, \$output )
  23         367  
314             || Catalyst::Exception->throw(
315             message => qq/Couldn't process "$template", / . $t->error() );
316 23         191662 my $file = $self->mk_file( $path, $output );
317 23 100       166 chmod $perms, file($file) if defined $perms;
318 23         2462 return $file;
319             }
320              
321             sub _mk_information {
322 2     2   6 my $self = shift;
323 2         43 print qq/Change to application directory and Run "perl Makefile.PL" to make sure your install is complete\n/;
324             }
325              
326             sub _mk_dirs {
327 1     1   4 my $self = shift;
328 1         7 $self->mk_dir( $self->{dir} );
329 1         6 $self->mk_dir( $self->{script} );
330 1         6 $self->{lib} = dir( $self->{dir}, 'lib' );
331 1         52 $self->mk_dir( $self->{lib} );
332 1         6 $self->{root} = dir( $self->{dir}, 'root' );
333 1         51 $self->mk_dir( $self->{root} );
334 1         6 $self->{static} = dir( $self->{root}, 'static' );
335 1         55 $self->mk_dir( $self->{static} );
336 1         6 $self->{images} = dir( $self->{static}, 'images' );
337 1         48 $self->mk_dir( $self->{images} );
338 1         5 $self->{t} = dir( $self->{dir}, 't' );
339 1         50 $self->mk_dir( $self->{t} );
340              
341 1         8 $self->{class} = dir( split( /\:\:/, $self->{name} ) );
342 1         44 $self->{mod} = dir( $self->{lib}, $self->{class} );
343 1         43 $self->mk_dir( $self->{mod} );
344              
345 1 50       6 if ( $self->{short} ) {
346 0         0 $self->{m} = dir( $self->{mod}, 'M' );
347 0         0 $self->mk_dir( $self->{m} );
348 0         0 $self->{v} = dir( $self->{mod}, 'V' );
349 0         0 $self->mk_dir( $self->{v} );
350 0         0 $self->{c} = dir( $self->{mod}, 'C' );
351 0         0 $self->mk_dir( $self->{c} );
352             }
353             else {
354 1         11 $self->{m} = dir( $self->{mod}, 'Model' );
355 1         47 $self->mk_dir( $self->{m} );
356 1         6 $self->{v} = dir( $self->{mod}, 'View' );
357 1         56 $self->mk_dir( $self->{v} );
358 1         5 $self->{c} = dir( $self->{mod}, 'Controller' );
359 1         45 $self->mk_dir( $self->{c} );
360             }
361 1         3 my $name = $self->{name};
362             $self->{rootname} =
363 1 50       7 $self->{short} ? "$name\::C::Root" : "$name\::Controller::Root";
364 1         6 $self->{base} = dir( $self->{dir} )->absolute;
365             }
366              
367             sub _mk_appclass {
368 1     1   3 my $self = shift;
369 1         4 my $mod = $self->{mod};
370 1         8 $self->render_sharedir_file( file('lib', 'MyApp.pm.tt'), "$mod.pm" );
371             }
372              
373             sub _mk_rootclass {
374 1     1   3 my $self = shift;
375             $self->render_sharedir_file( file('lib', 'MyApp', 'Controller', 'Root.pm.tt'),
376 1         7 file( $self->{c}, "Root.pm" ) );
377             }
378              
379             sub _mk_makefile {
380 1     1   4 my $self = shift;
381 1         9 $self->{path} = join('/', 'lib', split( '::', $self->{name} ) );
382 1         5 $self->{path} .= '.pm';
383 1         3 my $dir = $self->{dir};
384 1         7 $self->render_sharedir_file( 'Makefile.PL.tt', file($dir, "Makefile.PL") );
385              
386 1 50       52 if ( $self->{makefile} ) {
387              
388             # deprecate the old Build.PL file when regenerating Makefile.PL
389             $self->_deprecate_file(
390 0         0 file( $self->{dir}, 'Build.PL' ) );
391             }
392             }
393              
394             sub _mk_psgi {
395 1     1   3 my $self = shift;
396 1         36 my $dir = $self->{dir};
397 1         3 my $appprefix = $self->{appprefix};
398 1         8 $self->render_sharedir_file( 'myapp.psgi.tt',
399             file( $dir, "$appprefix.psgi" ) );
400             }
401              
402             sub _mk_config {
403 1     1   3 my $self = shift;
404 1         4 my $dir = $self->{dir};
405 1         2 my $appprefix = $self->{appprefix};
406 1         9 $self->render_sharedir_file( 'myapp.conf.tt',
407             file( $dir, "$appprefix.conf" ) );
408             }
409              
410             sub _mk_readme {
411 1     1   4 my $self = shift;
412 1         6 my $dir = $self->{dir};
413 1         6 $self->render_sharedir_file( 'README.tt', file($dir, "README") );
414             }
415              
416             sub _mk_changes {
417 1     1   4 my $self = shift;
418 1         3 my $dir = $self->{dir};
419 1         143 my $time = strftime('%Y-%m-%d %H:%M:%S', localtime time);
420 1         11 $self->render_sharedir_file( 'Changes.tt', file($dir, "Changes"), { time => $time } );
421             }
422              
423             sub _mk_apptest {
424 1     1   3 my $self = shift;
425 1         2 my $t = $self->{t};
426 1         8 $self->render_sharedir_file( file('t', '01app.t.tt'), file($t, "01app.t") );
427             }
428              
429             sub _mk_podtest {
430 1     1   5 my $self = shift;
431 1         3 my $t = $self->{t};
432 1         6 $self->render_sharedir_file( file('t', '02pod.t.tt'), file($t, "02pod.t") );
433             }
434              
435             sub _mk_podcoveragetest {
436 1     1   4 my $self = shift;
437 1         3 my $t = $self->{t};
438 1         7 $self->render_sharedir_file( file('t', '03podcoverage.t.tt'), file($t, "03podcoverage.t") );
439             }
440              
441             sub _mk_cgi {
442 2     2   8 my $self = shift;
443 2         5 my $script = $self->{script};
444 2         8 my $appprefix = $self->{appprefix};
445 2         12 $self->render_sharedir_file( file('script', 'myapp_cgi.pl.tt'),
446             file($script,"$appprefix\_cgi.pl"), undef, 0755 );
447             }
448              
449             sub _mk_fastcgi {
450 2     2   7 my $self = shift;
451 2         5 my $script = $self->{script};
452 2         5 my $appprefix = $self->{appprefix};
453 2         11 $self->render_sharedir_file( file('script', 'myapp_fastcgi.pl.tt'),
454             file($script, "$appprefix\_fastcgi.pl"), undef, 0755 );
455             }
456              
457             sub _mk_server {
458 2     2   7 my $self = shift;
459 2         5 my $script = $self->{script};
460 2         7 my $appprefix = $self->{appprefix};
461 2         9 $self->render_sharedir_file( file('script', 'myapp_server.pl.tt'),
462             file($script, "$appprefix\_server.pl"), undef, 0755 );
463             }
464              
465             sub _mk_test {
466 2     2   6 my $self = shift;
467 2         6 my $script = $self->{script};
468 2         6 my $appprefix = $self->{appprefix};
469 2         10 $self->render_sharedir_file( file('script', 'myapp_test.pl.tt'),
470             file($script, "$appprefix\_test.pl"), undef, 0755 );
471             }
472              
473             sub _mk_create {
474 2     2   6 my $self = shift;
475 2         5 my $script = $self->{script};
476 2         7 my $appprefix = $self->{appprefix};
477 2         10 $self->render_sharedir_file( file('script', 'myapp_create.pl.tt'),
478             file($script, "$appprefix\_create.pl"), undef, 0755 );
479             }
480              
481             sub _mk_compclass {
482 0     0   0 my $self = shift;
483 0         0 my $file = $self->{file};
484 0         0 return $self->render_sharedir_file( file('lib', 'Helper', 'compclass.pm.tt'), $file );
485             }
486              
487             sub _mk_comptest {
488 0     0   0 my $self = shift;
489 0         0 my $test = $self->{test};
490 0         0 $self->render_sharedir_file( file('t', 'comptest.tt'), $test ); ## wtf do i rename this to?
491             }
492              
493             sub _mk_images {
494 1     1   3 my $self = shift;
495 1         4 my $images = $self->{images};
496 1         7 my @images =
497             qw/catalyst_logo btn_120x50_built btn_120x50_built_shadow
498             btn_120x50_powered btn_120x50_powered_shadow btn_88x31_built
499             btn_88x31_built_shadow btn_88x31_powered btn_88x31_powered_shadow/;
500 1         3 for my $name (@images) {
501 9         57 my $image = $self->get_sharedir_file("root", "static", "images", "$name.png.bin");
502 9         45 $self->mk_file( file( $images, "$name.png" ), $image );
503             }
504             }
505              
506             sub _mk_favicon {
507 1     1   5 my $self = shift;
508 1         3 my $root = $self->{root};
509 1         4 my $favicon = $self->get_sharedir_file( 'root', 'favicon.ico.bin' );
510 1         7 my $dest = dir( $root, "favicon.ico" );
511 1         54 $self->mk_file( $dest, $favicon );
512              
513             }
514              
515             sub _deprecate_file {
516 0     0     my ( $self, $file ) = @_;
517 0 0         if ( -e $file ) {
518 0           my ($f, $oldcontent);
519 0 0         if ( $f = IO::File->new("< $file") ) {
520 0           $oldcontent = join( '', (<$f>) );
521             }
522 0           my $newfile = $file . '.deprecated';
523 0 0         if ( $f = IO::File->new("> $newfile") ) {
524 0           binmode $f;
525 0           print $f $oldcontent;
526 0           print qq/created "$newfile"\n/;
527 0           unlink $file;
528 0           print qq/removed "$file"\n/;
529 0           return 1;
530             }
531             Catalyst::Exception->throw(
532 0           message => qq/Couldn't create "$file", "$!"/ );
533             }
534             }
535              
536             1;
537             __END__
538              
539             =head1 NAME
540              
541             Catalyst::Helper - Bootstrap a Catalyst application
542              
543             =head1 SYNOPSIS
544              
545             catalyst.pl <myappname>
546              
547             =head1 DESCRIPTION
548              
549             This module is used by B<catalyst.pl> to create a set of scripts for a
550             new catalyst application. The scripts each contain documentation and
551             will output help on how to use them if called incorrectly or in some
552             cases, with no arguments.
553              
554             It also provides some useful methods for a Helper module to call when
555             creating a component. See L</METHODS>.
556              
557             =head1 SCRIPTS
558              
559             =head2 _create.pl
560              
561             Used to create new components for a catalyst application at the
562             development stage.
563              
564             =head2 _server.pl
565              
566             The catalyst test server, starts an HTTPD which outputs debugging to
567             the terminal.
568              
569             =head2 _test.pl
570              
571             A script for running tests from the command-line.
572              
573             =head2 _cgi.pl
574              
575             Run your application as a CGI.
576              
577             =head2 _fastcgi.pl
578              
579             Run the application as a fastcgi app. Either by hand, or call this
580             from FastCgiServer in your http server config.
581              
582             =head1 HELPERS
583              
584             The L</_create.pl> script creates application components using Helper
585             modules. The Catalyst team provides a good number of Helper modules
586             for you to use. You can also add your own.
587              
588             Helpers are classes that provide two methods.
589              
590             * mk_compclass - creates the Component class
591             * mk_comptest - creates the Component test
592              
593             So when you call C<scripts/myapp_create.pl view MyView TT>, create
594             will try to execute Catalyst::Helper::View::TT->mk_compclass and
595             Catalyst::Helper::View::TT->mk_comptest.
596              
597             See L<Catalyst::Helper::View::TT> and
598             L<Catalyst::Helper::Model::DBIC::Schema> for examples.
599              
600             All helper classes should be under one of the following namespaces.
601              
602             Catalyst::Helper::Model::
603             Catalyst::Helper::View::
604             Catalyst::Helper::Controller::
605              
606             =head2 COMMON HELPERS
607              
608             =over
609              
610             =item *
611              
612             L<Catalyst::Helper::Model::DBIC::Schema> - DBIx::Class models
613              
614             =item *
615              
616             L<Catalyst::Helper::View::TT> - Template Toolkit view
617              
618             =item *
619              
620             L<Catalyst::Helper::Model::LDAP>
621              
622             =item *
623              
624             L<Catalyst::Helper::Model::Adaptor> - wrap any class into a Catalyst model
625              
626             =back
627              
628             =head3 NOTE
629              
630             The helpers will read author name from /etc/passwd by default.
631             To override, please export the AUTHOR variable.
632              
633             =head1 METHODS
634              
635             =head2 mk_compclass
636              
637             This method in your Helper module is called with C<$helper>
638             which is a L<Catalyst::Helper> object, and whichever other arguments
639             the user added to the command-line. You can use the $helper to call methods
640             described below.
641              
642             If the Helper module does not contain a C<mk_compclass> method, it
643             will fall back to calling L</render_file>, with an argument of
644             C<compclass>.
645              
646             =head2 mk_comptest
647              
648             This method in your Helper module is called with C<$helper>
649             which is a L<Catalyst::Helper> object, and whichever other arguments
650             the user added to the command-line. You can use the $helper to call methods
651             described below.
652              
653             If the Helper module does not contain a C<mk_compclass> method, it
654             will fall back to calling L</render_file>, with an argument of
655             C<comptest>.
656              
657             =head2 mk_stuff
658              
659             This method is called if the user does not supply any of the usual
660             component types C<view>, C<controller>, C<model>. It is passed the
661             C<$helper> object (an instance of L<Catalyst::Helper>), and any other
662             arguments the user typed.
663              
664             There is no fallback for this method.
665              
666             =head1 INTERNAL METHODS
667              
668             These are the methods that the Helper classes can call on the
669             <$helper> object passed to them.
670              
671             =head2 render_file ($file, $path, $vars, $perms)
672              
673             Render and create a file from a template in DATA using Template
674             Toolkit. $file is the relevant chunk of the __DATA__ section, $path is
675             the path to the file, $vars is the hashref as expected by
676             L<Template Toolkit|Template> and $perms are desired permissions (or system
677             defaults if not set).
678              
679             =head2 get_file ($class, $file)
680              
681             Fetch file contents from the DATA section. This is used internally by
682             L</render_file>. $class is the name of the class to get the DATA
683             section from. __PACKAGE__ or ( caller(0) )[0] might be sensible
684             values for this.
685              
686             =head2 mk_app
687              
688             Create the main application skeleton. This is called by L<catalyst.pl>.
689              
690             =head2 mk_component ($app)
691              
692             This method is called by L<create.pl> to make new components
693             for your application.
694              
695             =head2 mk_dir ($path)
696              
697             Surprisingly, this function makes a directory.
698              
699             =head2 mk_file ($file, $content)
700              
701             Writes content to a file. Called by L</render_file>.
702              
703             =head2 next_test ($test_name)
704              
705             Calculates the name of the next numbered test file and returns it.
706             Don't give the number or the .t suffix for the test name.
707              
708             =cut
709              
710             =head2 get_sharedir_file
711              
712             Method for getting a file out of share/
713              
714             =head2 render_file_contents
715              
716             Process a L<Template::Toolkit> template.
717              
718             =head2 render_sharedir_file
719              
720             Render a template/image file from our share directory
721              
722             =head1 NOTE
723              
724             The helpers will read author name from /etc/passwd by default.
725             To override, please export the AUTHOR variable.
726              
727             =head1 SEE ALSO
728              
729             L<Catalyst::Manual>, L<Catalyst::Test>, L<Catalyst::Request>,
730             L<Catalyst::Response>, L<Catalyst>
731              
732             =head1 AUTHORS
733              
734             Catalyst Contributors, see Catalyst.pm
735              
736             =head1 LICENSE
737              
738             This library is free software. You can redistribute it and/or modify
739             it under the same terms as Perl itself.
740              
741             =cut