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