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