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