Merge branch 'pr/135' into release-candidates/rc-5.90116
[catagits/Catalyst-Runtime.git] / lib / Catalyst / ScriptRole.pm
1 package Catalyst::ScriptRole;
2 use Moose::Role;
3 use Pod::Usage;
4 use MooseX::Getopt;
5 use Catalyst::EngineLoader;
6 use Moose::Util::TypeConstraints;
7 use Catalyst::Utils;
8 use namespace::autoclean;
9
10 subtype 'Catalyst::ScriptRole::LoadableClass',
11   as 'ClassName';
12 coerce 'Catalyst::ScriptRole::LoadableClass',
13   from 'Str',
14   via { Catalyst::Utils::ensure_class_loaded($_); $_ };
15
16 with 'MooseX::Getopt' => {
17     -version => 0.48,
18     -excludes => [qw/
19         _getopt_spec_warnings
20         _getopt_spec_exception
21         print_usage_text
22     /],
23 };
24
25 has application_name => (
26     traits   => ['NoGetopt'],
27     isa      => 'Str',
28     is       => 'ro',
29     required => 1,
30 );
31
32 has loader_class => (
33     isa => 'Catalyst::ScriptRole::LoadableClass',
34     is => 'ro',
35     coerce => 1,
36     default => 'Catalyst::EngineLoader',
37     documentation => 'The class to use to detect and load the PSGI engine',
38 );
39
40 has _loader => (
41     isa => 'Plack::Loader',
42     default => sub {
43         my $self = shift;
44         $self->loader_class->new(application_name => $self->application_name);
45     },
46     handles => {
47         load_engine => 'load',
48         autoload_engine => 'auto',
49     },
50     lazy => 1,
51 );
52
53 sub _getopt_spec_exception {}
54
55 sub _getopt_spec_warnings {
56     shift;
57     warn @_;
58 }
59
60 sub print_usage_text {
61     my $self = shift;
62     pod2usage();
63     exit 0;
64 }
65
66 sub run {
67     my $self = shift;
68     $self->_run_application;
69 }
70
71 sub _application_args {
72     my $self = shift;
73     return {
74         argv => $self->ARGV,
75         extra_argv => $self->extra_argv,
76     }
77 }
78
79 sub _plack_loader_args {
80     my $self = shift;
81     my @app_args = $self->_application_args;
82     return (port => $app_args[0]);
83 }
84
85 sub _plack_engine_name {}
86
87 sub _run_application {
88     my $self = shift;
89     my $app = $self->application_name;
90     Catalyst::Utils::ensure_class_loaded($app);
91     my $server;
92     if (my $e = $self->_plack_engine_name ) {
93         $server = $self->load_engine($e, $self->_plack_loader_args);
94     }
95     else {
96         $server = $self->autoload_engine($self->_plack_loader_args);
97     }
98     $app->run($self->_application_args, $server);
99 }
100
101 1;
102
103 =head1 NAME
104
105 Catalyst::ScriptRole - Common functionality for Catalyst scripts.
106
107 =head1 SYNOPSIS
108
109     package MyApp::Script::Foo;
110     use Moose;
111     use namespace::autoclean;
112
113     with 'Catalyst::ScriptRole';
114
115     sub _application_args { ... }
116
117 =head1 DESCRIPTION
118
119 Role with the common functionality of Catalyst scripts.
120
121 =head1 METHODS
122
123 =head2 run
124
125 The method invoked to run the application.
126
127 =head2 print_usage_text
128
129 Prints out the usage text for the script you tried to invoke.
130
131 =head1 ATTRIBUTES
132
133 =head2 application_name
134
135 The name of the application class, e.g. MyApp
136
137 =head1 SEE ALSO
138
139 L<Catalyst>
140
141 L<MooseX::Getopt>
142
143 =head1 AUTHORS
144
145 Catalyst Contributors, see Catalyst.pm
146
147 =head1 COPYRIGHT
148
149 This library is free software, you can redistribute it and/or modify
150 it under the same terms as Perl itself.
151
152 =cut