X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Runtime.git;a=blobdiff_plain;f=lib%2FCatalyst%2FScriptRunner.pm;h=7b803771e339b7623e069adb819db4e41539e105;hp=cc280947b2648de700c5ca75d6c397159e4ea7d0;hb=15c40696c8e1e840553573af61037032cc16768d;hpb=410d96eb61df4f4c5beecb9bf7a6757e7e19ce24 diff --git a/lib/Catalyst/ScriptRunner.pm b/lib/Catalyst/ScriptRunner.pm index cc28094..7b80377 100644 --- a/lib/Catalyst/ScriptRunner.pm +++ b/lib/Catalyst/ScriptRunner.pm @@ -1,18 +1,112 @@ package Catalyst::ScriptRunner; use Moose; -extends qw(MooseX::App::Cmd::Command); +use FindBin; +use lib; +use File::Spec; +use Class::Load qw/ load_first_existing_class load_optional_class /; +use Catalyst::Utils; +use namespace::autoclean -also => 'subclass_with_traits'; +use Try::Tiny; +sub find_script_class { + my ($self, $app, $script) = @_; + return load_first_existing_class("${app}::Script::${script}", "Catalyst::Script::$script"); +} + +sub find_script_traits { + my ($self, @try) = @_; + + return grep { load_optional_class($_) } @try; +} + +sub subclass_with_traits { + my ($base, @traits) = @_; + + my $meta = Class::MOP::class_of($base)->create_anon_class( + superclasses => [ $base ], + roles => [ @traits ], + cache => 1, + ); + $meta->add_method(meta => sub { $meta }); + + return $meta->name; +} sub run { - my ($self, $class, $scriptclass) = @_; - my $classtoload = "${class}::Script::$scriptclass"; - - # FIXME - Error handling / reporting - if ( eval { Class::MOP::load_class($classtoload) } ) { - } else { - $classtoload = "Catalyst::Script::$scriptclass"; - Class::MOP::load_class($classtoload); + my ($self, $appclass, $scriptclass) = @_; + + if (my $home = Catalyst::Utils::find_home_unloaded_in_checkout()) { + lib->import(File::Spec->catdir($home, 'lib')); } - $classtoload->new_with_options( app => $class )->run; + + my $class = $self->find_script_class($appclass, $scriptclass); + + my @possible_traits = ("${appclass}::TraitFor::Script::${scriptclass}", "${appclass}::TraitFor::Script"); + my @traits = $self->find_script_traits(@possible_traits); + + $class = subclass_with_traits($class, @traits) + if @traits; + + $class->new_with_options( application_name => $appclass )->run; } + +__PACKAGE__->meta->make_immutable; 1; + +=head1 NAME + +Catalyst::ScriptRunner - The Catalyst Framework script runner + +=head1 SYNOPSIS + + # Will run MyApp::Script::Server if it exists, otherwise + # will run Catalyst::Script::Server. + Catalyst::ScriptRunner->run('MyApp', 'Server'); + +=head1 DESCRIPTION + +This class is responsible for loading and running scripts, either in the +application specific namespace +(e.g. C), or the Catalyst namespace (e.g. C). + +If your application contains a custom script, then it will be used in preference to the generic +script, and is expected to sub-class the standard script. + +=head1 TRAIT LOADING + +Catalyst will automatically load and apply roles to the scripts in your +application. + +C will be loaded if present, and will be applied to B +scripts. + +C will be loaded (if present) and for script +individually. + +=head1 METHODS + +=head2 run ($application_class, $scriptclass) + +Called with two parameters, the application class (e.g. MyApp) +and the script class, (i.e. one of Server/FastCGI/CGI/Create/Test) + +=head2 find_script_class ($appname, $script_name) + +Finds and loads the class for the script, trying the application specific +script first, and falling back to the generic script. Returns the script +which was loaded. + +=head2 find_script_traits ($appname, @try) + +Finds and loads a set of traits. Returns the list of traits which were loaded. + +=head1 AUTHORS + +Catalyst Contributors, see Catalyst.pm + +=head1 COPYRIGHT + +This library is free software. You can redistribute it and/or modify it under +the same terms as Perl itself. + +=cut