| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | use Moose; | 
| 2 | 3 |  |  | 3 |  | 115310 | use Catalyst::Utils; | 
|  | 3 |  |  |  |  | 927010 |  | 
|  | 3 |  |  |  |  | 24 |  | 
| 3 | 3 |  |  | 3 |  | 22744 | use Class::Load qw(try_load_class load_class); | 
|  | 3 |  |  |  |  | 9 |  | 
|  | 3 |  |  |  |  | 109 |  | 
| 4 | 3 |  |  | 3 |  | 21 | use namespace::clean -except => [ 'meta' ]; | 
|  | 3 |  |  |  |  | 7 |  | 
|  | 3 |  |  |  |  | 201 |  | 
| 5 | 3 |  |  | 3 |  | 19 |  | 
|  | 3 |  |  |  |  | 6 |  | 
|  | 3 |  |  |  |  | 23 |  | 
| 6 |  |  |  |  |  |  | with 'Catalyst::ScriptRole'; | 
| 7 |  |  |  |  |  |  |  | 
| 8 |  |  |  |  |  |  | has debug => ( | 
| 9 |  |  |  |  |  |  | traits        => [qw(Getopt)], | 
| 10 |  |  |  |  |  |  | cmd_aliases   => 'd', | 
| 11 |  |  |  |  |  |  | isa           => 'Bool', | 
| 12 |  |  |  |  |  |  | is            => 'ro', | 
| 13 |  |  |  |  |  |  | documentation => q{Force debug mode}, | 
| 14 |  |  |  |  |  |  | ); | 
| 15 |  |  |  |  |  |  |  | 
| 16 |  |  |  |  |  |  | has host => ( | 
| 17 |  |  |  |  |  |  | traits        => [qw(Getopt)], | 
| 18 |  |  |  |  |  |  | cmd_aliases   => 'h', | 
| 19 |  |  |  |  |  |  | isa           => 'Str', | 
| 20 |  |  |  |  |  |  | is            => 'ro', | 
| 21 |  |  |  |  |  |  | # N.B. undef (the default) means we bind on all interfaces on the host. | 
| 22 |  |  |  |  |  |  | documentation => 'Specify a hostname or IP on this host for the server to bind to', | 
| 23 |  |  |  |  |  |  | ); | 
| 24 |  |  |  |  |  |  |  | 
| 25 |  |  |  |  |  |  | has fork => ( | 
| 26 |  |  |  |  |  |  | traits        => [qw(Getopt)], | 
| 27 |  |  |  |  |  |  | cmd_aliases   => 'f', | 
| 28 |  |  |  |  |  |  | isa           => 'Bool', | 
| 29 |  |  |  |  |  |  | is            => 'ro', | 
| 30 |  |  |  |  |  |  | default       => 0, | 
| 31 |  |  |  |  |  |  | documentation => 'Fork the server to be able to serve multiple requests at once', | 
| 32 |  |  |  |  |  |  | ); | 
| 33 |  |  |  |  |  |  |  | 
| 34 |  |  |  |  |  |  | has port => ( | 
| 35 |  |  |  |  |  |  | traits        => [qw(Getopt)], | 
| 36 |  |  |  |  |  |  | cmd_aliases   => 'p', | 
| 37 |  |  |  |  |  |  | isa           => 'Int', | 
| 38 |  |  |  |  |  |  | is            => 'ro', | 
| 39 |  |  |  |  |  |  | lazy          => 1, | 
| 40 |  |  |  |  |  |  | default       => sub { | 
| 41 |  |  |  |  |  |  | Catalyst::Utils::env_value(shift->application_name, 'port') || 3000 | 
| 42 |  |  |  |  |  |  | }, | 
| 43 |  |  |  |  |  |  | documentation => 'Specify a different listening port (to the default port 3000)', | 
| 44 |  |  |  |  |  |  | ); | 
| 45 |  |  |  |  |  |  |  | 
| 46 |  |  |  |  |  |  | has '+help_flag' => ( | 
| 47 |  |  |  |  |  |  | cmd_aliases => [ qw(usage ?) ], | 
| 48 |  |  |  |  |  |  | ); | 
| 49 |  |  |  |  |  |  |  | 
| 50 |  |  |  |  |  |  | use Moose::Util::TypeConstraints; | 
| 51 | 3 |  |  | 3 |  | 1639 | class_type 'MooseX::Daemonize::Pid::File'; | 
|  | 3 |  |  |  |  | 7 |  | 
|  | 3 |  |  |  |  | 29 |  | 
| 52 |  |  |  |  |  |  | subtype 'Catalyst::Script::Server::Types::Pidfile', | 
| 53 |  |  |  |  |  |  | as 'MooseX::Daemonize::Pid::File'; | 
| 54 |  |  |  |  |  |  |  | 
| 55 |  |  |  |  |  |  | coerce 'Catalyst::Script::Server::Types::Pidfile', from 'Str', via { | 
| 56 |  |  |  |  |  |  | my ($success, $error) = try_load_class("MooseX::Daemonize::Pid::File"); | 
| 57 |  |  |  |  |  |  | warn("Could not load MooseX::Daemonize::Pid::File, needed for --pid option: $error\n"), | 
| 58 |  |  |  |  |  |  | exit 1 if not $success; | 
| 59 |  |  |  |  |  |  | MooseX::Daemonize::Pid::File->new( file => $_ ); | 
| 60 |  |  |  |  |  |  | }; | 
| 61 |  |  |  |  |  |  | MooseX::Getopt::OptionTypeMap->add_option_type_to_map( | 
| 62 |  |  |  |  |  |  | 'Catalyst::Script::Server::Types::Pidfile' => '=s', | 
| 63 |  |  |  |  |  |  | ); | 
| 64 |  |  |  |  |  |  | has pidfile => ( | 
| 65 |  |  |  |  |  |  | traits        => [qw(Getopt)], | 
| 66 |  |  |  |  |  |  | cmd_aliases   => 'pid', | 
| 67 |  |  |  |  |  |  | isa           => 'Catalyst::Script::Server::Types::Pidfile', | 
| 68 |  |  |  |  |  |  | is            => 'ro', | 
| 69 |  |  |  |  |  |  | documentation => 'Specify a pidfile', | 
| 70 |  |  |  |  |  |  | coerce        => 1, | 
| 71 |  |  |  |  |  |  | predicate     => '_has_pidfile', | 
| 72 |  |  |  |  |  |  | ); | 
| 73 |  |  |  |  |  |  |  | 
| 74 |  |  |  |  |  |  | # Override MooseX::Daemonize | 
| 75 |  |  |  |  |  |  | my $self = shift; | 
| 76 | 0 |  |  | 0 | 0 | 0 |  | 
| 77 |  |  |  |  |  |  | if ($self->background) { | 
| 78 | 44 |  |  | 44 | 0 | 96 | # FIXME - This is evil. Should we just add MX::Daemonize to the deps? | 
| 79 |  |  |  |  |  |  | my ($success, $error) = try_load_class("MooseX::Daemonize::Core"); | 
| 80 | 44 | 50 |  |  |  | 1564 | warn("MooseX::Daemonize is needed for the --background option: $error\n"), | 
| 81 |  |  |  |  |  |  | exit 1 if not $success; | 
| 82 | 0 |  |  |  |  | 0 | ($success, $error) = try_load_class("POSIX"); | 
| 83 | 0 | 0 |  |  |  | 0 | warn("$error\n"), exit 1 if not $success; | 
| 84 |  |  |  |  |  |  | MooseX::Daemonize::Core->meta->apply($self); | 
| 85 | 0 |  |  |  |  | 0 | POSIX::close($_) foreach (0..2); | 
| 86 | 0 | 0 |  |  |  | 0 | } | 
| 87 | 0 |  |  |  |  | 0 | } | 
| 88 | 0 |  |  |  |  | 0 |  | 
| 89 |  |  |  |  |  |  | has keepalive => ( | 
| 90 |  |  |  |  |  |  | traits        => [qw(Getopt)], | 
| 91 |  |  |  |  |  |  | cmd_aliases   => 'k', | 
| 92 |  |  |  |  |  |  | isa           => 'Bool', | 
| 93 |  |  |  |  |  |  | is            => 'ro', | 
| 94 |  |  |  |  |  |  | default       => 0, | 
| 95 |  |  |  |  |  |  | documentation => 'Support keepalive', | 
| 96 |  |  |  |  |  |  | ); | 
| 97 |  |  |  |  |  |  |  | 
| 98 |  |  |  |  |  |  | has background => ( | 
| 99 |  |  |  |  |  |  | traits        => [qw(Getopt)], | 
| 100 |  |  |  |  |  |  | cmd_aliases   => 'bg', | 
| 101 |  |  |  |  |  |  | isa           => 'Bool', | 
| 102 |  |  |  |  |  |  | is            => 'ro', | 
| 103 |  |  |  |  |  |  | default       => 0, | 
| 104 |  |  |  |  |  |  | documentation => 'Run in the background', | 
| 105 |  |  |  |  |  |  | ); | 
| 106 |  |  |  |  |  |  |  | 
| 107 |  |  |  |  |  |  | has restart => ( | 
| 108 |  |  |  |  |  |  | traits        => [qw(Getopt)], | 
| 109 |  |  |  |  |  |  | cmd_aliases   => 'r', | 
| 110 |  |  |  |  |  |  | isa           => 'Bool', | 
| 111 |  |  |  |  |  |  | is            => 'ro', | 
| 112 |  |  |  |  |  |  | lazy          => 1, | 
| 113 |  |  |  |  |  |  | default       => sub { | 
| 114 |  |  |  |  |  |  | Catalyst::Utils::env_value(shift->application_name, 'reload') || 0; | 
| 115 |  |  |  |  |  |  | }, | 
| 116 |  |  |  |  |  |  | documentation => 'use Catalyst::Restarter to detect code changes and restart the application', | 
| 117 |  |  |  |  |  |  | ); | 
| 118 |  |  |  |  |  |  |  | 
| 119 |  |  |  |  |  |  | has restart_directory => ( | 
| 120 |  |  |  |  |  |  | traits        => [qw(Getopt)], | 
| 121 |  |  |  |  |  |  | cmd_aliases   => [ 'rdir', 'restartdirectory' ], | 
| 122 |  |  |  |  |  |  | isa           => 'ArrayRef[Str]', | 
| 123 |  |  |  |  |  |  | is            => 'ro', | 
| 124 |  |  |  |  |  |  | documentation => 'Restarter directory to watch', | 
| 125 |  |  |  |  |  |  | predicate     => '_has_restart_directory', | 
| 126 |  |  |  |  |  |  | ); | 
| 127 |  |  |  |  |  |  |  | 
| 128 |  |  |  |  |  |  | has restart_delay => ( | 
| 129 |  |  |  |  |  |  | traits        => [qw(Getopt)], | 
| 130 |  |  |  |  |  |  | cmd_aliases   => 'rd', | 
| 131 |  |  |  |  |  |  | isa           => 'Int', | 
| 132 |  |  |  |  |  |  | is            => 'ro', | 
| 133 |  |  |  |  |  |  | documentation => 'Set a restart delay', | 
| 134 |  |  |  |  |  |  | predicate     => '_has_restart_delay', | 
| 135 |  |  |  |  |  |  | ); | 
| 136 |  |  |  |  |  |  |  | 
| 137 |  |  |  |  |  |  | { | 
| 138 |  |  |  |  |  |  | use Moose::Util::TypeConstraints; | 
| 139 |  |  |  |  |  |  |  | 
| 140 |  |  |  |  |  |  | my $tc = subtype 'Catalyst::Script::Server::Types::RegexpRef', as 'RegexpRef'; | 
| 141 | 3 |  |  | 3 |  | 8377 | coerce $tc, from 'Str', via { qr/$_/ }; | 
|  | 3 |  |  |  |  | 7 |  | 
|  | 3 |  |  |  |  | 36 |  | 
| 142 |  |  |  |  |  |  |  | 
| 143 |  |  |  |  |  |  | MooseX::Getopt::OptionTypeMap->add_option_type_to_map($tc => '=s'); | 
| 144 |  |  |  |  |  |  |  | 
| 145 |  |  |  |  |  |  | has restart_regex => ( | 
| 146 |  |  |  |  |  |  | traits        => [qw(Getopt)], | 
| 147 |  |  |  |  |  |  | cmd_aliases   => 'rr', | 
| 148 |  |  |  |  |  |  | isa           => $tc, | 
| 149 |  |  |  |  |  |  | coerce        => 1, | 
| 150 |  |  |  |  |  |  | is            => 'ro', | 
| 151 |  |  |  |  |  |  | documentation => 'Restart regex', | 
| 152 |  |  |  |  |  |  | predicate     => '_has_restart_regex', | 
| 153 |  |  |  |  |  |  | ); | 
| 154 |  |  |  |  |  |  | } | 
| 155 |  |  |  |  |  |  |  | 
| 156 |  |  |  |  |  |  | has follow_symlinks => ( | 
| 157 |  |  |  |  |  |  | traits        => [qw(Getopt)], | 
| 158 |  |  |  |  |  |  | cmd_aliases   => 'sym', | 
| 159 |  |  |  |  |  |  | isa           => 'Bool', | 
| 160 |  |  |  |  |  |  | is            => 'ro', | 
| 161 |  |  |  |  |  |  | default       => 0, | 
| 162 |  |  |  |  |  |  | documentation => 'Follow symbolic links', | 
| 163 |  |  |  |  |  |  | predicate     => '_has_follow_symlinks', | 
| 164 |  |  |  |  |  |  | ); | 
| 165 |  |  |  |  |  |  |  | 
| 166 |  |  |  |  |  |  | my $self = shift; | 
| 167 |  |  |  |  |  |  | return $self->fork || $self->keepalive ? 'Starman' : 'Standalone'; | 
| 168 |  |  |  |  |  |  | } | 
| 169 |  |  |  |  |  |  |  | 
| 170 | 18 |  |  | 18 |  | 32 | my $self = shift; | 
| 171 | 18 | 50 | 33 |  |  | 557 |  | 
| 172 |  |  |  |  |  |  | return ( | 
| 173 |  |  |  |  |  |  | argv => $self->ARGV, | 
| 174 |  |  |  |  |  |  | start_sub => sub { $self->_run_application }, | 
| 175 | 20 |  |  | 20 |  | 52 | ($self->_has_follow_symlinks   ? (follow_symlinks => $self->follow_symlinks)   : ()), | 
| 176 |  |  |  |  |  |  | ($self->_has_restart_delay     ? (sleep_interval  => $self->restart_delay)     : ()), | 
| 177 |  |  |  |  |  |  | ($self->_has_restart_directory ? (directories     => $self->restart_directory) : ()), | 
| 178 |  |  |  |  |  |  | ($self->_has_restart_regex     ? (filter          => $self->restart_regex)     : ()), | 
| 179 | 0 |  |  | 0 |  | 0 | ), | 
| 180 |  |  |  |  |  |  | ( | 
| 181 |  |  |  |  |  |  | map { $_ => $self->$_ } qw(application_name host port debug pidfile fork background keepalive) | 
| 182 |  |  |  |  |  |  | ); | 
| 183 |  |  |  |  |  |  | } | 
| 184 |  |  |  |  |  |  |  | 
| 185 |  |  |  |  |  |  | has restarter_class => ( | 
| 186 | 20 | 50 |  |  |  | 715 | is => 'ro', | 
|  | 160 | 100 |  |  |  | 4609 |  | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 100 |  |  |  |  |  | 
| 187 |  |  |  |  |  |  | isa => 'Str', | 
| 188 |  |  |  |  |  |  | lazy => 1, | 
| 189 |  |  |  |  |  |  | default => sub { | 
| 190 |  |  |  |  |  |  | my $self = shift; | 
| 191 |  |  |  |  |  |  | Catalyst::Utils::env_value($self->application_name, 'RESTARTER') || 'Catalyst::Restarter'; | 
| 192 |  |  |  |  |  |  | } | 
| 193 |  |  |  |  |  |  | ); | 
| 194 |  |  |  |  |  |  |  | 
| 195 |  |  |  |  |  |  | my $self = shift; | 
| 196 |  |  |  |  |  |  |  | 
| 197 |  |  |  |  |  |  | local $ENV{CATALYST_DEBUG} = 1 | 
| 198 |  |  |  |  |  |  | if $self->debug; | 
| 199 |  |  |  |  |  |  |  | 
| 200 |  |  |  |  |  |  | if ( $self->restart ) { | 
| 201 | 18 |  |  | 18 | 0 | 16998 | die "Cannot run in the background and also watch for changed files.\n" | 
| 202 |  |  |  |  |  |  | if $self->background; | 
| 203 | 18 | 50 |  |  |  | 668 | die "Cannot write out a pid file and fork for the restarter.\n" | 
| 204 |  |  |  |  |  |  | if $self->_has_pidfile; | 
| 205 |  |  |  |  |  |  |  | 
| 206 | 18 | 50 |  |  |  | 535 | # If we load this here, then in the case of a restarter, it does not | 
| 207 | 0 | 0 |  |  |  | 0 | # need to be reloaded for each restart. | 
| 208 |  |  |  |  |  |  | require Catalyst; | 
| 209 | 0 | 0 |  |  |  | 0 |  | 
| 210 |  |  |  |  |  |  | # If this isn't done, then the Catalyst::Devel tests for the restarter | 
| 211 |  |  |  |  |  |  | # fail. | 
| 212 |  |  |  |  |  |  | $| = 1 if $ENV{HARNESS_ACTIVE}; | 
| 213 |  |  |  |  |  |  |  | 
| 214 | 0 |  |  |  |  | 0 | Catalyst::Utils::ensure_class_loaded($self->restarter_class); | 
| 215 |  |  |  |  |  |  |  | 
| 216 |  |  |  |  |  |  | my $subclass = $self->restarter_class->pick_subclass; | 
| 217 |  |  |  |  |  |  |  | 
| 218 | 0 | 0 |  |  |  | 0 | my $restarter = $subclass->new( | 
| 219 |  |  |  |  |  |  | $self->_restarter_args() | 
| 220 | 0 |  |  |  |  | 0 | ); | 
| 221 |  |  |  |  |  |  |  | 
| 222 | 0 |  |  |  |  | 0 | $restarter->run_and_watch; | 
| 223 |  |  |  |  |  |  | } | 
| 224 | 0 |  |  |  |  | 0 | else { | 
| 225 |  |  |  |  |  |  | if ($self->background) { | 
| 226 |  |  |  |  |  |  | $self->daemon_fork; | 
| 227 |  |  |  |  |  |  |  | 
| 228 | 0 |  |  |  |  | 0 | return 1 unless $self->is_daemon; | 
| 229 |  |  |  |  |  |  |  | 
| 230 |  |  |  |  |  |  | load_class($self->application_name); | 
| 231 | 18 | 50 |  |  |  | 538 |  | 
| 232 | 0 |  |  |  |  | 0 | $self->daemon_detach; | 
| 233 |  |  |  |  |  |  | } | 
| 234 | 0 | 0 |  |  |  | 0 |  | 
| 235 |  |  |  |  |  |  | $self->pidfile->write | 
| 236 | 0 |  |  |  |  | 0 | if $self->_has_pidfile; | 
| 237 |  |  |  |  |  |  |  | 
| 238 | 0 |  |  |  |  | 0 | $self->_run_application; | 
| 239 |  |  |  |  |  |  | } | 
| 240 |  |  |  |  |  |  |  | 
| 241 |  |  |  |  |  |  |  | 
| 242 | 18 | 50 |  |  |  | 598 | } | 
| 243 |  |  |  |  |  |  |  | 
| 244 | 18 |  |  |  |  | 82 | my ($self) = shift; | 
| 245 |  |  |  |  |  |  | return ( | 
| 246 |  |  |  |  |  |  | port => $self->port, | 
| 247 |  |  |  |  |  |  | host => $self->host, | 
| 248 |  |  |  |  |  |  | keepalive => $self->keepalive ? 100 : 1, | 
| 249 |  |  |  |  |  |  | server_ready => sub { | 
| 250 |  |  |  |  |  |  | my ($args) = @_; | 
| 251 | 18 |  |  | 18 |  | 42 |  | 
| 252 |  |  |  |  |  |  | my $name  = $args->{server_software} || ref($args); # $args is $server | 
| 253 |  |  |  |  |  |  | my $host  = $args->{host} || 0; | 
| 254 |  |  |  |  |  |  | my $proto = $args->{proto} || 'http'; | 
| 255 |  |  |  |  |  |  |  | 
| 256 |  |  |  |  |  |  | print STDERR "$name: Accepting connections at $proto://$host:$args->{port}/\n"; | 
| 257 | 0 |  |  | 0 |  |  | }, | 
| 258 |  |  |  |  |  |  | ); | 
| 259 | 0 |  | 0 |  |  |  | } | 
| 260 | 0 |  | 0 |  |  |  |  | 
| 261 | 0 |  | 0 |  |  |  | around _application_args => sub { | 
| 262 |  |  |  |  |  |  | my ($orig, $self) = @_; | 
| 263 | 0 |  |  |  |  |  | return ( | 
| 264 |  |  |  |  |  |  | $self->port, | 
| 265 | 18 | 50 |  |  |  | 503 | $self->host, | 
| 266 |  |  |  |  |  |  | { | 
| 267 |  |  |  |  |  |  | %{ $self->$orig }, | 
| 268 |  |  |  |  |  |  | map { $_ => $self->$_ } qw/ | 
| 269 |  |  |  |  |  |  | fork | 
| 270 |  |  |  |  |  |  | keepalive | 
| 271 |  |  |  |  |  |  | background | 
| 272 |  |  |  |  |  |  | pidfile | 
| 273 |  |  |  |  |  |  | keepalive | 
| 274 |  |  |  |  |  |  | follow_symlinks | 
| 275 |  |  |  |  |  |  | port | 
| 276 |  |  |  |  |  |  | host | 
| 277 |  |  |  |  |  |  | /, | 
| 278 |  |  |  |  |  |  | }, | 
| 279 |  |  |  |  |  |  | ); | 
| 280 |  |  |  |  |  |  | }; | 
| 281 |  |  |  |  |  |  |  | 
| 282 |  |  |  |  |  |  | __PACKAGE__->meta->make_immutable; | 
| 283 |  |  |  |  |  |  | 1; | 
| 284 |  |  |  |  |  |  |  | 
| 285 |  |  |  |  |  |  | =head1 NAME | 
| 286 |  |  |  |  |  |  |  | 
| 287 |  |  |  |  |  |  | Catalyst::Script::Server - Catalyst test server | 
| 288 |  |  |  |  |  |  |  | 
| 289 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 290 |  |  |  |  |  |  |  | 
| 291 |  |  |  |  |  |  | myapp_server.pl [options] | 
| 292 |  |  |  |  |  |  |  | 
| 293 |  |  |  |  |  |  | Options: | 
| 294 |  |  |  |  |  |  | -d     --debug          force debug mode | 
| 295 |  |  |  |  |  |  | -f     --fork           handle each request in a new process | 
| 296 |  |  |  |  |  |  | (defaults to false) | 
| 297 |  |  |  |  |  |  | --help           display this help and exits | 
| 298 |  |  |  |  |  |  | -h     --host           host (defaults to all) | 
| 299 |  |  |  |  |  |  | -p     --port           port (defaults to 3000) | 
| 300 |  |  |  |  |  |  | -k     --keepalive      enable keep-alive connections | 
| 301 |  |  |  |  |  |  | -r     --restart        restart when files get modified | 
| 302 |  |  |  |  |  |  | (defaults to false) | 
| 303 |  |  |  |  |  |  | --rd   --restart_delay  delay between file checks | 
| 304 |  |  |  |  |  |  | (ignored if you have Linux::Inotify2 installed) | 
| 305 |  |  |  |  |  |  | --rr   --restart_regex  regex match files that trigger | 
| 306 |  |  |  |  |  |  | a restart when modified | 
| 307 |  |  |  |  |  |  | (defaults to '\.yml$|\.yaml$|\.conf|\.pm$') | 
| 308 |  |  |  |  |  |  | --rdir --restart_directory  the directory to search for | 
| 309 |  |  |  |  |  |  | modified files, can be set multiple times | 
| 310 |  |  |  |  |  |  | (defaults to '[SCRIPT_DIR]/..') | 
| 311 |  |  |  |  |  |  | --sym  --follow_symlinks   follow symlinks in search directories | 
| 312 |  |  |  |  |  |  | (defaults to false. this is a no-op on Win32) | 
| 313 |  |  |  |  |  |  | --bg   --background        run the process in the background | 
| 314 |  |  |  |  |  |  | --pid  --pidfile           specify filename for pid file | 
| 315 |  |  |  |  |  |  |  | 
| 316 |  |  |  |  |  |  | See also: | 
| 317 |  |  |  |  |  |  | perldoc Catalyst::Manual | 
| 318 |  |  |  |  |  |  | perldoc Catalyst::Manual::Intro | 
| 319 |  |  |  |  |  |  |  | 
| 320 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 321 |  |  |  |  |  |  |  | 
| 322 |  |  |  |  |  |  | Run a Catalyst test server for this application. | 
| 323 |  |  |  |  |  |  |  | 
| 324 |  |  |  |  |  |  | =head1 SEE ALSO | 
| 325 |  |  |  |  |  |  |  | 
| 326 |  |  |  |  |  |  | L<Catalyst::ScriptRunner> | 
| 327 |  |  |  |  |  |  |  | 
| 328 |  |  |  |  |  |  | =head1 AUTHORS | 
| 329 |  |  |  |  |  |  |  | 
| 330 |  |  |  |  |  |  | Catalyst Contributors, see Catalyst.pm | 
| 331 |  |  |  |  |  |  |  | 
| 332 |  |  |  |  |  |  | =head1 COPYRIGHT | 
| 333 |  |  |  |  |  |  |  | 
| 334 |  |  |  |  |  |  | This library is free software. You can redistribute it and/or modify | 
| 335 |  |  |  |  |  |  | it under the same terms as Perl itself. | 
| 336 |  |  |  |  |  |  |  | 
| 337 |  |  |  |  |  |  | =cut |