Merge branch 'master' into psgi
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Script / Server.pm
index c3c6584..1ec97a3 100644 (file)
 package Catalyst::Script::Server;
-
-BEGIN {
-    $ENV{CATALYST_ENGINE} ||= 'HTTP';
-    require Catalyst::Engine::HTTP;
-}
-
 use Moose;
-use MooseX::Types::Moose qw/ArrayRef Str Bool Int/;
+use MooseX::Types::Common::Numeric qw/PositiveInt/;
+use MooseX::Types::Moose qw/ArrayRef Str Bool Int RegexpRef/;
+use Catalyst::Utils;
 use namespace::autoclean;
 
-with 'Catalyst::ScriptRole';
+sub _plack_engine_name { 'Standalone' }
 
-__PACKAGE__->meta->get_attribute('help')->cmd_aliases('?');
+with 'Catalyst::ScriptRole';
 
 has debug => (
-    traits => [qw(Getopt)],
-    cmd_aliases => 'd',
-    isa => Bool,
-    is => 'ro',
+    traits        => [qw(Getopt)],
+    cmd_aliases   => 'd',
+    isa           => Bool,
+    is            => 'ro',
     documentation => q{Force debug mode},
 );
 
 has host => (
-    traits => [qw(Getopt)],
-    cmd_aliases => 'h',
-    isa => Str,
-    is => 'ro',
-    default => 'localhost',
-    documentation => 'Specify an IP on this host for the server to bind to',
+    traits        => [qw(Getopt)],
+    cmd_aliases   => 'h',
+    isa           => Str,
+    is            => 'ro',
+    # N.B. undef (the default) means we bind on all interfaces on the host.
+    documentation => 'Specify a hostname or IP on this host for the server to bind to',
 );
 
 has fork => (
-    traits => [qw(Getopt)],
-    cmd_aliases => 'f',
-    isa => Bool,
-    is => 'ro',
-    default => 0,
+    traits        => [qw(Getopt)],
+    cmd_aliases   => 'f',
+    isa           => Bool,
+    is            => 'ro',
+    default       => 0,
     documentation => 'Fork the server to be able to serve multiple requests at once',
 );
 
 has port => (
-    traits => [qw(Getopt)],
-    cmd_aliases => 'p',
-    isa => Int,
-    is => 'ro',
-    default => 3000,
+    traits        => [qw(Getopt)],
+    cmd_aliases   => 'p',
+    isa           => PositiveInt,
+    is            => 'ro',
+    default       => sub {
+        Catalyst::Utils::env_value(shift->application_name, 'port') || 3000
+    },
     documentation => 'Specify a different listening port (to the default port 3000)',
 );
 
 has pidfile => (
-    traits => [qw(Getopt)],
-    cmd_aliases => 'pid',
-    isa => Str,
-    is => 'ro',
+    traits        => [qw(Getopt)],
+    cmd_aliases   => 'pid',
+    isa           => Str,
+    is            => 'ro',
     documentation => 'Specify a pidfile',
 );
 
 has keepalive => (
-    traits => [qw(Getopt)],
-    cmd_aliases => 'k',
-    isa => Bool,
-    is => 'ro',
-    default => 0,
+    traits        => [qw(Getopt)],
+    cmd_aliases   => 'k',
+    isa           => Bool,
+    is            => 'ro',
+    default       => 0,
     documentation => 'Support keepalive',
 );
 
 has background => (
-    traits => [qw(Getopt)],
-    cmd_aliases => 'bg',
-    isa => Bool,
-    is => 'ro',
-    default => 0,
+    traits        => [qw(Getopt)],
+    cmd_aliases   => 'bg',
+    isa           => Bool,
+    is            => 'ro',
+    default       => 0,
     documentation => 'Run in the background',
 );
 
 has restart => (
-    traits => [qw(Getopt)],
-    cmd_aliases => 'r',
-    isa => Bool,
-    is => 'ro',
-    default => 0,
+    traits        => [qw(Getopt)],
+    cmd_aliases   => 'r',
+    isa           => Bool,
+    is            => 'ro',
+    default       => sub {
+        Catalyst::Utils::env_value(shift->application_name, 'reload') || 0;
+    },
     documentation => 'use Catalyst::Restarter to detect code changes and restart the application',
 );
 
 has restart_directory => (
-    traits => [qw(Getopt)],
-    cmd_aliases => 'rdir',
-    isa => ArrayRef[Str],
-    is  => 'ro',
+    traits        => [qw(Getopt)],
+    cmd_aliases   => [ 'rdir', 'restartdirectory' ],
+    isa           => ArrayRef[Str],
+    is            => 'ro',
     documentation => 'Restarter directory to watch',
-    predicate => '_has_restart_directory',
+    predicate     => '_has_restart_directory',
 );
 
 has restart_delay => (
-    traits => [qw(Getopt)],
-    cmd_aliases => 'rd',
-    isa => Int,
-    is => 'ro',
+    traits        => [qw(Getopt)],
+    cmd_aliases   => 'rd',
+    isa           => Int,
+    is            => 'ro',
     documentation => 'Set a restart delay',
-    predicate => '_has_restart_delay',
+    predicate     => '_has_restart_delay',
 );
 
-has restart_regex => (
-    traits => [qw(Getopt)],
-    cmd_aliases => 'rr',
-    isa => Str,
-    is => 'ro',
-    documentation => 'Restart regex',
-    predicate => '_has_restart_regex',
-);
+{
+    use Moose::Util::TypeConstraints;
+
+    my $tc = subtype as RegexpRef;
+    coerce $tc, from Str, via { qr/$_/ };
+
+    MooseX::Getopt::OptionTypeMap->add_option_type_to_map($tc => '=s');
+
+    has restart_regex => (
+        traits        => [qw(Getopt)],
+        cmd_aliases   => 'rr',
+        isa           => $tc,
+        coerce        => 1,
+        is            => 'ro',
+        documentation => 'Restart regex',
+        predicate     => '_has_restart_regex',
+    );
+}
 
 has follow_symlinks => (
-    traits => [qw(Getopt)],
-    cmd_aliases => 'sym',
-    isa => Bool,
-    is => 'ro',
-    default => 0,
+    traits        => [qw(Getopt)],
+    cmd_aliases   => 'sym',
+    isa           => Bool,
+    is            => 'ro',
+    default       => 0,
     documentation => 'Follow symbolic links',
+    predicate     => '_has_follow_symlinks',
 );
 
+sub _restarter_args {
+    my $self = shift;
+
+    return (
+        argv => $self->ARGV,
+        start_sub => sub { $self->_run_application },
+        ($self->_has_follow_symlinks   ? (follow_symlinks => $self->follow_symlinks)   : ()),
+        ($self->_has_restart_delay     ? (sleep_interval  => $self->restart_delay)     : ()),
+        ($self->_has_restart_directory ? (directories     => $self->restart_directory) : ()),
+        ($self->_has_restart_regex     ? (filter          => $self->restart_regex)     : ()),
+    );
+}
+
 sub run {
-    my ($self) = shift;
+    my $self = shift;
 
     local $ENV{CATALYST_DEBUG} = 1
         if $self->debug;
@@ -141,20 +165,8 @@ sub run {
 
         my $subclass = Catalyst::Restarter->pick_subclass;
 
-        my %args;
-        $args{follow_symlinks} = $self->follow_symlinks
-            if $self->follow_symlinks;
-        $args{directories}     = $self->restart_directory
-            if $self->_has_restart_directory;
-        $args{sleep_interval}  = $self->restart_delay
-            if $self->_has_restart_delay;
-        $args{filter} = qr/$self->restart_regex/
-            if $self->_has_restart_regex;
-
         my $restarter = $subclass->new(
-            %args,
-            start_sub => sub { $self->_run_application },
-            argv      => $self->ARGV,
+            $self->_restarter_args()
         );
 
         $restarter->run_and_watch;
@@ -166,12 +178,22 @@ sub run {
 
 }
 
+sub _plack_loader_args {
+    my ($self) = shift;
+    return (
+        port => $self->port,
+        host => $self->host,
+        keepalive => $self->keepalive ? 100 : 1,
+    );
+}
+
 sub _application_args {
     my ($self) = shift;
     return (
         $self->port,
         $self->host,
         {
+           argv => $self->ARGV,
            map { $_ => $self->$_ } qw/
                 fork
                 keepalive
@@ -206,13 +228,13 @@ Catalyst::Script::Server - Catalyst test server
    -k     --keepalive      enable keep-alive connections
    -r     --restart        restart when files get modified
                        (defaults to false)
-   --rd   --restartdelay  delay between file checks
+   --rd   --restart_delay  delay between file checks
                       (ignored if you have Linux::Inotify2 installed)
-   --rr   --restartregex  regex match files that trigger
+   --rr   --restart_regex  regex match files that trigger
                       a restart when modified
                       (defaults to '\.yml$|\.yaml$|\.conf|\.pm$')
-   --rdir --restartdirectory  the directory to search for
-                      modified files, can be set mulitple times
+   --rdir --restart_directory  the directory to search for
+                      modified files, can be set multiple times
                       (defaults to '[SCRIPT_DIR]/..')
    --sym  --follow_symlinks   follow symlinks in search directories
                       (defaults to false. this is a no-op on Win32)