Pass all normal script options by default.
This enables applications which have custom script options
(e.g. Gitalist) to get at the options the user gave at app startup,
without needed horrible code to stash the options in global or
environment variables.
__PACKAGE__->mk_classdata($_)
for qw/components arguments dispatcher engine log dispatcher_class
engine_loader context_class request_class response_class stats_class
- setup_finished _psgi_app loading_psgi_file/;
+ setup_finished _psgi_app loading_psgi_file run_options/;
__PACKAGE__->dispatcher_class('Catalyst::Dispatcher');
__PACKAGE__->request_class('Catalyst::Request');
EOF
}
+=head2 run_options
+
+Contains a hash of options passed from the application script, including
+the original ARGV the script receieved, the processed values from that
+ARGV and any extra arguments to the script which were not processed.
+
+This can be used to add custom options to your application's scripts
+and setup your application differently depending on the values of these
+options.
+
=head1 INTERNAL METHODS
These methods are not meant to be used by end users.
# instead the $app->handle method is called per request.
$app->log->warn("Not supplied a Plack engine, falling back to engine auto-loader (are your scripts ancient?)")
}
+ $app->run_options($options);
$server->run($psgi, $options);
}
return %args;
}
-sub _application_args {
- my ($self) = shift;
+around _application_args => sub {
+ my ($orig, $self) = @_;
return (
$self->listen,
{
+ %{ $self->$orig },
nproc => $self->nproc,
pidfile => $self->pidfile,
manager => $self->manager,
proc_title => $self->proc_title,
}
);
-}
+};
__PACKAGE__->meta->make_immutable;
1;
);
}
-sub _application_args {
- my ($self) = shift;
+around _application_args => sub {
+ my ($orig, $self) = @_;
return (
$self->port,
$self->host,
{
- argv => $self->ARGV,
+ %{ $self->$orig },
map { $_ => $self->$_ } qw/
fork
keepalive
pidfile
keepalive
follow_symlinks
+ port
+ host
/,
},
);
-}
+};
__PACKAGE__->meta->make_immutable;
1;
}
sub _application_args {
- ()
+ my $self = shift;
+ return {
+ argv => $self->ARGV,
+ extra_argv => $self->extra_argv,
+ }
}
sub _plack_loader_args {
return (port => $app_args[0]);
}
+sub _plack_engine_name {}
+
sub _run_application {
my $self = shift;
my $app = $self->application_name;
Class::MOP::load_class($app);
my $server;
- if (my $e = $self->can('_plack_engine_name') ) {
- $server = $self->load_engine($self->$e, $self->_plack_loader_args);
+ if (my $e = $self->_plack_engine_name ) {
+ $server = $self->load_engine($e, $self->_plack_loader_args);
}
else {
$server = $self->autoload_engine($self->_plack_loader_args);
shift @TestAppToTestScripts::RUN_ARGS;
my $server = pop @TestAppToTestScripts::RUN_ARGS;
like ref($server), qr/^Plack::Handler/, 'Is a Plack::Handler';
-is_deeply \@TestAppToTestScripts::RUN_ARGS, [], "no args";
+is ref(delete($TestAppToTestScripts::RUN_ARGS[0]->{argv})), 'ARRAY';
+is ref(delete($TestAppToTestScripts::RUN_ARGS[0]->{extra_argv})), 'ARRAY';
+is_deeply \@TestAppToTestScripts::RUN_ARGS, [{}], "no args";
done_testing;
} "new_with_options";
# First element of RUN_ARGS will be the script name, which we don't care about
shift @TestAppToTestScripts::RUN_ARGS;
+
my $server = pop @TestAppToTestScripts::RUN_ARGS;
is $server, $fake_handler, 'Loaded Plack handler gets passed to the app';
+
+ if (scalar(@TestAppToTestScripts::RUN_ARGS) && ref($TestAppToTestScripts::RUN_ARGS[-1]) eq "HASH") {
+ is ref(delete($TestAppToTestScripts::RUN_ARGS[-1]->{argv})), 'ARRAY';
+ is ref(delete($TestAppToTestScripts::RUN_ARGS[-1]->{extra_argv})), 'ARRAY';
+ }
+
is_deeply \@TestAppToTestScripts::RUN_ARGS, $resultarray, "is_deeply comparison";
}
--- /dev/null
+use strict;
+use warnings;
+use Test::More;
+use FindBin qw/$Bin/;
+use IO::Handle;
+use Try::Tiny;
+use File::Temp qw/ tempfile /;
+use lib "$Bin/../lib";
+
+use_ok('Catalyst::ScriptRunner');
+use_ok('ScriptTestApp');
+
+is ScriptTestApp->run_options, undef;
+
+my ($fh, $fn) = tempfile();
+
+binmode( $fh );
+binmode( STDOUT );
+
+local @ARGV = ();
+local %ENV;
+
+my $saved;
+open( $saved, '>&'. STDOUT->fileno )
+ or croak("Can't dup stdout: $!");
+open( STDOUT, '>&='. $fh->fileno )
+ or croak("Can't open stdout: $!");
+local $SIG{__WARN__} = sub {}; # Shut up warnings...
+try { Catalyst::ScriptRunner->run('ScriptTestApp', 'CGI'); pass("Ran ok") }
+catch { fail "Failed to run $_" };
+
+STDOUT->flush
+ or croak("Can't flush stdout: $!");
+
+open( STDOUT, '>&'. fileno($saved) )
+ or croak("Can't restore stdout: $!");
+
+is_deeply ScriptTestApp->run_options, { argv => [], extra_argv => [] };
+
+done_testing;
# help -? -help --help -? --help
# debug -d -debug --debug -d --debug
# host -host --host --host
-testOption( [ qw/--host testhost/ ], ['3000', 'testhost', opthash()] );
-testOption( [ qw/-h testhost/ ], ['3000', 'testhost', opthash()] );
+testOption( [ qw/--host testhost/ ], ['3000', 'testhost', opthash(host => 'testhost')] );
+testOption( [ qw/-h testhost/ ], ['3000', 'testhost', opthash(host => 'testhost')] );
# port -p -port --port -l --listen
-testOption( [ qw/-p 3001/ ], ['3001', undef, opthash()] );
-testOption( [ qw/--port 3001/ ], ['3001', undef, opthash()] );
+testOption( [ qw/-p 3001/ ], ['3001', undef, opthash(port => 3001)] );
+testOption( [ qw/--port 3001/ ], ['3001', undef, opthash(port => 3001)] );
{
local $ENV{TESTAPPTOTESTSCRIPTS_PORT} = 5000;
- testOption( [ qw// ], [5000, undef, opthash()] );
+ testOption( [ qw// ], [5000, undef, opthash(port => 5000)] );
}
{
local $ENV{CATALYST_PORT} = 5000;
- testOption( [ qw// ], [5000, undef, opthash()] );
+ testOption( [ qw// ], [5000, undef, opthash(port => 5000)] );
}
if (try { require Starman; 1; }) {
$run_args[-1]->{pidfile} = $run_args[-1]->{pidfile}->file->stringify
if scalar(@run_args) && $run_args[-1]->{pidfile};
-
# Mangle argv into the options..
$resultarray->[-1]->{argv} = $argstring;
+ $resultarray->[-1]->{extra_argv} = [];
is_deeply \@run_args, $resultarray, "is_deeply comparison " . join(' ', @$argstring);
}
'follow_symlinks' => 0,
'background' => 0,
'keepalive' => 0,
+ port => 3000,
+ host => undef,
@_,
};
}
--- /dev/null
+package ScriptTestApp;
+use Moose;
+
+extends 'Catalyst';
+
+__PACKAGE__->setup;
+1;
+
--- /dev/null
+package ScriptTestApp::Controller::Root;
+use Moose;
+use namespace::autoclean;
+
+BEGIN { extends 'Catalyst::Controller' }
+
+sub default : Chained('/') PathPart('') Args() {}
+
+1;
+