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