Add Moose so we have a constructor and fix changes generation
[catagits/Catalyst-Devel.git] / lib / Catalyst / Helper.pm
CommitLineData
68ccb5e5 1package Catalyst::Helper;
957ccd4d 2use 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/;
957ccd4d 15use 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";
acde1869 85 $self->{scriptgen } = $Catalyst::Devel::CATALYST_SCRIPT_GEN || 34;
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) {
420ad692 96 for ( qw/ _mk_dirs _mk_config _mk_appclass _mk_rootclass _mk_readme
97 _mk_changes _mk_apptest _mk_images _mk_favicon/ ) {
98
99 $self->$_;
420ad692 100 }
68ccb5e5 101 }
102 if ($gen_makefile) {
103 $self->_mk_makefile;
104 }
105 if ($gen_scripts) {
420ad692 106 for ( qw/ _mk_cgi _mk_fastcgi _mk_server
28d172c6 107 _mk_test _mk_create _mk_information
108 / ) {
109 $self->$_;
110 }
68ccb5e5 111 }
112 return $self->{dir};
113}
114
23f9f145 115## not much of this can really be changed, mk_compclass must be left for
116## backcompat
68ccb5e5 117sub mk_component {
118 my $self = shift;
119 my $app = shift;
120 $self->{app} = $app;
121 $self->{author} = $self->{author} = $ENV{'AUTHOR'}
122 || eval { @{ [ getpwuid($<) ] }[6] }
123 || 'A clever guy';
068587bd 124 $self->{base} ||= dir( $FindBin::Bin, '..' );
68ccb5e5 125 unless ( $_[0] =~ /^(?:model|view|controller)$/i ) {
126 my $helper = shift;
127 my @args = @_;
128 my $class = "Catalyst::Helper::$helper";
129 eval "require $class";
130
131 if ($@) {
132 Catalyst::Exception->throw(
133 message => qq/Couldn't load helper "$class", "$@"/ );
134 }
135
136 if ( $class->can('mk_stuff') ) {
137 return 1 unless $class->mk_stuff( $self, @args );
138 }
139 }
140 else {
141 my $type = shift;
142 my $name = shift || "Missing name for model/view/controller";
143 my $helper = shift;
144 my @args = @_;
fab70e0a 145 return 0 if $name =~ /[^\w\:]/;
68ccb5e5 146 $type = lc $type;
147 $self->{long_type} = ucfirst $type;
148 $type = 'M' if $type =~ /model/i;
149 $type = 'V' if $type =~ /view/i;
150 $type = 'C' if $type =~ /controller/i;
068587bd 151 my $appdir = dir( split /\:\:/, $app );
68ccb5e5 152 my $test_path =
068587bd 153 dir( $self->{base}, 'lib', $appdir, 'C' );
68ccb5e5 154 $type = $self->{long_type} unless -d $test_path;
155 $self->{type} = $type;
156 $self->{name} = $name;
157 $self->{class} = "$app\::$type\::$name";
158
159 # Class
160 my $path =
068587bd 161 dir( $self->{base}, 'lib', $appdir, $type );
68ccb5e5 162 my $file = $name;
163 if ( $name =~ /\:/ ) {
164 my @path = split /\:\:/, $name;
165 $file = pop @path;
068587bd 166 $path = dir( $path, @path );
68ccb5e5 167 }
168 $self->mk_dir($path);
068587bd 169 $file = file( $path, "$file.pm" );
68ccb5e5 170 $self->{file} = $file;
171
172 # Test
068587bd 173 $self->{test_dir} = dir( $self->{base}, 't' );
68ccb5e5 174 $self->{test} = $self->next_test;
175
176 # Helper
177 if ($helper) {
178 my $comp = $self->{long_type};
179 my $class = "Catalyst::Helper::$comp\::$helper";
180 eval "require $class";
181
182 if ($@) {
183 Catalyst::Exception->throw(
184 message => qq/Couldn't load helper "$class", "$@"/ );
185 }
186
23f9f145 187 ## must be left for back compat! ###################################
68ccb5e5 188 if ( $class->can('mk_compclass') ) {
189 return 1 unless $class->mk_compclass( $self, @args );
190 }
191 else { return 1 unless $self->_mk_compclass }
192
193 if ( $class->can('mk_comptest') ) {
194 $class->mk_comptest( $self, @args );
195 }
196 else { $self->_mk_comptest }
23f9f145 197 ####################################################################
68ccb5e5 198 }
199
200 # Fallback
201 else {
202 return 1 unless $self->_mk_compclass;
203 $self->_mk_comptest;
204 }
205 }
206 return 1;
207}
208
68ccb5e5 209sub mk_dir {
210 my ( $self, $dir ) = @_;
211 if ( -d $dir ) {
212 print qq/ exists "$dir"\n/;
213 return 0;
214 }
215 if ( mkpath [$dir] ) {
216 print qq/created "$dir"\n/;
217 return 1;
218 }
219
220 Catalyst::Exception->throw( message => qq/Couldn't create "$dir", "$!"/ );
221}
222
68ccb5e5 223sub mk_file {
224 my ( $self, $file, $content ) = @_;
06f62452 225 if ( -e $file && -s _ ) {
68ccb5e5 226 print qq/ exists "$file"\n/;
227 return 0
228 unless ( $self->{'.newfiles'}
229 || $self->{scripts}
230 || $self->{makefile} );
231 if ( $self->{'.newfiles'} ) {
232 if ( my $f = IO::File->new("< $file") ) {
233 my $oldcontent = join( '', (<$f>) );
234 return 0 if $content eq $oldcontent;
235 }
236 $file .= '.new';
237 }
238 }
620dd287 239
68ccb5e5 240 if ( my $f = IO::File->new("> $file") ) {
241 binmode $f;
242 print $f $content;
243 print qq/created "$file"\n/;
244 return 1;
245 }
246
247 Catalyst::Exception->throw( message => qq/Couldn't create "$file", "$!"/ );
248}
249
68ccb5e5 250sub next_test {
251 my ( $self, $tname ) = @_;
252 if ($tname) { $tname = "$tname.t" }
253 else {
254 my $name = $self->{name};
255 my $prefix = $name;
256 $prefix =~ s/::/-/g;
257 $prefix = $prefix;
258 $tname = $prefix . '.t';
259 $self->{prefix} = $prefix;
260 $prefix = lc $prefix;
261 $prefix =~ s/-/\//g;
262 $self->{uri} = "/$prefix";
263 }
264 my $dir = $self->{test_dir};
265 my $type = lc $self->{type};
266 $self->mk_dir($dir);
068587bd 267 return file( $dir, "$type\_$tname" );
68ccb5e5 268}
269
faae88e5 270# Do not touch this method, *EVER*, it is needed for back compat.
7025ed89 271## addendum: we had to split this method so we could have backwards
19fecc42 272## compatability. otherwise, we'd have no way to pass stuff from __DATA__
faae88e5 273
68ccb5e5 274sub render_file {
275 my ( $self, $file, $path, $vars ) = @_;
7025ed89 276 my $template = $self->get_file( ( caller(0) )[0], $file );
06f62452 277 $self->render_file_contents($template, $path, $vars);
7025ed89 278}
279
280sub render_sharedir_file {
281 my ( $self, $file, $path, $vars ) = @_;
282 my $template = $self->get_sharedir_file( $file );
f8d3d4e0 283 die("Cannot get template from $file for $self\n") unless $template;
e97273a4 284 $self->render_file_contents($template, $path, $vars);
7025ed89 285}
286
287sub render_file_contents {
288 my ( $self, $template, $path, $vars ) = @_;
68ccb5e5 289 $vars ||= {};
290 my $t = Template->new;
68ccb5e5 291 return 0 unless $template;
292 my $output;
293 $t->process( \$template, { %{$self}, %$vars }, \$output )
294 || Catalyst::Exception->throw(
7025ed89 295 message => qq/Couldn't process "$template", / . $t->error() );
68ccb5e5 296 $self->mk_file( $path, $output );
297}
298
45d74601 299sub _mk_information {
300 my $self = shift;
301 print qq/Change to application directory and Run "perl Makefile.PL" to make sure your install is complete\n/;
302}
303
68ccb5e5 304sub _mk_dirs {
305 my $self = shift;
306 $self->mk_dir( $self->{dir} );
307 $self->mk_dir( $self->{script} );
068587bd 308 $self->{lib} = dir( $self->{dir}, 'lib' );
68ccb5e5 309 $self->mk_dir( $self->{lib} );
068587bd 310 $self->{root} = dir( $self->{dir}, 'root' );
68ccb5e5 311 $self->mk_dir( $self->{root} );
068587bd 312 $self->{static} = dir( $self->{root}, 'static' );
68ccb5e5 313 $self->mk_dir( $self->{static} );
068587bd 314 $self->{images} = dir( $self->{static}, 'images' );
68ccb5e5 315 $self->mk_dir( $self->{images} );
068587bd 316 $self->{t} = dir( $self->{dir}, 't' );
68ccb5e5 317 $self->mk_dir( $self->{t} );
318
068587bd 319 $self->{class} = dir( split( /\:\:/, $self->{name} ) );
320 $self->{mod} = dir( $self->{lib}, $self->{class} );
68ccb5e5 321 $self->mk_dir( $self->{mod} );
322
323 if ( $self->{short} ) {
068587bd 324 $self->{m} = dir( $self->{mod}, 'M' );
68ccb5e5 325 $self->mk_dir( $self->{m} );
068587bd 326 $self->{v} = dir( $self->{mod}, 'V' );
68ccb5e5 327 $self->mk_dir( $self->{v} );
068587bd 328 $self->{c} = dir( $self->{mod}, 'C' );
68ccb5e5 329 $self->mk_dir( $self->{c} );
330 }
331 else {
068587bd 332 $self->{m} = dir( $self->{mod}, 'Model' );
68ccb5e5 333 $self->mk_dir( $self->{m} );
068587bd 334 $self->{v} = dir( $self->{mod}, 'View' );
68ccb5e5 335 $self->mk_dir( $self->{v} );
068587bd 336 $self->{c} = dir( $self->{mod}, 'Controller' );
68ccb5e5 337 $self->mk_dir( $self->{c} );
338 }
339 my $name = $self->{name};
340 $self->{rootname} =
341 $self->{short} ? "$name\::C::Root" : "$name\::Controller::Root";
068587bd 342 $self->{base} = dir( $self->{dir} )->absolute;
68ccb5e5 343}
344
345sub _mk_appclass {
346 my $self = shift;
347 my $mod = $self->{mod};
068587bd 348 $self->render_sharedir_file( file('lib', 'MyApp.pm.tt'), "$mod.pm" );
68ccb5e5 349}
350
351sub _mk_rootclass {
352 my $self = shift;
068587bd 353 $self->render_sharedir_file( file('lib', 'MyApp', 'Controller', 'Root.pm.tt'),
354 file( $self->{c}, "Root.pm" ) );
68ccb5e5 355}
356
357sub _mk_makefile {
358 my $self = shift;
068587bd 359 $self->{path} = dir( 'lib', split( '::', $self->{name} ) );
68ccb5e5 360 $self->{path} .= '.pm';
361 my $dir = $self->{dir};
068587bd 362 $self->render_sharedir_file( 'Makefile.PL.tt', file($dir, "Makefile.PL") );
68ccb5e5 363
364 if ( $self->{makefile} ) {
365
366 # deprecate the old Build.PL file when regenerating Makefile.PL
367 $self->_deprecate_file(
068587bd 368 file( $self->{dir}, 'Build.PL' ) );
68ccb5e5 369 }
370}
371
372sub _mk_config {
373 my $self = shift;
374 my $dir = $self->{dir};
375 my $appprefix = $self->{appprefix};
d5ff5c0f 376 $self->render_sharedir_file( 'myapp.conf.tt',
068587bd 377 file( $dir, "$appprefix.conf" ) );
68ccb5e5 378}
379
380sub _mk_readme {
381 my $self = shift;
382 my $dir = $self->{dir};
068587bd 383 $self->render_sharedir_file( 'README.tt', file($dir, "README") );
68ccb5e5 384}
385
386sub _mk_changes {
387 my $self = shift;
388 my $dir = $self->{dir};
5b1ec88b 389 my $time = strftime('%Y-%m-%d %H:%M:%S', localtime time);
957ccd4d 390 $self->render_sharedir_file( 'Changes.tt', file($dir, "Changes"), { time => $time } );
68ccb5e5 391}
392
393sub _mk_apptest {
394 my $self = shift;
395 my $t = $self->{t};
068587bd 396 $self->render_sharedir_file( file('t', '01app.t.tt'), file($t, "01app.t") );
397 $self->render_sharedir_file( file('t', '02pod.t.tt'), file($t, "02pod.t") );
398 $self->render_sharedir_file( file('t', '03podcoverage.t.tt'), file($t, "03podcoverage.t") );
68ccb5e5 399}
400
401sub _mk_cgi {
402 my $self = shift;
403 my $script = $self->{script};
404 my $appprefix = $self->{appprefix};
068587bd 405 $self->render_sharedir_file( file('script', 'myapp_cgi.pl.tt'), file($script,"$appprefix\_cgi.pl") );
406 chmod 0700, file($script,"$appprefix\_cgi.pl");
68ccb5e5 407}
408
409sub _mk_fastcgi {
410 my $self = shift;
411 my $script = $self->{script};
412 my $appprefix = $self->{appprefix};
068587bd 413 $self->render_sharedir_file( file('script', 'myapp_fastcgi.pl.tt'), file($script, "$appprefix\_fastcgi.pl") );
414 chmod 0700, file($script, "$appprefix\_fastcgi.pl");
68ccb5e5 415}
416
417sub _mk_server {
418 my $self = shift;
419 my $script = $self->{script};
420 my $appprefix = $self->{appprefix};
068587bd 421 $self->render_sharedir_file( file('script', 'myapp_server.pl.tt'), file($script, "$appprefix\_server.pl") );
422 chmod 0700, file($script, "$appprefix\_server.pl");
68ccb5e5 423}
424
425sub _mk_test {
426 my $self = shift;
427 my $script = $self->{script};
428 my $appprefix = $self->{appprefix};
068587bd 429 $self->render_sharedir_file( file('script', 'myapp_test.pl.tt'), file($script, "$appprefix\_test.pl") );
430 chmod 0700, file($script, "$appprefix\_test.pl");
68ccb5e5 431}
432
433sub _mk_create {
434 my $self = shift;
435 my $script = $self->{script};
436 my $appprefix = $self->{appprefix};
068587bd 437 $self->render_sharedir_file( file('script', 'myapp_create.pl.tt'), file($script, "$appprefix\_create.pl") );
438 chmod 0700, file($script, "$appprefix\_create.pl");
68ccb5e5 439}
440
441sub _mk_compclass {
442 my $self = shift;
443 my $file = $self->{file};
068587bd 444 return $self->render_sharedir_file( file('lib', 'Helper', 'compclass.pm.tt'), $file );
68ccb5e5 445}
446
447sub _mk_comptest {
448 my $self = shift;
449 my $test = $self->{test};
068587bd 450 $self->render_sharedir_file( file('t', 'comptest.tt'), $test ); ## wtf do i rename this to?
68ccb5e5 451}
452
453sub _mk_images {
454 my $self = shift;
455 my $images = $self->{images};
456 my @images =
457 qw/catalyst_logo btn_120x50_built btn_120x50_built_shadow
458 btn_120x50_powered btn_120x50_powered_shadow btn_88x31_built
459 btn_88x31_built_shadow btn_88x31_powered btn_88x31_powered_shadow/;
460 for my $name (@images) {
3f2f19ec 461 my $image = $self->get_sharedir_file("root", "static", "images", "$name.png.bin");
068587bd 462 $self->mk_file( file( $images, "$name.png" ), $image );
68ccb5e5 463 }
464}
465
466sub _mk_favicon {
467 my $self = shift;
468 my $root = $self->{root};
f023d4a1 469 my $favicon = $self->get_sharedir_file( 'root', 'favicon.ico.bin' );
068587bd 470 my $dest = dir( $root, "favicon.ico" );
afd739f1 471 $self->mk_file( $dest, $favicon );
68ccb5e5 472
473}
474
f5159e3e 475sub _mk_dbic_deploy {
476 my $self = shift;
477 my $script = $self->{script};
478 my $appprefix = $self->{appprefix};
068587bd 479 $self->render_sharedir_file( file('script', 'myapp_deploy_schema.pl.tt'), file($script, "$appprefix\_deploy_schema.pl") );
480 chmod 0700, file($script, "$appprefix\_deploy_schema.pl");
f5159e3e 481}
482
68ccb5e5 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
28eb1300 651=head3 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