Merge 'trunk' into 'better_scripts'
Tomas Doran [Fri, 20 Nov 2009 01:09:14 +0000 (01:09 +0000)]
r11361@tomas-dorans-macbook-pro (orig r11331):  t0m | 2009-09-07 15:45:01 +0100
Fix hash key name back to what it used to be for compat, keeping renamed accessor where it was. Tests for this breakage to follow
r11363@tomas-dorans-macbook-pro (orig r11333):  t0m | 2009-09-07 21:19:40 +0100
Test for r11331 + fix to only report each action name once from get_action_methods
r11364@tomas-dorans-macbook-pro (orig r11334):  t0m | 2009-09-07 21:21:52 +0100
I'm an idiot, that totally doesn't work. remove.
r11365@tomas-dorans-macbook-pro (orig r11335):  t0m | 2009-09-07 21:25:53 +0100
AGH. Too tired to be doing this, fucked it up again
r11366@tomas-dorans-macbook-pro (orig r11336):  t0m | 2009-09-07 21:33:31 +0100
Fix duplicate results from get_action_methods. Q. Why didn't I just do that first time round? A: Am idiot.
r11369@tomas-dorans-macbook-pro (orig r11339):  marcus | 2009-09-09 18:05:32 +0100
un-TODO passing TODO tests
r11370@tomas-dorans-macbook-pro (orig r11340):  marcus | 2009-09-09 18:08:03 +0100
Prepare for release
r11374@tomas-dorans-macbook-pro (orig r11344):  groditi | 2009-09-09 22:06:59 +0100
add myself to contributors
r11375@tomas-dorans-macbook-pro (orig r11345):  t0m | 2009-09-10 01:13:56 +0100
Fix warnings in upcoming moose
r11377@tomas-dorans-macbook-pro (orig r11347):  t0m | 2009-09-10 02:14:13 +0100
 r11046@t0mlaptop (orig r11045):  yousef | 2009-08-07 00:07:07 +0100
 Moved action methods from t/lib/TestApp.pm to t/lib/Test/Controller/Root.pm. Uncommented the if statement in lib/Catalyst/Controller.pm that checks for actions in the appclass.

r11378@tomas-dorans-macbook-pro (orig r11348):  t0m | 2009-09-10 02:20:55 +0100
Eat the merge mark, svk hates me.
r11379@tomas-dorans-macbook-pro (orig r11349):  t0m | 2009-09-10 03:13:04 +0100
Blargh. Merge branch deprecate_appclass_actions manually, with svn merge http://dev.catalyst.perl.org/repos/Catalyst/Catalyst-Runtime/5.80/trunk http://dev.catalyst.perl.org/repos/Catalyst/Catalyst-Runtime/5.80/branches/deprecate_appclass_actions . after I forgot -l on svk push, but ctrl-C after the first rev meant svk had already committed a merge mark and re-merging did nothing, and removing it didn't do the right thing. Fail cake..
r11380@tomas-dorans-macbook-pro (orig r11350):  hobbs | 2009-09-10 08:20:31 +0100
Rework the C<< $c->go >> documentation a little, hopefully it's more clear.

r11382@tomas-dorans-macbook-pro (orig r11352):  autarch | 2009-09-11 03:48:29 +0100
Preserve immutable_options when temporarily making a class mutable

r11383@tomas-dorans-macbook-pro (orig r11353):  t0m | 2009-09-11 09:18:09 +0100
Work with old and new Moose
r11393@tomas-dorans-macbook-pro (orig r11363):  autarch | 2009-09-14 19:37:25 +0100
The warning about a class having mutable ancestors has been removed (and was never in a non-dev Moose release)

r11396@tomas-dorans-macbook-pro (orig r11366):  t0m | 2009-09-15 21:48:19 +0100
Remove what is now lies from Changes. Bump all the deps which need to be bumped to not crap warnings everywhere
r11399@tomas-dorans-macbook-pro (orig r11369):  t0m | 2009-09-16 18:14:29 +0100
Changelog
r11400@tomas-dorans-macbook-pro (orig r11370):  t0m | 2009-09-16 18:15:52 +0100
Now we depend on latest Moose we are certain to have immutable options
r11401@tomas-dorans-macbook-pro (orig r11371):  t0m | 2009-09-17 09:52:34 +0100
-short is dead, RT#49771
r11402@tomas-dorans-macbook-pro (orig r11372):  t0m | 2009-09-17 09:52:52 +0100
Add note about actions in appclass being deprecated
r11403@tomas-dorans-macbook-pro (orig r11373):  t0m | 2009-09-17 09:54:45 +0100
Add note about ::[MVC]:: warnings
r11404@tomas-dorans-macbook-pro (orig r11374):  t0m | 2009-09-17 09:58:15 +0100
Re-space current release changelog to align with the rest. Move -short changelog to the right place.
r11405@tomas-dorans-macbook-pro (orig r11375):  rafl | 2009-09-17 10:33:28 +0100
Version 5.80013.
r11407@tomas-dorans-macbook-pro (orig r11377):  t0m | 2009-09-17 14:32:16 +0100
Well, that got forgotten, oops
r11426@tomas-dorans-macbook-pro (orig r11396):  rafl | 2009-09-20 15:01:45 +0100
Fix a syntax error in the ContextClosure pod.
r11427@tomas-dorans-macbook-pro (orig r11397):  rafl | 2009-09-20 15:01:51 +0100
Use clean instead of autoclean in the ContextClosure synopsis until we've fixed the issues with that and MXMA.
r11428@tomas-dorans-macbook-pro (orig r11398):  gbjk | 2009-09-21 15:05:17 +0100
- Fix go / visit expecting captures and arguments in reverse order.

r11429@tomas-dorans-macbook-pro (orig r11399):  mateu | 2009-09-21 19:57:14 +0100
Update $c->forward and $c->state documentation to address scalar context.
r11430@tomas-dorans-macbook-pro (orig r11400):  t0m | 2009-09-23 15:48:06 +0100
Dep bump
r11452@tomas-dorans-macbook-pro (orig r11422):  t0m | 2009-09-25 13:03:50 +0100
Remove warnings for using Catalyst::Dispatcher->dispatch_types
r11459@tomas-dorans-macbook-pro (orig r11429):  t0m | 2009-09-27 13:27:41 +0100
Optional test not optional for authors
r11460@tomas-dorans-macbook-pro (orig r11430):  t0m | 2009-09-27 13:33:05 +0100
Make r11422 not break stuff - idiot :(
r11487@tomas-dorans-macbook-pro (orig r11457):  t0m | 2009-10-05 22:59:47 +0100
 r11483@t0mlaptop (orig r11453):  abraxxa | 2009-10-05 12:57:34 +0100
 Improved the suggested fix warning when component resolution uses regex fallback for fully qualified component names.
 Added disable_component_resolution_regex_fallback config option to switch off regex fallback for component resolution.

r11488@tomas-dorans-macbook-pro (orig r11458):  t0m | 2009-10-05 22:59:52 +0100
 r11486@t0mlaptop (orig r11456):  t0m | 2009-10-05 22:59:01 +0100
 Tidy up changelog/attribution

r11503@tomas-dorans-macbook-pro (orig r11468):  ilmari | 2009-10-06 16:30:41 +0100
Set ->request on the response object i Catalyst::Test::local_request--This line, and those below, will be ignored--

M    t/unit_load_catalyst_test.t
M    lib/Catalyst/Test.pm
M    Changes

r11519@tomas-dorans-macbook-pro (orig r11484):  phaylon | 2009-10-07 18:21:47 +0100
added stub config section (incl TODO) to Cat.pm for things like 'current_view'
r11548@tomas-dorans-macbook-pro (orig r11513):  caelum | 2009-10-12 17:18:22 +0100
fix uninitialized warning in ACL
r11549@tomas-dorans-macbook-pro (orig r11514):  caelum | 2009-10-12 17:22:08 +0100
better fix for uninitialized warning
r11550@tomas-dorans-macbook-pro (orig r11515):  t0m | 2009-10-12 18:10:32 +0100
Less cargo cult madness
r11554@tomas-dorans-macbook-pro (orig r11519):  caelum | 2009-10-13 15:37:02 +0100
more correct fix for uninitialized warning from ACL
r11556@tomas-dorans-macbook-pro (orig r11521):  dhoss | 2009-10-14 01:14:42 +0100
Snow Leopard uses COPYFILE_DISABLE
r11557@tomas-dorans-macbook-pro (orig r11522):  dhoss | 2009-10-14 01:20:06 +0100
fixed regex for next mac codename/version, will have to actually figure out what the 10.7 codename is when it arrives
r11558@tomas-dorans-macbook-pro (orig r11523):  dhoss | 2009-10-14 01:23:45 +0100
Attempted to make the error message more obvious
r11561@tomas-dorans-macbook-pro (orig r11526):  dhoss | 2009-10-14 01:50:26 +0100
fixed error message for mac osx 10.7
r11568@tomas-dorans-macbook-pro (orig r11533):  hobbs | 2009-10-15 03:32:28 +0100
Give people a pointer to chase if they're looking for info on $c->req->user

r11574@tomas-dorans-macbook-pro (orig r11539):  t0m | 2009-10-15 22:19:26 +0100
Add docs I promised for  r11484
r11622@tomas-dorans-macbook-pro (orig r11587):  jshirley | 2009-10-16 21:06:19 +0100
The longawaited nginx patch to support non-root apps, and some pod
r11623@tomas-dorans-macbook-pro (orig r11588):  jshirley | 2009-10-16 21:07:29 +0100
Changes for nginx patches
r11624@tomas-dorans-macbook-pro (orig r11589):  jshirley | 2009-10-16 21:08:55 +0100
My favorite color is clear and I like to eat rocks
r11670@tomas-dorans-macbook-pro (orig r11635):  t0m | 2009-10-19 18:02:59 +0100
Remove warnings from duplicate action declerations
r11675@tomas-dorans-macbook-pro (orig r11640):  poisonbit | 2009-10-20 21:12:46 +0100
Example added to #Actions_in_your_application_class

r11676@tomas-dorans-macbook-pro (orig r11641):  poisonbit | 2009-10-20 21:32:41 +0100
Formating (a lost space and line break)

r11677@tomas-dorans-macbook-pro (orig r11642):  poisonbit | 2009-10-20 21:34:45 +0100
More regresion from 11640, correcting parentheses and endpoint.

r11678@tomas-dorans-macbook-pro (orig r11643):  poisonbit | 2009-10-20 22:08:47 +0100
Change in actions inside roles.
http://bobtfish.livejournal.com/264317.html

r11679@tomas-dorans-macbook-pro (orig r11644):  poisonbit | 2009-10-20 23:16:03 +0100
Fixes to pass podchecker OK

r11714@tomas-dorans-macbook-pro (orig r11679):  rafl | 2009-10-28 23:54:56 +0000
Enable Catalyst::Utils::home() to find home within Dist::Zilla built dists.

Courtesy of nperez.
r11716@tomas-dorans-macbook-pro (orig r11681):  t0m | 2009-10-29 00:43:07 +0000
Make URI a link to make it super obvious
r11796@tomas-dorans-macbook-pro (orig r11761):  t0m | 2009-11-05 00:11:15 +0000
Need newer LWP for tests to pass as suggested on list by Jose Luis Martinez
r11811@tomas-dorans-macbook-pro (orig r11776):  altreus | 2009-11-06 17:09:51 +0000
Add doc for no-args call to ->uri_for
r11813@tomas-dorans-macbook-pro (orig r11778):  dhoss | 2009-11-06 17:13:27 +0000
fixed options passed to devel server so that author tests pass
r11814@tomas-dorans-macbook-pro (orig r11779):  altreus | 2009-11-06 17:14:49 +0000
Amend doc to not mention using undef in ->uri_for
r11816@tomas-dorans-macbook-pro (orig r11781):  t0m | 2009-11-07 16:50:59 +0000
Back out change from -port to -l - svn merge -r 11778:11777
r11823@tomas-dorans-macbook-pro (orig r11788):  rafl | 2009-11-09 22:21:19 +0000
Make request->body fail when used as a writer.
r11824@tomas-dorans-macbook-pro (orig r11789):  t0m | 2009-11-10 19:51:33 +0000
Fix changelog, me--
r11825@tomas-dorans-macbook-pro (orig r11790):  t0m | 2009-11-10 19:56:09 +0000
Warn on case_sensitive being set, remove documentation
r11827@tomas-dorans-macbook-pro (orig r11792):  t0m | 2009-11-10 21:36:06 +0000
Return 1, only currently works by chance
r11828@tomas-dorans-macbook-pro (orig r11793):  t0m | 2009-11-10 21:37:26 +0000
Also retarded
r11829@tomas-dorans-macbook-pro (orig r11794):  t0m | 2009-11-10 21:41:27 +0000
And lets not change behaviour with the log flush change..
r11836@tomas-dorans-macbook-pro (orig r11801):  t0m | 2009-11-12 01:12:05 +0000
Bring the changelog up to date.
r11839@tomas-dorans-macbook-pro (orig r11804):  t0m | 2009-11-12 01:44:46 +0000
 r11462@t0mlaptop (orig r11432):  rafl | 2009-09-27 16:06:26 +0100
 More aggregated tests.
 r11463@t0mlaptop (orig r11433):  rafl | 2009-09-27 16:06:36 +0100
 Fix a couple of aggregation warnings.
 r11464@t0mlaptop (orig r11434):  rafl | 2009-09-27 16:06:51 +0100
 More aggregation.
 r11465@t0mlaptop (orig r11435):  rafl | 2009-09-27 16:28:04 +0100
 Make things run again with aggregation disabled.
 r11838@t0mlaptop (orig r11803):  t0m | 2009-11-12 01:39:56 +0000
 Patch up changes to tests into new location. This merges parts of the following commits which were missed by svk:

 -r11456:11457 http://dev.catalyst.perl.org/repos/Catalyst/Catalyst-Runtime/5.80/trunk
 -r11467:11468 http://dev.catalyst.perl.org/repos/Catalyst/Catalyst-Runtime/5.80/trunk

r11841@tomas-dorans-macbook-pro (orig r11806):  bricas | 2009-11-12 17:58:02 +0000
remove duplicate changelog entry
r11847@tomas-dorans-macbook-pro (orig r11812):  t0m | 2009-11-12 23:57:15 +0000
 r11668@t0mlaptop (orig r11633):  t0m | 2009-10-19 17:53:27 +0100
 Branch for uri encoding things in uri_for in some way that means you can round trip path parts like '24/7', but without totally breaking backward compatibility this time hopefully.

 r11669@t0mlaptop (orig r11634):  t0m | 2009-10-19 17:54:08 +0100
 Well, this fixes my current issue, and doesn't seem to break any tests.. This likely means that the tests are still shit
 r11769@t0mlaptop (orig r11734):  t0m | 2009-11-04 19:17:33 +0000
 Needed for authors to run optional http test
 r11833@t0mlaptop (orig r11798):  t0m | 2009-11-12 00:22:06 +0000
 Tests, fix args as well as captureargs and be less violent - only encode /
 r11840@t0mlaptop (orig r11805):  rafl | 2009-11-12 16:08:57 +0000
 trailing whitespace
 r11843@t0mlaptop (orig r11808):  t0m | 2009-11-12 23:41:17 +0000
 Tidy up a bit
 r11845@t0mlaptop (orig r11810):  t0m | 2009-11-12 23:46:28 +0000
 Changelog
 r11846@t0mlaptop (orig r11811):  t0m | 2009-11-12 23:56:36 +0000
 Don't fail the live tests by only looking for http://localhost/etc..

r11858@tomas-dorans-macbook-pro (orig r11823):  t0m | 2009-11-14 17:26:04 +0000
Pod patch
r11860@tomas-dorans-macbook-pro (orig r11825):  t0m | 2009-11-14 17:30:26 +0000
Pod fixes re RT#51489
r11914@tomas-dorans-macbook-pro (orig r11879):  rafl | 2009-11-17 23:00:32 +0000
Merge branch 'exception_interface'

* exception_interface:
  Use MooseX::Role::WithOverloading.
  Add Exception::Interface and Exception::Basic. Make ::Base, ::Go and ::Detach use them.
  Create branch exception_interface
r11953@tomas-dorans-macbook-pro (orig r11918):  t0m | 2009-11-19 21:58:59 +0000
Add Pod for all the new exception classes
r11954@tomas-dorans-macbook-pro (orig r11919):  t0m | 2009-11-19 22:00:27 +0000
Rename http server test as it is not optional for authors

22 files changed:
Makefile.PL
TODO.scripts [new file with mode: 0644]
lib/Catalyst.pm
lib/Catalyst/ROADMAP.pod
lib/Catalyst/Script/CGI.pm [new file with mode: 0644]
lib/Catalyst/Script/Create.pm [new file with mode: 0644]
lib/Catalyst/Script/FastCGI.pm [new file with mode: 0644]
lib/Catalyst/Script/Server.pm [new file with mode: 0644]
lib/Catalyst/Script/Test.pm [new file with mode: 0644]
lib/Catalyst/ScriptRole.pm [new file with mode: 0644]
lib/Catalyst/ScriptRunner.pm [new file with mode: 0644]
t/aggregate/unit_core_script_cgi.t [new file with mode: 0644]
t/aggregate/unit_core_script_fastcgi.t [new file with mode: 0644]
t/aggregate/unit_core_script_help.t [new file with mode: 0644]
t/aggregate/unit_core_script_server.t [new file with mode: 0644]
t/aggregate/unit_core_script_test.t [new file with mode: 0644]
t/aggregate/unit_core_scriptrunner.t [new file with mode: 0644]
t/lib/Catalyst/Script/Bar.pm [new file with mode: 0644]
t/lib/Catalyst/Script/Baz.pm [new file with mode: 0644]
t/lib/ScriptTestApp/Script/Bar.pm [new file with mode: 0644]
t/lib/ScriptTestApp/Script/Foo.pm [new file with mode: 0644]
t/lib/TestAppToTestScripts.pm [new file with mode: 0644]

index fe7a723..b98a180 100644 (file)
@@ -18,6 +18,7 @@ all_from 'lib/Catalyst/Runtime.pm';
 requires 'List::MoreUtils';
 requires 'namespace::autoclean' => '0.09';
 requires 'namespace::clean';
+requires 'namespace::autoclean';
 requires 'B::Hooks::EndOfScope' => '0.08';
 requires 'MooseX::Emulate::Class::Accessor::Fast' => '0.00903';
 requires 'Class::MOP' => '0.83';
@@ -47,10 +48,10 @@ requires 'URI' => '1.35';
 requires 'Task::Weaken';
 requires 'Text::Balanced'; # core in 5.8.x but mentioned for completeness
 requires 'MRO::Compat';
+requires 'MooseX::Getopt';
+requires 'MooseX::Types';
 requires 'String::RewritePrefix' => '0.004'; # Catalyst::Utils::resolve_namespace
 
-recommends 'B::Hooks::OP::Check::StashChange';
-
 test_requires 'Class::Data::Inheritable';
 test_requires 'Test::Exception';
 test_requires 'Test::More' => '0.88';
diff --git a/TODO.scripts b/TODO.scripts
new file mode 100644 (file)
index 0000000..1096520
--- /dev/null
@@ -0,0 +1,5 @@
+* $ARGV[0] has slipped to $ARGV[1] in ::Test
+* ScriptRunner tests for MyApp::Script::DoesNotCompile
+* Sort out help so that it shows what you fucked up.
+* Fix horrible hacking around MX::Getopt's help display - probably by fixing MX::Getopt.
+* Tests for ::Create
index 6e74e58..5d8de24 100644 (file)
@@ -2892,6 +2892,8 @@ David Naughton, C<naughton@umn.edu>
 
 David E. Wheeler
 
+dhoss: Devin Austin <dhoss@cpan.org>
+
 dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
 
 Drew Taylor
index e872e5e..9c29d1d 100644 (file)
@@ -8,11 +8,6 @@ in the the catalyst trunk, currently at
 
 Make sure you get it from there to ensure you have the latest version.
 
-=head2 5.80000 1st Quarter 2009
-
-Next major planned release, ports Catalyst to Moose, and does some refactoring
-to help app/ctx.
-
 =head2 5.81000 
 
 =over
diff --git a/lib/Catalyst/Script/CGI.pm b/lib/Catalyst/Script/CGI.pm
new file mode 100644 (file)
index 0000000..c37dfdc
--- /dev/null
@@ -0,0 +1,31 @@
+package Catalyst::Script::CGI;
+use Moose;
+BEGIN { $ENV{CATALYST_ENGINE} ||= 'CGI' }
+use namespace::autoclean;
+
+with 'Catalyst::ScriptRole';
+
+__PACKAGE__->meta->make_immutable;
+
+=head1 NAME
+
+Catalyst::Script::CGI - The CGI Catalyst Script
+
+=head1 SYNOPSIS
+
+See L<Catalyst>.
+
+=head1 DESCRIPTION
+
+This is a script to run the Catalyst engine specialized for the CGI environment.
+
+=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
diff --git a/lib/Catalyst/Script/Create.pm b/lib/Catalyst/Script/Create.pm
new file mode 100644 (file)
index 0000000..6191d72
--- /dev/null
@@ -0,0 +1,94 @@
+package Catalyst::Script::Create;
+use Moose;
+use Catalyst::Helper;
+use MooseX::Types::Moose qw/Bool/;
+use namespace::autoclean;
+
+with 'Catalyst::ScriptRole';
+
+has force => (
+    traits => [qw(Getopt)],
+    cmd_aliases => 'nonew',
+    isa => Bool,
+    is => 'ro',
+    documentation => 'Force new scripts',
+);
+
+has debug => (
+    traits => [qw(Getopt)],
+    cmd_aliases => 'd',
+    isa => Bool,
+    is => 'ro',
+    documentation => 'Force debug mode',
+);
+
+has mechanize => (
+    traits => [qw(Getopt)],
+    cmd_aliases => 'mech',
+    isa => Bool,
+    is => 'ro',
+    documentation => 'use WWW::Mechanize',
+);
+
+sub run {
+    my ($self) = @_;
+
+    $self->_exit_with_usage if !$ARGV[0];
+
+    my $helper = Catalyst::Helper->new( { '.newfiles' => !$self->force, mech => $self->mech } );
+
+    $self->_display_help unless $helper->mk_component( $self->app, @ARGV );
+
+}
+
+__PACKAGE__->meta->make_immutable;
+
+=head1 NAME
+
+Catalyst::Script::Create - Create a new Catalyst Component
+
+=head1 SYNOPSIS
+
+ myapp_create.pl [options] model|view|controller name [helper] [options]
+
+ Options:
+   -force        don't create a .new file where a file to be created exists
+   -mechanize    use Test::WWW::Mechanize::Catalyst for tests if available
+   -help         display this help and exits
+
+ Examples:
+   myapp_create.pl controller My::Controller
+   myapp_create.pl controller My::Controller BindLex
+   myapp_create.pl -mechanize controller My::Controller
+   myapp_create.pl view My::View
+   myapp_create.pl view MyView TT
+   myapp_create.pl view TT TT
+   myapp_create.pl model My::Model
+   myapp_create.pl model SomeDB DBIC::Schema MyApp::Schema create=dynamic\
+   dbi:SQLite:/tmp/my.db
+   myapp_create.pl model AnotherDB DBIC::Schema MyApp::Schema create=static\
+   dbi:Pg:dbname=foo root 4321
+
+ See also:
+   perldoc Catalyst::Manual
+   perldoc Catalyst::Manual::Intro
+
+=head1 DESCRIPTION
+
+Create a new Catalyst Component.
+
+Existing component files are not overwritten.  If any of the component files
+to be created already exist the file will be written with a '.new' suffix.
+This behavior can be suppressed with the C<-force> option.
+
+=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
+
diff --git a/lib/Catalyst/Script/FastCGI.pm b/lib/Catalyst/Script/FastCGI.pm
new file mode 100644 (file)
index 0000000..d76727d
--- /dev/null
@@ -0,0 +1,121 @@
+package Catalyst::Script::FastCGI;
+
+BEGIN { $ENV{CATALYST_ENGINE} ||= 'FastCGI' }
+use Moose;
+use MooseX::Types::Moose qw/Str Bool Int/;
+use namespace::autoclean;
+
+with 'Catalyst::ScriptRole';
+
+has listen => (
+    traits => [qw(Getopt)],
+    cmd_aliases => 'l',
+    isa => Str,
+    is => 'ro',
+    documentation => 'Specify a listening port/socket',
+);
+
+has pidfile => (
+    traits => [qw(Getopt)],
+    cmd_aliases => 'pid',
+    isa => Str,
+    is => 'ro',
+    documentation => 'Specify a pidfile',
+);
+
+has daemon => (
+    traits => [qw(Getopt)],
+    isa => Bool,   
+    is => 'ro', 
+    cmd_aliases => 'd', 
+    documentation => 'Daemonize (go into the background)',
+);
+
+has manager => (
+    traits => [qw(Getopt)],
+    isa => Str,    
+    is => 'ro',
+    cmd_aliases => 'M',
+    documentation => 'Use a different FastCGI process manager class',
+);
+
+has keeperr => (
+    traits => [qw(Getopt)],
+    cmd_aliases => 'e', 
+    isa => Bool,   
+    is => 'ro',  
+    documentation => 'Log STDERR',
+);
+
+has nproc => (
+    traits => [qw(Getopt)],
+    cmd_aliases => 'n',  
+    isa => Int,
+    is => 'ro',  
+    documentation => 'Specify a number of child processes',
+);
+
+has detach => (
+    traits => [qw(Getopt)],
+    cmd_aliases => 'det', 
+    isa => Bool,   
+    is => 'ro',  
+    documentation => 'Detach this FastCGI process',
+);
+
+sub _application_args {
+    my ($self) = shift;
+    return (
+        $self->listen,
+        {
+            nproc   => $self->nproc,
+            pidfile => $self->pidfile,
+            manager => $self->manager,
+            detach  => $self->detach,
+            keep_stderr => $self->keeperr,
+        }
+    );
+}
+
+__PACKAGE__->meta->make_immutable;
+
+=head1 NAME
+
+Catalyst::Script::FastCGI - The FastCGI Catalyst Script
+
+=head1 SYNOPSIS
+
+  myapp_fastcgi.pl [options]
+
+ Options:
+   -? -help      display this help and exits
+   -l -listen    Socket path to listen on
+                 (defaults to standard input)
+                 can be HOST:PORT, :PORT or a
+                 filesystem path
+   -n -nproc     specify number of processes to keep
+                 to serve requests (defaults to 1,
+                 requires -listen)
+   -p -pidfile   specify filename for pid file
+                 (requires -listen)
+   -d -daemon    daemonize (requires -listen)
+   -M -manager   specify alternate process manager
+                 (FCGI::ProcManager sub-class)
+                 or empty string to disable
+   -e -keeperr   send error messages to STDOUT, not
+                 to the webserver
+
+=head1 DESCRIPTION
+
+Run a Catalyst application as fastcgi.
+
+=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
diff --git a/lib/Catalyst/Script/Server.pm b/lib/Catalyst/Script/Server.pm
new file mode 100644 (file)
index 0000000..ef1f818
--- /dev/null
@@ -0,0 +1,237 @@
+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 namespace::autoclean;
+
+with 'Catalyst::ScriptRole';
+
+has debug => (
+    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',
+);
+
+has fork => (
+    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,
+    documentation => 'Specify a different listening port (to the default port 3000)',
+);
+
+has pidfile => (
+    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,
+    documentation => 'Support keepalive',
+);
+
+has background => (
+    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,
+    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',
+    documentation => 'Restarter directory to watch',
+    predicate => '_has_restart_directory',
+);
+
+has restart_delay => (
+    traits => [qw(Getopt)],
+    cmd_aliases => 'rd',
+    isa => Int,
+    is => 'ro',
+    documentation => 'Set a 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',
+);
+
+has follow_symlinks => (
+    traits => [qw(Getopt)],
+    cmd_aliases => 'sym',
+    isa => Bool,
+    is => 'ro',
+    default => 0,
+    documentation => 'Follow symbolic links',
+);
+
+sub run {
+    my ($self) = shift;
+
+    local $ENV{CATALYST_DEBUG} = 1
+        if $self->debug;
+
+    if ( $self->restart ) {
+        die "Cannot run in the background and also watch for changed files.\n"
+            if $self->background;
+
+        # If we load this here, then in the case of a restarter, it does not
+        # need to be reloaded for each restart.
+        require Catalyst;
+
+        # If this isn't done, then the Catalyst::Devel tests for the restarter
+        # fail.
+        $| = 1 if $ENV{HARNESS_ACTIVE};
+
+        require Catalyst::Restarter;
+
+        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,
+        );
+
+        $restarter->run_and_watch;
+    }
+    else {
+        $self->_run_application;
+    }
+
+
+}
+
+sub _application_args {
+    my ($self) = shift;
+    return (
+        $self->port,
+        $self->host,
+        {
+           map { $_ => $self->$_ } qw/
+                fork
+                keepalive
+                background
+                pidfile
+                keepalive
+                follow_symlinks
+            /,
+        },
+    );
+}
+
+__PACKAGE__->meta->make_immutable;
+
+1;
+
+=head1 NAME
+
+Catalyst::Script::Server - Catalyst test server
+
+=head1 SYNOPSIS
+
+ myapp_server.pl [options]
+
+ Options:
+   -d     --debug          force debug mode
+   -f     --fork           handle each request in a new process
+                      (defaults to false)
+   -h     --help           display this help and exits
+          --host           host (defaults to all)
+   -p     --port           port (defaults to 3000)
+   -k     --keepalive      enable keep-alive connections
+   -r     --restart        restart when files get modified
+                       (defaults to false)
+   --rd   --restartdelay  delay between file checks
+                      (ignored if you have Linux::Inotify2 installed)
+   --rr   --restartregex  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
+                      (defaults to '[SCRIPT_DIR]/..')
+   --sym  --follow_symlinks   follow symlinks in search directories
+                      (defaults to false. this is a no-op on Win32)
+   --bg   --background        run the process in the background
+   --pid  --pidfile           specify filename for pid file
+
+ See also:
+   perldoc Catalyst::Manual
+   perldoc Catalyst::Manual::Intro
+
+=head1 DESCRIPTION
+
+Run a Catalyst test server for this application.
+
+=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
diff --git a/lib/Catalyst/Script/Test.pm b/lib/Catalyst/Script/Test.pm
new file mode 100644 (file)
index 0000000..7d5e978
--- /dev/null
@@ -0,0 +1,41 @@
+package Catalyst::Script::Test;
+use Moose;
+use namespace::autoclean;
+
+with 'Catalyst::ScriptRole';
+
+sub run {
+    my $self = shift;
+
+    Class::MOP::load_class("Catalyst::Test");
+    Catalyst::Test->import($self->application_name);
+
+    print request($ARGV[1])->content  . "\n";
+
+}
+
+
+__PACKAGE__->meta->make_immutable;
+
+=head1 NAME
+
+Catalyst::Script::Test - Test Catalyst application on the command line
+
+=head1 SYNOPSIS
+
+See L<Catalyst>.
+
+=head1 DESCRIPTION
+
+FIXME
+
+=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
diff --git a/lib/Catalyst/ScriptRole.pm b/lib/Catalyst/ScriptRole.pm
new file mode 100644 (file)
index 0000000..bea26de
--- /dev/null
@@ -0,0 +1,118 @@
+package Catalyst::ScriptRole;
+use Moose::Role;
+use MooseX::Types::Moose qw/Str Bool/;
+use Pod::Usage;
+use namespace::autoclean;
+
+with 'MooseX::Getopt';
+
+has application_name => (
+    traits => ['NoGetopt'],
+    isa => Str,
+    is => 'ro',
+    required => 1,
+);
+
+has help => (
+    traits => ['Getopt'],
+    cmd_aliases => 'h',
+    isa => Bool,
+    is => 'ro',
+    documentation => q{Display this help and exit},
+);
+
+sub _exit_with_usage {
+    my $self = shift;
+    pod2usage();
+    exit 0;
+}
+
+before run => sub {
+    my $self = shift;
+    $self->_exit_with_usage if $self->help;
+};
+
+sub run {
+    my $self = shift;
+    $self->_run_application;
+}
+
+sub _application_args {
+    ()
+}
+
+sub _run_application {
+    my $self = shift;
+    my $app = $self->application_name;
+    Class::MOP::load_class($app);
+    $app->run($self->_application_args);
+}
+
+# GROSS HACK, temporary until MX::Getopt gets some proper refactoring and unfucking..
+around '_parse_argv' => sub {
+    my ($orig, $self, @args) = @_;
+    my %data = eval { $self->$orig(@args) };
+    $self->_exit_with_usage($@) if $@;
+    $data{usage} = Catalyst::ScriptRole::Useage->new(code => sub { shift; $self->_exit_with_usage(@_) });
+    return %data;
+};
+
+# This package is going away.
+package # Hide from PAUSE
+    Catalyst::ScriptRole::Useage;
+use Moose;
+use namespace::autoclean;
+
+has code => ( is => 'ro', required => 1 );
+
+sub die { shift->code->(@_) }
+
+1;
+
+=head1 NAME
+
+Catalyst::ScriptRole - Common functionality for Catalyst scripts.
+
+=head1 SYNOPSIS
+
+    package MyApp::Script::Foo;
+    use Moose;
+    use namespace::autoclean;
+    
+    with 'Catalyst::Script::Role';
+    
+     sub _application_args { ... }
+    
+=head1 DESCRIPTION
+
+Role with the common functionality of Catalyst scripts.
+
+=head1 METHODS
+
+=head2 run
+
+The method invoked to run the application.
+
+=head1 ATTRIBUTES
+
+=head2 application_name
+
+The name of the application class, e.g. MyApp
+
+=head1 SEE ALSO
+
+L<Catalyst>
+
+L<MooseX::Getopt>
+
+=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
+    
diff --git a/lib/Catalyst/ScriptRunner.pm b/lib/Catalyst/ScriptRunner.pm
new file mode 100644 (file)
index 0000000..63d153d
--- /dev/null
@@ -0,0 +1,57 @@
+package Catalyst::ScriptRunner;
+use Moose;
+use FindBin;
+use lib;
+use File::Spec;
+use namespace::autoclean;
+
+sub run {
+    my ($self, $class, $scriptclass) = @_;
+    my $classtoload = "${class}::Script::$scriptclass";
+
+    lib->import(File::Spec->catdir($FindBin::Bin, '..', 'lib'));
+
+    # FIXME - Error handling / reporting
+    if ( eval { Class::MOP::load_class($classtoload) } ) {
+    }
+    else {
+        $classtoload = "Catalyst::Script::$scriptclass";
+        Class::MOP::load_class($classtoload);
+    }
+    $classtoload->new_with_options( application_name => $class )->run;
+}
+
+__PACKAGE__->meta->make_immutable;
+
+=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 running scripts, either in the application specific namespace
+(e.g. C<MyApp::Script::Server>), or the Catalyst namespace (e.g. C<Catalyst::Script::Server>)
+
+=head1 METHODS
+
+=head2 run ($application_class, $scriptclass)
+
+Called with two parameters, the application classs (e.g. MyApp)
+and the script class, (i.e. one of Server/FastCGI/CGI/Create/Test)
+
+=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
diff --git a/t/aggregate/unit_core_script_cgi.t b/t/aggregate/unit_core_script_cgi.t
new file mode 100644 (file)
index 0000000..ba187e1
--- /dev/null
@@ -0,0 +1,20 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+
+use FindBin qw/$Bin/;
+use lib "$Bin/../lib";
+
+use Test::More;
+use Test::Exception;
+
+use Catalyst::Script::CGI;
+
+local @ARGV;
+lives_ok {
+    Catalyst::Script::CGI->new_with_options(application_name => 'TestAppToTestScripts')->run;
+} "new_with_options";
+shift @TestAppToTestScripts::RUN_ARGS;
+is_deeply \@TestAppToTestScripts::RUN_ARGS, [], "no args";
+
+done_testing;
diff --git a/t/aggregate/unit_core_script_fastcgi.t b/t/aggregate/unit_core_script_fastcgi.t
new file mode 100644 (file)
index 0000000..7d4da0f
--- /dev/null
@@ -0,0 +1,70 @@
+use strict;
+use warnings;
+
+use FindBin qw/$Bin/;
+use lib "$Bin/../lib";
+
+use Test::More;
+use Test::Exception;
+
+use Catalyst::Script::FastCGI;
+
+my $testopts;
+
+# Test default (no opts/args behaviour)
+testOption( [ qw// ], [undef, opthash()] );
+
+# listen socket
+testOption( [ qw|-l /tmp/foo| ], ['/tmp/foo', opthash()] );
+testOption( [ qw/-l 127.0.0.1:3000/ ], ['127.0.0.1:3000', opthash()] );
+
+#daemonize           -d --daemon
+testOption( [ qw/-d/ ], [undef, opthash()] );
+testOption( [ qw/--daemon/ ], [undef, opthash()] );
+
+# pidfile        -pidfile                  --pid --pidfile
+testOption( [ qw/--pidfile cat.pid/ ], [undef, opthash(pidfile => 'cat.pid')] );
+testOption( [ qw/--pid cat.pid/ ], [undef, opthash(pidfile => 'cat.pid')] );
+
+# manager
+testOption( [ qw/--manager foo::bar/ ], [undef, opthash(manager => 'foo::bar')] );
+testOption( [ qw/-M foo::bar/ ], [undef, opthash(manager => 'foo::bar')] );
+
+# keeperr
+testOption( [ qw/--keeperr/ ], [undef, opthash(keep_stderr => 1)] );
+testOption( [ qw/-e/ ], [undef, opthash(keep_stderr => 1)] );
+
+# nproc
+testOption( [ qw/--nproc 6/ ], [undef, opthash(nproc => 6)] );
+testOption( [ qw/--n 6/ ], [undef, opthash(nproc => 6)] );
+
+# detach
+testOption( [ qw/--detach/ ], [undef, opthash(detach => 1)] );
+testOption( [ qw/--det/ ], [undef, opthash(detach => 1)] );
+
+done_testing;
+
+sub testOption {
+    my ($argstring, $resultarray) = @_;
+
+    local @ARGV = @$argstring;
+    local @TestAppToTestScripts::RUN_ARGS;
+    lives_ok {
+        Catalyst::Script::FastCGI->new_with_options(application_name => 'TestAppToTestScripts')->run;
+    } "new_with_options";
+    # First element of RUN_ARGS will be the script name, which we don't care about
+    shift @TestAppToTestScripts::RUN_ARGS;
+    is_deeply \@TestAppToTestScripts::RUN_ARGS, $resultarray, "is_deeply comparison";
+}
+
+# Returns the hash expected when no flags are passed
+sub opthash {
+    return {
+        pidfile => undef,
+        keep_stderr => undef,
+        detach => undef,
+        nproc => undef,
+        manager => undef,
+        @_,
+    };
+}
diff --git a/t/aggregate/unit_core_script_help.t b/t/aggregate/unit_core_script_help.t
new file mode 100644 (file)
index 0000000..26a3a92
--- /dev/null
@@ -0,0 +1,35 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+use Test::More;
+use Test::Exception;
+
+use FindBin qw/$Bin/;
+use lib "$Bin/../lib";
+
+{
+    package TestHelpScript;
+    use Moose;
+    with 'Catalyst::ScriptRole';
+    our $help;
+    sub _exit_with_usage { $help++ }
+}
+
+test('-h');
+test('--help');
+
+TODO: {
+    local $TODO = 'This is bork';
+    test('-?');
+}
+
+sub test {
+    local $TestHelpScript::help;
+    local @ARGV = (@_);
+    lives_ok {
+        TestHelpScript->new_with_options(application_name => 'TestAppToTestScripts')->run;
+    };
+    ok $TestHelpScript::help;
+}
+
+done_testing;
diff --git a/t/aggregate/unit_core_script_server.t b/t/aggregate/unit_core_script_server.t
new file mode 100644 (file)
index 0000000..e129f19
--- /dev/null
@@ -0,0 +1,80 @@
+use strict;
+use warnings;
+
+use FindBin qw/$Bin/;
+use lib "$Bin/../lib";
+
+use Test::More;
+use Test::Exception;
+
+use Catalyst::Script::Server;
+
+my $testopts;
+
+# Test default (no opts/args behaviour)
+testOption( [ qw// ], ['3000', 'localhost', opthash()] );
+
+# Old version supports long format opts with either one or two dashes.  New version only supports two.
+#                Old                       New
+# 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()] );
+
+# port           -p -port --port           -l --listen
+testOption( [ qw/-p 3001/ ], ['3001', 'localhost', opthash()] );
+testOption( [ qw/--port 3001/ ], ['3001', 'localhost', opthash()] );
+
+# fork           -f -fork --fork           -f --fork
+testOption( [ qw/--fork/ ], ['3000', 'localhost', opthash(fork => 1)] );
+testOption( [ qw/-f/ ], ['3000', 'localhost', opthash(fork => 1)] );
+
+# pidfile        -pidfile                  --pid --pidfile
+testOption( [ qw/--pidfile cat.pid/ ], ['3000', 'localhost', opthash(pidfile => "cat.pid")] );
+testOption( [ qw/--pid cat.pid/ ], ['3000', 'localhost', opthash(pidfile => "cat.pid")] );
+
+# keepalive      -k -keepalive --keepalive -k --keepalive
+testOption( [ qw/-k/ ], ['3000', 'localhost', opthash(keepalive => 1)] );
+testOption( [ qw/--keepalive/ ], ['3000', 'localhost', opthash(keepalive => 1)] );
+
+# symlinks       -follow_symlinks          --sym --follow_symlinks
+testOption( [ qw/--follow_symlinks/ ], ['3000', 'localhost', opthash(follow_symlinks => 1)] );
+testOption( [ qw/--sym/ ], ['3000', 'localhost', opthash(follow_symlinks => 1)] );
+
+# background     -background               --bg --background
+testOption( [ qw/--background/ ], ['3000', 'localhost', opthash(background => 1)] );
+testOption( [ qw/--bg/ ], ['3000', 'localhost', opthash(background => 1)] );
+
+# Restart stuff requires a threaded perl, apparently.
+# restart        -r -restart --restart     -R --restart
+# restart dly    -rd -restartdelay         --rdel --restart_delay
+# restart dir    -restartdirectory         --rdir --restart_directory
+# restart regex  -rr -restartregex         --rxp --restart_regex
+
+done_testing;
+
+sub testOption {
+    my ($argstring, $resultarray) = @_;
+
+    local @ARGV = @$argstring;
+    local @TestAppToTestScripts::RUN_ARGS;
+    lives_ok {
+        Catalyst::Script::Server->new_with_options(application_name => 'TestAppToTestScripts')->run;
+    } "new_with_options";
+    # First element of RUN_ARGS will be the script name, which we don't care about
+    shift @TestAppToTestScripts::RUN_ARGS;
+    is_deeply \@TestAppToTestScripts::RUN_ARGS, $resultarray, "is_deeply comparison";
+}
+
+# Returns the hash expected when no flags are passed
+sub opthash {
+    return {
+        'pidfile' => undef,
+        'fork' => 0,
+        'follow_symlinks' => 0,
+        'background' => 0,
+        'keepalive' => 0,
+        @_,
+    };
+}
diff --git a/t/aggregate/unit_core_script_test.t b/t/aggregate/unit_core_script_test.t
new file mode 100644 (file)
index 0000000..cc91a3a
--- /dev/null
@@ -0,0 +1,48 @@
+use strict;
+use warnings;
+
+use FindBin qw/$Bin/;
+use lib "$Bin/../lib";
+
+use Test::More;
+use Test::Exception;
+
+use Catalyst::Script::Test;
+use File::Temp qw/tempfile/;
+use IO::Handle;
+
+my ($fh, $fn) = tempfile();
+
+binmode( $fh );
+binmode( STDOUT );
+
+{
+    local @ARGV = ('/');
+    my $i;
+    lives_ok {
+        $i = Catalyst::Script::Test->new_with_options(application_name => 'TestApp');
+    } "new_with_options";
+    ok $i;
+    my $saved;
+    open( $saved, '<&'. STDIN->fileno )
+          or croak("Can't dup stdin: $!");
+    open( STDOUT, '>&='. $fh->fileno )
+        or croak("Can't open stdout: $!");
+    eval { $i->run };
+    ok !$@, 'Ran ok';
+
+    STDOUT->flush
+        or croak("Can't flush stdout: $!");
+
+    open( STDOUT, '>&'. fileno($saved) )
+        or croak("Can't restore stdout: $!");
+}
+
+my $data = do { my $fh; open($fh, '<', $fn) or die $!; local $/; <$fh>; };
+$fh = undef;
+unlink $fn if -r $fn;
+
+is $data, "root index\n", 'correct content printed';
+
+done_testing;
+
diff --git a/t/aggregate/unit_core_scriptrunner.t b/t/aggregate/unit_core_scriptrunner.t
new file mode 100644 (file)
index 0000000..1dfe255
--- /dev/null
@@ -0,0 +1,16 @@
+use strict;
+use warnings;
+use Test::More tests => 5;
+use FindBin qw/$Bin/;
+use lib "$Bin/../lib";
+
+use_ok('Catalyst::ScriptRunner');
+
+is Catalyst::ScriptRunner->run('ScriptTestApp', 'Foo'), 'ScriptTestApp::Script::Foo',
+    'Script existing only in app';
+is Catalyst::ScriptRunner->run('ScriptTestApp', 'Bar'), 'ScriptTestApp::Script::Bar',
+    'Script existing in both app and Catalyst - prefers app';
+is Catalyst::ScriptRunner->run('ScriptTestApp', 'Baz'), 'Catalyst::Script::Baz',
+    'Script existing only in Catalyst';
+# +1 test for the params passed to new_with_options in t/lib/Catalyst/Script/Baz.pm
+
diff --git a/t/lib/Catalyst/Script/Bar.pm b/t/lib/Catalyst/Script/Bar.pm
new file mode 100644 (file)
index 0000000..18e699c
--- /dev/null
@@ -0,0 +1,9 @@
+package Catalyst::Script::Bar;
+use Moose;
+use namespace::autoclean;
+
+with 'Catalyst::ScriptRole';
+
+sub run { __PACKAGE__ }
+
+1;
diff --git a/t/lib/Catalyst/Script/Baz.pm b/t/lib/Catalyst/Script/Baz.pm
new file mode 100644 (file)
index 0000000..d699fe6
--- /dev/null
@@ -0,0 +1,16 @@
+package Catalyst::Script::Baz;
+use Moose;
+use namespace::autoclean;
+
+use Test::More;
+
+with 'Catalyst::ScriptRole';
+
+sub run { __PACKAGE__ }
+
+after new_with_options => sub {
+    my ($self, %args) = @_;
+    is_deeply \%args, { application_name => 'ScriptTestApp' }, 'App name correct';
+};
+
+1;
diff --git a/t/lib/ScriptTestApp/Script/Bar.pm b/t/lib/ScriptTestApp/Script/Bar.pm
new file mode 100644 (file)
index 0000000..1d01fad
--- /dev/null
@@ -0,0 +1,9 @@
+package ScriptTestApp::Script::Bar;
+use Moose;
+use namespace::autoclean;
+
+with 'Catalyst::ScriptRole';
+
+sub run { __PACKAGE__ }
+
+1;
\ No newline at end of file
diff --git a/t/lib/ScriptTestApp/Script/Foo.pm b/t/lib/ScriptTestApp/Script/Foo.pm
new file mode 100644 (file)
index 0000000..8d61c63
--- /dev/null
@@ -0,0 +1,9 @@
+package ScriptTestApp::Script::Foo;
+use Moose;
+use namespace::autoclean;
+
+with 'Catalyst::ScriptRole';
+
+sub run { __PACKAGE__ }
+
+1;
diff --git a/t/lib/TestAppToTestScripts.pm b/t/lib/TestAppToTestScripts.pm
new file mode 100644 (file)
index 0000000..f32154a
--- /dev/null
@@ -0,0 +1,14 @@
+package TestAppToTestScripts;
+use strict;
+use warnings;
+use Carp;
+
+our @RUN_ARGS;
+
+sub run {
+    @RUN_ARGS = @_;
+    1; # Does this work?
+}
+
+1;
+