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