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