Catalyst-Plugin-Static-Simple-0.33/000755 000766 000024 00000000000 12424207252 017235 5ustar00johnstaff000000 000000 Catalyst-Plugin-Static-Simple-0.33/.travis.yml000644 000766 000024 00000002165 12424201643 021350 0ustar00johnstaff000000 000000 language: perl perl: - "5.20" - "5.18" - "5.16" - "5.14" - "5.12" - "5.10" - "5.8" install: # Based on Catalyst travis cfg: # M::I deps - cpanm --notest --metacpan --skip-satisfied Module::Install Module::Install::AuthorRequires Module::Install::CheckConflicts Module::Install::AuthorTests Module::Install::Authority # author deps -- wish there was a better way - cpanm --notest --metacpan --skip-satisfied CatalystX::LeakChecker Catalyst::Devel Catalyst::Engine::PSGI Starman MooseX::Daemonize Test::WWW::Mechanize::Catalyst Catalyst::Plugin::Params::Nested - cpanm --notest --metacpan --skip-satisfied Test::Without::Module Test::NoTabs Test::Pod Test::Pod::Coverage Test::Spelling Pod::Coverage::TrustPod - cpanm --notest --metacpan --skip-satisfied --installdeps . - echo y | perl Makefile.PL # enable various test options, including parallel testing - export AUTOMATED_TESTING=1 HARNESS_OPTIONS=j10:c HARNESS_TIMER=1 # we want these for our tests, but not for any others - export AUTHOR_TESTING=1 - export RELEASE_TESTING=1 - make manifest script: - make disttest Catalyst-Plugin-Static-Simple-0.33/Changes000755 000766 000024 00000017002 12424206520 020530 0ustar00johnstaff000000 000000 Revision history for Perl extension Catalyst::Plugin::Static::Simple 0.33 2014-09-26 17:00 BST - In the case where someone is trying to merge configurations and some config sets use the depracated 'static' keyword, the configs will be properly merged. 0.32 2014-06-04 17:00 EDT - Sets 'autoflush' in the Catalyst Log object to false if available. This is a new API being added in Catalyst as of version 5.90065 0.31 2013-09-09 16:30:00 - Updated docs to reflect config key change from 'static' to 'Plugin::Static::Simple' (RT#77709) - Migrated repository from subversion to git - Fixed MIME::Types 2.xx compatibility be removing call to an undocumented method - Bumped the MIME::Types requirement to 2.03 to ensure its improvements make it into Catalyst environments 0.30 2012-05-04 17:05:00 - Add Cache-Control:public header - Optionally provide Expires header - Change configuration key to 'Plugin::Static::Simple' by default. The old 'static' key is still supported, but issues a warning. 0.29 2010-02-01 18:45:00 - Switch from override to around, because really, wtf 0.28 2010-01-04 13:15:00 - Fix issues in debug mode. (RT#53338) 0.27 2010-01-03 14:49:00 - Switch to being a Moose role, removing dependencies on Class::Data::Inheritable and Class::Accessor (Andrey Kostenko in RT#51089) - Make Pod tests mandatory for authors but never run otherwise - Switch to Test::NoTabs to ensure no tabs, rather than Test::Perl::Critic 0.26 2009-12-06 12:30:00 - Fix Pod to show less nasty method of assigning config by calling the config method with parameters, rather than poking around inside the hash. - Require newer (>= 0.15) Catalyst::Plugin::SubRequest for subrequest tests as old versions don't work with new Catalyst (>= 5.80014) 0.25 2009-10-22 21:40:00 BST - Fix bug where old unrelated $@ values would result in an error. 0.24 2009-10-18 19:10:00 BST - Fixup copyright information 0.23 2009-10-06 17:40:39 - Move actions out of TestApp into a Root controller as this is now deprecated. 0.22 2009-08-21 18:14:59 - Add tests for delivering empty files. - Fix those tests by depending on Catalyst-Runtime 5.80008. - Throw away compatibility code for older catalyst versions. - Fix docs to not include plugins in call to ->setup() (t0m) 0.21 2009-03-29 20:31:49 - Documentation improvements (jester) - Change from NEXT to MRO::Compat - RT#40628, RT#44553 (ilmari) - Bump prereq to MIME::Types to 1.25 to correctly send files commonly used to graft support for transparent PNGs into MSIE6 - RT#41314 (Florian Ragwitz) 0.20 2007-09-24 10:00:00 - Fixed issue where the static dir regex did not add a trailing slash so URLs such as /static1 were served as static when they should be handled by Catalyst. (Will Hawes) - Added text/html Content-Type to 404 responses. (Will Hawes) 0.19 2007-07-02 17:00:00 - Fixed test failure on some systems in 11serve_static.t due to multiple MIME types defined for the extension '.pm'. 0.18 2007-07-01 00:15:00 - Logging may now be enabled with the less confusing MyApp->config->{static}->{logging} = 1; 0.17 2007-05-11 11:00:00 - Added serve_static_file, to serve a given file as static. (groditi) 0.16 2007-04-30 15:00:00 - Allow all files in directories defined by the config option 'dirs' to be served as static even if the file matches ignore_dirs or ignore_extensions. - Fixed bug where 204 or 304 status codes would result in a 500 error under mod_perl. - Switch to Module::Install. 0.15 2006-12-08 22:30:00 - Quote metacharacters used in $c->config->{dirs} (Vlad Dan Dascalescu) - store Mime::Types object in config hash instead of as classdata - cleanup code a bit 0.14 2006-03-24 11:15:00 - Unescape the URI path before looking for the file. This fixes issues with files that have spaces. 0.13 2005-12-15 10:00:00 - Fixed bug in ignore_dirs under win32. - Doc rewriting 0.12 (released only with Catalyst) - Made prepare_action play nice with other plugins by not short- circuiting. - Added tmpl to the ignored extensions. - Fixed security problem if req->path contained '..'. 0.11 2005-11-13 16:25:00 - Removed the code that set the 304 Not Modified header. This caused problems with IE under Apache. - Changed 5.50 writing method to pass an IO::File object directly to $c->res->body. - This version is included with Catalyst 5.50. 0.10 2005-10-19 17:20:00 - Added tt2 to the list of ignored extensions. - For Catalyst 5.5+, replaced File::Slurp with a buffered read/write process. This will improve memory usage and performance on larger static files. - Removed Apache integration feature. It is slower than serving through Catalyst and as far as I know no one is using it. If you need the best performance, use a separate Location block for static content. 0.09 2005-10-07 13:40:00 - Added new configuration options to improve security: ignore_extensions - keep certain extensions from being static - This option defaults to tt, html, and xhtml to prevent template files from being accessible. ignore_dirs - keep certain dirs from being static - include_path is no longer experimental. - Added support for hiding log output, depends on Cat 5.50. (Marcus Ramberg) 0.08 2005-09-07 18:50:00 - Added tests for everything except Apache support. 0.07 2005-09-05 21:05:00 - POD fixes. (Thomas L. Shinnick) 0.06 2005-09-05 15:40:00 - Moved initial file check into prepare_action so processing can bypass other plugins. - Added error-checking to static dir regexes. - Cleaned up various code as per Best Practices. 0.05 2005-08-26 12:00:00 - Added use_apache option to enable the Apache DECLINED support. Default is disabled as it appears Catalyst is faster at serving the files! - Added a check that Apache's DocumentRoot matches Catalyst's root before serving DECLINED. - Preload MIME::Types index during setup() so it's not built on the first request. - Added a note on performance of Apache vs. Catalyst. 0.04 2005-08-22 12:00:00 - Fixed bug where static files were searched for on every request even without a file extension. - Fixed bug where files without extensions in defined static dirs were not served with text/plain. - Consolidated the debug log messages. 0.03 2005-08-21 23:50:00 - Added config option for include_path to allow for multiple directories with static files. This option should be considered experimental! - Documentation cleanups. 0.02 2005-08-16 18:00:00 - Return DECLINED when running under mod_perl to allow Apache to serve the static file. This is not done when any custom MIME types have been specified, however. 0.01 2005-08-11 22:00:00 - Initial release. Catalyst-Plugin-Static-Simple-0.33/inc/000755 000766 000024 00000000000 12424207252 020006 5ustar00johnstaff000000 000000 Catalyst-Plugin-Static-Simple-0.33/lib/000755 000766 000024 00000000000 12424207252 020003 5ustar00johnstaff000000 000000 Catalyst-Plugin-Static-Simple-0.33/Makefile.PL000644 000766 000024 00000002201 12424201643 021200 0ustar00johnstaff000000 000000 use strict; use warnings; use inc::Module::Install 0.91; use Module::Install::AuthorRequires; use Module::Install::AuthorTests; name 'Catalyst-Plugin-Static-Simple'; all_from 'lib/Catalyst/Plugin/Static/Simple.pm'; requires 'Catalyst::Runtime' => '5.80008'; requires 'MIME::Types' => '2.03'; requires 'Test::More'; requires 'Moose'; requires 'MooseX::Types'; requires 'namespace::autoclean'; test_requires 'Test::More'; author_requires 'Test::NoTabs'; author_requires 'Test::Pod' => '1.14'; author_requires 'Test::Pod::Coverage' => '1.04'; author_tests 't/author'; if( can_use 'Catalyst::Plugin::SubRequest' ) { unless( can_use 'Catalyst::Plugin::SubRequest' => '0.08' ) { print "** WARNING **\n" . "You appear to have a version of Catalyst::Plugin::SubRequest " . "older than 0.08.\n" . "You must upgrade to SubRequest 0.08 or later if you use it " . "in any applications with Static::Simple.\n"; requires 'Catalyst::Plugin::SubRequest' => '0.08'; } } auto_install; resources repository => 'git://git.shadowcat.co.uk/catagits/Catalyst-Plugin-Static-Simple.git'; WriteAll; Catalyst-Plugin-Static-Simple-0.33/MANIFEST000644 000766 000024 00000003275 12424207145 020376 0ustar00johnstaff000000 000000 .travis.yml Changes inc/Module/AutoInstall.pm inc/Module/Install.pm inc/Module/Install/AuthorRequires.pm inc/Module/Install/AuthorTests.pm inc/Module/Install/AutoInstall.pm inc/Module/Install/Base.pm inc/Module/Install/Can.pm inc/Module/Install/Fetch.pm inc/Module/Install/Include.pm inc/Module/Install/Makefile.pm inc/Module/Install/Metadata.pm inc/Module/Install/Win32.pm inc/Module/Install/WriteAll.pm lib/Catalyst/Plugin/Static/Simple.pm Makefile.PL MANIFEST This list of files META.yml MYMETA.json MYMETA.yml t/01use.t t/04static.t t/05dirs.t t/06include_path.t t/07mime_types.t t/08subreq.t t/09ignore_ext.t t/10ignore_dirs.t t/11serve_static.t t/12check_error_scope.t t/13no_include_path.t t/14deprecated.t t/20debug.t t/author/02pod.t t/author/03podcoverage.t t/author/notabs.t t/lib/IncTestApp.pm t/lib/IncTestApp/Controller/Root.pm t/lib/IncTestApp/root/images/bad.gif t/lib/IncTestApp/root/overlay/overlay.jpg t/lib/TestApp.pm t/lib/TestApp/Controller/Root.pm t/lib/TestApp/root/always-static/test t/lib/TestApp/root/always-static/test.html t/lib/TestApp/root/css/static.css t/lib/TestApp/root/files/bad.gif t/lib/TestApp/root/files/empty.txt t/lib/TestApp/root/files/err.omg t/lib/TestApp/root/files/static.css t/lib/TestApp/root/ignored/bad.gif t/lib/TestApp/root/ignored/index.html t/lib/TestApp/root/ignored/static.css t/lib/TestApp/root/ignored/tmpl.tt t/lib/TestApp/root/images/bad.gif t/lib/TestApp/root/images/catalyst.png t/lib/TestApp/root/incpath/incpath.css t/lib/TestApp/root/overlay/o-ignored/bad.gif t/lib/TestApp/root/overlay/o-ignored/index.html t/lib/TestApp/root/overlay/o-ignored/static.css t/lib/TestApp/root/overlay/o-ignored/tmpl.tt t/lib/TestApp/root/overlay/overlay.jpg t/lib/TestLog.pm Catalyst-Plugin-Static-Simple-0.33/META.yml000644 000766 000024 00000001376 12424207124 020513 0ustar00johnstaff000000 000000 --- abstract: 'Make serving static pages painless.' author: - 'Andy Grundman, ' build_requires: ExtUtils::MakeMaker: 6.36 Test::More: 0 configure_requires: ExtUtils::MakeMaker: 6.36 distribution_type: module dynamic_config: 1 generated_by: 'Module::Install version 1.12' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: Catalyst-Plugin-Static-Simple no_index: directory: - inc - t requires: Catalyst::Runtime: '5.80008' MIME::Types: '2.03' Moose: 0 MooseX::Types: 0 Test::More: 0 namespace::autoclean: 0 resources: license: http://dev.perl.org/licenses/ repository: git://git.shadowcat.co.uk/catagits/Catalyst-Plugin-Static-Simple.git version: '0.33' Catalyst-Plugin-Static-Simple-0.33/MYMETA.json000644 000766 000024 00000002517 12424207124 021127 0ustar00johnstaff000000 000000 { "abstract" : "Make serving static pages painless.", "author" : [ "Andy Grundman, " ], "dynamic_config" : 0, "generated_by" : "Module::Install version 1.12, CPAN::Meta::Converter version 2.142060", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "Catalyst-Plugin-Static-Simple", "no_index" : { "directory" : [ "inc", "t" ] }, "prereqs" : { "build" : { "requires" : { "ExtUtils::MakeMaker" : "6.36", "Test::More" : "0" } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "runtime" : { "requires" : { "Catalyst::Runtime" : "5.80008", "MIME::Types" : "2.03", "Moose" : "0", "MooseX::Types" : "0", "Test::More" : "0", "namespace::autoclean" : "0" } } }, "release_status" : "stable", "resources" : { "license" : [ "http://dev.perl.org/licenses/" ], "repository" : { "type" : "git", "url" : "git://git.shadowcat.co.uk/catagits/Catalyst-Plugin-Static-Simple.git" } }, "version" : "0.32" } Catalyst-Plugin-Static-Simple-0.33/MYMETA.yml000644 000766 000024 00000001431 12424207124 020751 0ustar00johnstaff000000 000000 --- abstract: 'Make serving static pages painless.' author: - 'Andy Grundman, ' build_requires: ExtUtils::MakeMaker: '6.36' Test::More: '0' configure_requires: ExtUtils::MakeMaker: '0' dynamic_config: 0 generated_by: 'Module::Install version 1.12, CPAN::Meta::Converter version 2.142060' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: Catalyst-Plugin-Static-Simple no_index: directory: - inc - t requires: Catalyst::Runtime: '5.80008' MIME::Types: '2.03' Moose: '0' MooseX::Types: '0' Test::More: '0' namespace::autoclean: '0' resources: license: http://dev.perl.org/licenses/ repository: git://git.shadowcat.co.uk/catagits/Catalyst-Plugin-Static-Simple.git version: '0.32' Catalyst-Plugin-Static-Simple-0.33/t/000755 000766 000024 00000000000 12424207252 017500 5ustar00johnstaff000000 000000 Catalyst-Plugin-Static-Simple-0.33/t/01use.t000644 000766 000024 00000000134 12424201643 020616 0ustar00johnstaff000000 000000 use Test::More tests => 2; use_ok('Catalyst'); use_ok('Catalyst::Plugin::Static::Simple'); Catalyst-Plugin-Static-Simple-0.33/t/04static.t000644 000766 000024 00000002457 12424201643 021326 0ustar00johnstaff000000 000000 #!perl use strict; use warnings; use FindBin; use lib "$FindBin::Bin/lib"; # Module::Build craps out on files with spaces so it's not included in the dist my $has_space_file = -e "$FindBin::Bin/lib/TestApp/root/files/space file.txt"; use Test::More; plan tests => ($has_space_file) ? 12 : 9; use Catalyst::Test 'TestApp'; # test getting a css file ok( my $res = request('http://localhost/files/static.css'), 'request ok' ); is( $res->content_type, 'text/css', 'content-type text/css ok' ); like( $res->content, qr/background/, 'content of css ok' ); # test a file with spaces if ( $has_space_file ) { ok( $res = request('http://localhost/files/space file.txt'), 'request ok' ); is( $res->content_type, 'text/plain', 'content-type text/plain ok' ); like( $res->content, qr/background/, 'content of space file ok' ); } # test a non-existent file ok( $res = request('http://localhost/files/404.txt'), 'request ok' ); is( $res->content, 'default', 'default handler for non-existent content ok' ); # test unknown extension ok( $res = request('http://localhost/files/err.omg'), 'request ok' ); is( $res->content_type, 'text/plain', 'unknown extension as text/plain ok' ); ok( $res = request('http://localhost/files/empty.txt'), 'request ok' ); is( $res->content, '', 'empty files result in an empty response' ); Catalyst-Plugin-Static-Simple-0.33/t/05dirs.t000644 000766 000024 00000002547 12424201643 021001 0ustar00johnstaff000000 000000 #!perl use strict; use warnings; use FindBin; use lib "$FindBin::Bin/lib"; use Test::More tests => 13; use Catalyst::Test 'TestApp'; # test defined static dirs TestApp->config->{'Plugin::Static::Simple'}->{dirs} = [ 'always-static', qr/^images/, 'qr/^css/', ]; # a file with no extension will return text/plain ok( my $res = request('http://localhost/always-static/test'), 'request ok' ); is( $res->content_type, 'text/plain', 'text/plain ok' ); # a file with an extension in ignore_extensions still gets served ok( $res = request('http://localhost/always-static/test.html'), 'request ok' ); is( $res->code, 200, 'html file in dirs get served' ); # a missing file in a defined static dir will return 404 and text/html ok( $res = request('http://localhost/always-static/404.txt'), 'request ok' ); is( $res->code, 404, '404 ok' ); is( $res->content_type, 'text/html', '404 is text/html' ); # qr regex test ok( $res = request('http://localhost/images/catalyst.png'), 'request ok' ); is( $res->content_type, 'image/png', 'qr regex path ok' ); # eval regex test ok( $res = request('http://localhost/css/static.css'), 'request ok' ); like( $res->content, qr/background/, 'eval regex path ok' ); # A static dir with no trailing slash is handled by Cat ok( $res = request('http://localhost/always-static'), 'request ok' ); is( $res->content, 'default', 'content ok' ); Catalyst-Plugin-Static-Simple-0.33/t/06include_path.t000644 000766 000024 00000001430 12424201643 022466 0ustar00johnstaff000000 000000 #!perl use strict; use warnings; use FindBin; use lib "$FindBin::Bin/lib"; use Test::More tests => 6; use Catalyst::Test 'TestApp'; # test altenate root dirs TestApp->config->{'Plugin::Static::Simple'}->{include_path} = [ TestApp->config->{root} . '/overlay', \&TestApp::incpath_generator, TestApp->config->{root}, ]; # test overlay dir ok( my $res = request('http://localhost/overlay.jpg'), 'request ok' ); is( $res->content_type, 'image/jpeg', 'overlay path ok' ); # test incpath_generator ok( $res = request('http://localhost/incpath.css'), 'request ok' ); is( $res->content_type, 'text/css', 'incpath coderef ok' ); # test passthrough to root ok( $res = request('http://localhost/images/bad.gif'), 'request ok' ); is( $res->content_type, 'image/gif', 'root path ok' ); Catalyst-Plugin-Static-Simple-0.33/t/07mime_types.t000644 000766 000024 00000001113 12424201643 022201 0ustar00johnstaff000000 000000 #!perl use strict; use warnings; use FindBin; use lib "$FindBin::Bin/lib"; use Test::More tests => 4; use Catalyst::Test 'TestApp'; # test custom MIME types TestApp->config->{'Plugin::Static::Simple'}->{mime_types} = { omg => 'holy/crap', gif => 'patents/are-evil', }; ok( my $res = request('http://localhost/files/err.omg'), 'request ok' ); is( $res->content_type, 'holy/crap', 'custom MIME type ok' ); ok( $res = request('http://localhost/files/bad.gif'), 'request ok' ); is( $res->content_type, 'patents/are-evil', 'custom MIME type overlay ok' ); Catalyst-Plugin-Static-Simple-0.33/t/08subreq.t000644 000766 000024 00000001070 12424201643 021332 0ustar00johnstaff000000 000000 #!perl use strict; use warnings; use FindBin; use lib "$FindBin::Bin/lib"; use Test::More tests => 2; use Catalyst::Test 'TestApp'; SKIP: { unless ( TestApp->isa('Catalyst::Plugin::SubRequest') ) { skip "Install Catalyst::Plugin::SubRequest >= 0.15 for these tests", 2; } unless ( $Catalyst::Plugin::SubRequest::VERSION >= 0.15 ) { skip "Need Catalyst::Plugin::SubRequest >= 0.15 for these tests", 2; } ok( my $res = request('http://localhost/subtest'), 'Request' ); is( $res->content, 'subtest2 ok', 'SubRequest ok' ); } Catalyst-Plugin-Static-Simple-0.33/t/09ignore_ext.t000644 000766 000024 00000000716 12424201643 022203 0ustar00johnstaff000000 000000 #!perl use strict; use warnings; use FindBin; use lib "$FindBin::Bin/lib"; use Test::More tests => 4; use Catalyst::Test 'TestApp'; # test ignoring extensions # default is tt/html/xhtml ok( my $res = request('http://localhost/ignored/tmpl.tt'), 'request ok' ); is( $res->content, 'default', 'ignored extension tt ok' ); ok( $res = request('http://localhost/ignored/index.html'), 'request ok' ); is( $res->content, 'default', 'ignored extension html ok' ); Catalyst-Plugin-Static-Simple-0.33/t/10ignore_dirs.t000644 000766 000024 00000001512 12424201643 022327 0ustar00johnstaff000000 000000 #!perl use strict; use warnings; use FindBin; use lib "$FindBin::Bin/lib"; use Test::More tests => 6; use Catalyst::Test 'TestApp'; # test ignoring directories TestApp->config->{'Plugin::Static::Simple'}->{ignore_dirs} = [ qw/ignored o-ignored files/ ]; # test altenate root dirs TestApp->config->{'Plugin::Static::Simple'}->{include_path} = [ TestApp->config->{root} . '/overlay', TestApp->config->{root}, ]; ok( my $res = request('http://localhost/ignored/bad.gif'), 'request ok' ); is( $res->content, 'default', 'ignored directory `ignored` ok' ); ok( $res = request('http://localhost/files/static.css'), 'request ok' ); is( $res->content, 'default', 'ignored directory `files` ok' ); ok( $res = request('http://localhost/o-ignored/bad.gif'), 'request ok' ); is( $res->content, 'default', 'ignored overlay directory ok' ); Catalyst-Plugin-Static-Simple-0.33/t/11serve_static.t000644 000766 000024 00000001225 12424201643 022520 0ustar00johnstaff000000 000000 #!perl use strict; use warnings; use FindBin; use lib "$FindBin::Bin/lib"; use Test::More tests => 6; use Catalyst::Test 'TestApp'; # test getting a file via serve_static_file ok( my $res = request('http://localhost/serve_static'), 'request ok' ); is( $res->code, 200, '200 ok' ); # .pm can be both application/x-pagemaker or text/x-perl, so only check for a slash like( $res->content_type, qr{/}, 'content-type ok' ); like( $res->content, qr/package TestApp/, 'content of serve_static ok' ); # test getting a non-existant file via serve_static_file ok( $res = request('http://localhost/serve_static_404'), 'request ok' ); is( $res->code, 404, '404 ok' ); Catalyst-Plugin-Static-Simple-0.33/t/12check_error_scope.t000644 000766 000024 00000001227 12424201643 023507 0ustar00johnstaff000000 000000 #!perl use strict; use warnings; no strict 'refs'; no warnings 'redefine'; use FindBin; use lib "$FindBin::Bin/lib"; use Test::More tests => 3; BEGIN { use Catalyst::Plugin::Static::Simple; Catalyst::Plugin::Static::Simple->meta->add_before_method_modifier( 'prepare_action', sub { my ($c) = @_; eval { die("FOO"); }; ok( $@, '$@ has a value.' ); } ); } use Catalyst::Test 'TestApp'; TestApp->config->{'Plugin::Static::Simple'}->{dirs} = [qr{stuff/}]; ok( my $res = request("http://localhost/"), 'request ok' ); ok( $res->code == 200, q{Previous error doesn't crash static::simple} ); Catalyst-Plugin-Static-Simple-0.33/t/13no_include_path.t000644 000766 000024 00000001006 12424201643 023157 0ustar00johnstaff000000 000000 #!perl use strict; use warnings; use FindBin; use lib "$FindBin::Bin/lib"; use Test::More tests => 4; use Catalyst::Test 'TestApp'; # test passthrough to root ok( my $res = request('http://localhost/images/bad.gif'), 'request ok' ); is( $res->content_type, 'image/gif', 'root path ok' ); is( scalar @{ TestApp->config->{'Plugin::Static::Simple'}->{include_path} }, 1, 'One include path used'); is( TestApp->config->{'Plugin::Static::Simple'}->{include_path}->[0], TestApp->config->{root}, "It's the root path" ); Catalyst-Plugin-Static-Simple-0.33/t/14deprecated.t000644 000766 000024 00000001103 12424201643 022123 0ustar00johnstaff000000 000000 #!perl use strict; use warnings; use FindBin; use lib "$FindBin::Bin/lib"; use Test::More tests => 5; use Catalyst::Test 'IncTestApp'; is( $TestLog::logged, "Deprecated 'static' config key used, please use the key 'Plugin::Static::Simple' instead", "Got warning" ); # test overlay dir ok( my $res = request('http://localhost/overlay.jpg'), 'request ok' ); is( $res->content_type, 'image/jpeg', 'overlay path ok' ); # test passthrough to root ok( $res = request('http://localhost/images/bad.gif'), 'request ok' ); is( $res->content_type, 'image/gif', 'root path ok' ); Catalyst-Plugin-Static-Simple-0.33/t/20debug.t000644 000766 000024 00000001544 12424201643 021117 0ustar00johnstaff000000 000000 #!perl use strict; use warnings; use FindBin; use lib "$FindBin::Bin/lib"; use Test::More tests => 5; use Catalyst::Test 'TestApp'; # test defined static dirs TestApp->config->{'Plugin::Static::Simple'}->{dirs} = [ 'always-static', ]; TestApp->config->{'Plugin::Static::Simple'}->{debug} = 1; use Catalyst::Log; local *Catalyst::Log::_send_to_log; local our @MESSAGES; { no warnings 'redefine'; *Catalyst::Log::_send_to_log = sub { my $self = shift; push @MESSAGES, @_; }; } # a missing file in a defined static dir will return 404 and text/html ok( my $res = request('http://localhost/always-static/404.txt'), 'request ok' ); is( $res->code, 404, '404 ok' ); is( $res->content_type, 'text/html', '404 is text/html' ); ok(defined $MESSAGES[0], 'debug message set'); like( $MESSAGES[0], qr/404/, 'debug message contains 404'); Catalyst-Plugin-Static-Simple-0.33/t/author/000755 000766 000024 00000000000 12424207252 021002 5ustar00johnstaff000000 000000 Catalyst-Plugin-Static-Simple-0.33/t/lib/000755 000766 000024 00000000000 12424207252 020246 5ustar00johnstaff000000 000000 Catalyst-Plugin-Static-Simple-0.33/t/lib/IncTestApp/000755 000766 000024 00000000000 12424207252 022260 5ustar00johnstaff000000 000000 Catalyst-Plugin-Static-Simple-0.33/t/lib/IncTestApp.pm000644 000766 000024 00000001632 12424203263 022616 0ustar00johnstaff000000 000000 package IncTestApp; # FIXME: I have to do this because TestApp runs setup at compile time # Perhaps it would be better to let the tests run setup? use strict; use Catalyst; use FindBin; use TestLog; our $VERSION = '0.01'; IncTestApp->config( name => 'TestApp', debug => 1, static => { include_path => [ IncTestApp->config->{root}, ] }, 'Plugin::Static::Simple' => { include_path => [ IncTestApp->config->{root} . '/overlay', ] }, ); IncTestApp->log( TestLog->new ); my @plugins = qw/Static::Simple/; # load the SubRequest plugin if available eval { require Catalyst::Plugin::SubRequest; die unless Catalyst::Plugin::SubRequest->VERSION ge '0.08'; }; push @plugins, 'SubRequest' unless ($@); IncTestApp->setup( @plugins ); sub incpath_generator { my $c = shift; return [ $c->config->{root} . '/incpath' ]; } 1; Catalyst-Plugin-Static-Simple-0.33/t/lib/TestApp/000755 000766 000024 00000000000 12424207252 021626 5ustar00johnstaff000000 000000 Catalyst-Plugin-Static-Simple-0.33/t/lib/TestApp.pm000644 000766 000024 00000001035 12424201643 022161 0ustar00johnstaff000000 000000 package TestApp; use strict; use Catalyst; use FindBin; our $VERSION = '0.01'; TestApp->config( name => 'TestApp', debug => 1, ); my @plugins = qw/Static::Simple/; # load the SubRequest plugin if available eval { require Catalyst::Plugin::SubRequest; die unless Catalyst::Plugin::SubRequest->VERSION ge '0.08'; }; push @plugins, 'SubRequest' unless ($@); TestApp->setup( @plugins ); sub incpath_generator { my $c = shift; return [ $c->config->{root} . '/incpath' ]; } 1; Catalyst-Plugin-Static-Simple-0.33/t/lib/TestLog.pm000644 000766 000024 00000000215 12424201643 022161 0ustar00johnstaff000000 000000 package TestLog; use Moose; extends 'Catalyst::Log'; our $logged; override warn => sub { my $self = shift; $logged = shift; }; 1; Catalyst-Plugin-Static-Simple-0.33/t/lib/TestApp/Controller/000755 000766 000024 00000000000 12424207252 023751 5ustar00johnstaff000000 000000 Catalyst-Plugin-Static-Simple-0.33/t/lib/TestApp/root/000755 000766 000024 00000000000 12424207252 022611 5ustar00johnstaff000000 000000 Catalyst-Plugin-Static-Simple-0.33/t/lib/TestApp/root/always-static/000755 000766 000024 00000000000 12424207252 025376 5ustar00johnstaff000000 000000 Catalyst-Plugin-Static-Simple-0.33/t/lib/TestApp/root/css/000755 000766 000024 00000000000 12424207252 023401 5ustar00johnstaff000000 000000 Catalyst-Plugin-Static-Simple-0.33/t/lib/TestApp/root/files/000755 000766 000024 00000000000 12424207252 023713 5ustar00johnstaff000000 000000 Catalyst-Plugin-Static-Simple-0.33/t/lib/TestApp/root/ignored/000755 000766 000024 00000000000 12424207252 024240 5ustar00johnstaff000000 000000 Catalyst-Plugin-Static-Simple-0.33/t/lib/TestApp/root/images/000755 000766 000024 00000000000 12424207252 024056 5ustar00johnstaff000000 000000 Catalyst-Plugin-Static-Simple-0.33/t/lib/TestApp/root/incpath/000755 000766 000024 00000000000 12424207252 024237 5ustar00johnstaff000000 000000 Catalyst-Plugin-Static-Simple-0.33/t/lib/TestApp/root/overlay/000755 000766 000024 00000000000 12424207252 024272 5ustar00johnstaff000000 000000 Catalyst-Plugin-Static-Simple-0.33/t/lib/TestApp/root/overlay/o-ignored/000755 000766 000024 00000000000 12424207252 026155 5ustar00johnstaff000000 000000 Catalyst-Plugin-Static-Simple-0.33/t/lib/TestApp/root/overlay/overlay.jpg000644 000766 000024 00000000037 12424201643 026453 0ustar00johnstaff000000 000000 body { background: #fff; } Catalyst-Plugin-Static-Simple-0.33/t/lib/TestApp/root/overlay/o-ignored/bad.gif000644 000766 000024 00000000037 12424201643 027370 0ustar00johnstaff000000 000000 body { background: #fff; } Catalyst-Plugin-Static-Simple-0.33/t/lib/TestApp/root/overlay/o-ignored/index.html000644 000766 000024 00000000037 12424201643 030150 0ustar00johnstaff000000 000000 body { background: #fff; } Catalyst-Plugin-Static-Simple-0.33/t/lib/TestApp/root/overlay/o-ignored/static.css000644 000766 000024 00000000037 12424201643 030154 0ustar00johnstaff000000 000000 body { background: #fff; } Catalyst-Plugin-Static-Simple-0.33/t/lib/TestApp/root/overlay/o-ignored/tmpl.tt000644 000766 000024 00000000037 12424201643 027500 0ustar00johnstaff000000 000000 body { background: #fff; } Catalyst-Plugin-Static-Simple-0.33/t/lib/TestApp/root/incpath/incpath.css000644 000766 000024 00000000037 12424201643 026375 0ustar00johnstaff000000 000000 body { background: #fff; } Catalyst-Plugin-Static-Simple-0.33/t/lib/TestApp/root/images/bad.gif000644 000766 000024 00000000037 12424201643 025271 0ustar00johnstaff000000 000000 body { background: #fff; } Catalyst-Plugin-Static-Simple-0.33/t/lib/TestApp/root/images/catalyst.png000644 000766 000024 00000004377 12424201643 026421 0ustar00johnstaff000000 000000 PNG  IHDRXTgAMAOX2tEXtSoftwareAdobe ImageReadyqe<PLTEOOggzzٔKKrrr((㳲嬬 80)fffSSS|||ZZZZZƇ..ك簾掊vqlttݺꥥII6.'ܐooo||E=7RKEhb]옘\\,,ł}yIB;{vqc]XԮ}lfaMF@ǻKKKjjj FFFԜ\\\铐^WQΟZSM}xsίPIC̝_YS66ح??mmlݷٰ rr諬գթߢaaa%IDATxڬ PWEA}FxUD9Y9[xP<"$,`r"ePZiZCE{M[Ŏmm{?;>"' IXoJcM p՞x+[n/-iVoJJʩ0+8Noo0ةx:{!n\8`:HScB#$ ރDb' XS&]7ި/H,oY"Ɋ):%Gdh`fIvZY3E;~e'asr#UfE8 sPobreh;6p4ø1TQ/ORNF0_BZdqLp6ar/'Nsxn1׃XRuBQ 6i1WsJ$=I ACqM[VӕmxWW׫?2Δa usՔ^ /v] a"U}N3k3 .ΰرR?}YʞZG`acݙN?W7_Z[ Z{d Ȉg˰ن Gí֠V''=lZH5-::>|rBѨ~כ67+V { SShBQ!GG phT(*|6ϙtFAvlJ;Id 28˝KsN2}U*nGM'In8 &ܤ^F ùs;붘(ʝ6z& rۗ)D<JP(f0yXAEQ(堥a •p!?`_,Z4;ۆj!?Qr<`94!hk,:jڈ0\w8QL$E$~!c;[P{.N#]eVYcpގ.gAȂZBڗDMSZZHmZmH7̘L.ݭJB^$'!JPˊ(V Y"ټZ.6Kf%1Am xϯDQqnnCg  S-\vU Pe!HP e*QJu I* test
test
Catalyst-Plugin-Static-Simple-0.33/t/lib/TestApp/Controller/Root.pm000644 000766 000024 00000001501 12424201643 025225 0ustar00johnstaff000000 000000 package TestApp::Controller::Root; use strict; use warnings; use File::Spec::Functions; use base qw/Catalyst::Controller/; __PACKAGE__->config(namespace => ''); sub default : Private { my ( $self, $c ) = @_; $c->res->output( 'default' ); } sub subtest : Local { my ( $self, $c ) = @_; $c->res->output( $c->subreq('/subtest2') ); } sub subtest2 : Local { my ( $self, $c ) = @_; $c->res->output( 'subtest2 ok' ); } sub serve_static : Local { my ( $self, $c ) = @_; my $file = catfile( $FindBin::Bin, 'lib', 'TestApp.pm' ); $c->serve_static_file( $file ); } sub serve_static_404 : Local { my ( $self, $c ) = @_; my $file = catfile( $FindBin::Bin, 'lib', 'foo.pm' ); $c->serve_static_file( $file ); } 1; Catalyst-Plugin-Static-Simple-0.33/t/lib/IncTestApp/Controller/000755 000766 000024 00000000000 12424207252 024403 5ustar00johnstaff000000 000000 Catalyst-Plugin-Static-Simple-0.33/t/lib/IncTestApp/root/000755 000766 000024 00000000000 12424207252 023243 5ustar00johnstaff000000 000000 Catalyst-Plugin-Static-Simple-0.33/t/lib/IncTestApp/root/images/000755 000766 000024 00000000000 12424207252 024510 5ustar00johnstaff000000 000000 Catalyst-Plugin-Static-Simple-0.33/t/lib/IncTestApp/root/overlay/000755 000766 000024 00000000000 12424207252 024724 5ustar00johnstaff000000 000000 Catalyst-Plugin-Static-Simple-0.33/t/lib/IncTestApp/root/overlay/overlay.jpg000644 000766 000024 00000000037 12424201643 027105 0ustar00johnstaff000000 000000 body { background: #fff; } Catalyst-Plugin-Static-Simple-0.33/t/lib/IncTestApp/root/images/bad.gif000644 000766 000024 00000000037 12424201643 025723 0ustar00johnstaff000000 000000 body { background: #fff; } Catalyst-Plugin-Static-Simple-0.33/t/lib/IncTestApp/Controller/Root.pm000644 000766 000024 00000000266 12424201643 025666 0ustar00johnstaff000000 000000 package IncTestApp::Controller::Root; use strict; use warnings; use File::Spec::Functions; use base qw/Catalyst::Controller/; __PACKAGE__->config(namespace => ''); 1; Catalyst-Plugin-Static-Simple-0.33/t/author/02pod.t000644 000766 000024 00000000124 12424201643 022106 0ustar00johnstaff000000 000000 use strict; use warnings; use Test::More; use Test::Pod 1.14; all_pod_files_ok(); Catalyst-Plugin-Static-Simple-0.33/t/author/03podcoverage.t000644 000766 000024 00000000107 12424201643 023624 0ustar00johnstaff000000 000000 use Test::More; use Test::Pod::Coverage 1.04; all_pod_coverage_ok(); Catalyst-Plugin-Static-Simple-0.33/t/author/notabs.t000644 000766 000024 00000000132 12424201643 022447 0ustar00johnstaff000000 000000 use strict; use warnings; use Test::More; use Test::NoTabs; all_perl_files_ok(qw/lib/); Catalyst-Plugin-Static-Simple-0.33/lib/Catalyst/000755 000766 000024 00000000000 12424207252 021567 5ustar00johnstaff000000 000000 Catalyst-Plugin-Static-Simple-0.33/lib/Catalyst/Plugin/000755 000766 000024 00000000000 12424207252 023025 5ustar00johnstaff000000 000000 Catalyst-Plugin-Static-Simple-0.33/lib/Catalyst/Plugin/Static/000755 000766 000024 00000000000 12424207252 024254 5ustar00johnstaff000000 000000 Catalyst-Plugin-Static-Simple-0.33/lib/Catalyst/Plugin/Static/Simple.pm000755 000766 000024 00000050355 12424206657 026066 0ustar00johnstaff000000 000000 package Catalyst::Plugin::Static::Simple; use Moose::Role; use File::stat; use File::Spec (); use IO::File (); use MIME::Types (); use MooseX::Types::Moose qw/ArrayRef Str/; use Catalyst::Utils; use namespace::autoclean; our $VERSION = '0.33'; has _static_file => ( is => 'rw' ); has _static_debug_message => ( is => 'rw', isa => ArrayRef[Str] ); after setup_finalize => sub { my $c = shift; # New: Turn off new 'autoflush' flag in logger (see Catalyst::Log). # This is needed to surpress output of debug log messages for # static requests: $c->log->autoflush(0) if $c->log->can('autoflush'); }; before prepare_action => sub { my $c = shift; my $path = $c->req->path; my $config = $c->config->{'Plugin::Static::Simple'}; $path =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg; # is the URI in a static-defined path? foreach my $dir ( @{ $config->{dirs} } ) { my $dir_re = quotemeta $dir; # strip trailing slashes, they'll be added in our regex $dir_re =~ s{/$}{}; my $re; if ( $dir =~ m{^qr/}xms ) { $re = eval $dir; if ($@) { $c->error( "Error compiling static dir regex '$dir': $@" ); } } else { $re = qr{^${dir_re}/}; } if ( $path =~ $re ) { if ( $c->_locate_static_file( $path, 1 ) ) { $c->_debug_msg( 'from static directory' ) if $config->{debug}; } else { $c->_debug_msg( "404: file not found: $path" ) if $config->{debug}; $c->res->status( 404 ); $c->res->content_type( 'text/html' ); } } } # Does the path have an extension? if ( $path =~ /.*\.(\S{1,})$/xms ) { # and does it exist? $c->_locate_static_file( $path ); } }; around dispatch => sub { my $orig = shift; my $c = shift; return if ( $c->res->status != 200 ); if ( $c->_static_file ) { if ( $c->config->{'Plugin::Static::Simple'}->{no_logs} && $c->log->can('abort') ) { $c->log->abort( 1 ); } return $c->_serve_static; } else { return $c->$orig(@_); } }; before finalize => sub { my $c = shift; # display all log messages if ( $c->config->{'Plugin::Static::Simple'}->{debug} && scalar @{$c->_debug_msg} ) { $c->log->debug( 'Static::Simple: ' . join q{ }, @{$c->_debug_msg} ); } }; before setup_finalize => sub { my $c = shift; $c->log->warn("Deprecated 'static' config key used, please use the key 'Plugin::Static::Simple' instead") if exists $c->config->{static}; if (exists $c->config->{static}->{include_path}) { $c->config->{'Plugin::Static::Simple'}->{include_path} = [ @{$c->config->{'Plugin::Static::Simple'}->{include_path} || []}, @{delete $c->config->{static}->{include_path} || []} ]; } my $config = $c->config->{'Plugin::Static::Simple'} = $c->config->{'static'} = Catalyst::Utils::merge_hashes( $c->config->{'Plugin::Static::Simple'} || {}, $c->config->{static} || {} ); $config->{dirs} ||= []; $config->{include_path} ||= [ $c->config->{root} ]; $config->{mime_types} ||= {}; $config->{ignore_extensions} ||= [ qw/tmpl tt tt2 html xhtml/ ]; $config->{ignore_dirs} ||= []; $config->{debug} ||= $c->debug; $config->{no_logs} = 1 unless defined $config->{no_logs}; $config->{no_logs} = 0 if $config->{logging}; # load up a MIME::Types object, only loading types with # at least 1 file extension $config->{mime_types_obj} = MIME::Types->new( only_complete => 1 ); }; # Search through all included directories for the static file # Based on Template Toolkit INCLUDE_PATH code sub _locate_static_file { my ( $c, $path, $in_static_dir ) = @_; $path = File::Spec->catdir( File::Spec->no_upwards( File::Spec->splitdir( $path ) ) ); my $config = $c->config->{'Plugin::Static::Simple'}; my @ipaths = @{ $config->{include_path} }; my $dpaths; my $count = 64; # maximum number of directories to search DIR_CHECK: while ( @ipaths && --$count) { my $dir = shift @ipaths || next DIR_CHECK; if ( ref $dir eq 'CODE' ) { eval { $dpaths = &$dir( $c ) }; if ($@) { $c->log->error( 'Static::Simple: include_path error: ' . $@ ); } else { unshift @ipaths, @$dpaths; next DIR_CHECK; } } else { $dir =~ s/(\/|\\)$//xms; if ( -d $dir && -f $dir . '/' . $path ) { # Don't ignore any files in static dirs defined with 'dirs' unless ( $in_static_dir ) { # do we need to ignore the file? for my $ignore ( @{ $config->{ignore_dirs} } ) { $ignore =~ s{(/|\\)$}{}; if ( $path =~ /^$ignore(\/|\\)/ ) { $c->_debug_msg( "Ignoring directory `$ignore`" ) if $config->{debug}; next DIR_CHECK; } } # do we need to ignore based on extension? for my $ignore_ext ( @{ $config->{ignore_extensions} } ) { if ( $path =~ /.*\.${ignore_ext}$/ixms ) { $c->_debug_msg( "Ignoring extension `$ignore_ext`" ) if $config->{debug}; next DIR_CHECK; } } } $c->_debug_msg( 'Serving ' . $dir . '/' . $path ) if $config->{debug}; return $c->_static_file( $dir . '/' . $path ); } } } return; } sub _serve_static { my $c = shift; my $config = $c->config->{'Plugin::Static::Simple'}; my $full_path = shift || $c->_static_file; my $type = $c->_ext_to_type( $full_path ); my $stat = stat $full_path; $c->res->headers->content_type( $type ); $c->res->headers->content_length( $stat->size ); $c->res->headers->last_modified( $stat->mtime ); # Tell Firefox & friends its OK to cache, even over SSL: $c->res->headers->header('Cache-control' => 'public'); # Optionally, set a fixed expiry time: if ($config->{expires}) { $c->res->headers->expires(time() + $config->{expires}); } my $fh = IO::File->new( $full_path, 'r' ); if ( defined $fh ) { binmode $fh; $c->res->body( $fh ); } else { Catalyst::Exception->throw( message => "Unable to open $full_path for reading" ); } return 1; } sub serve_static_file { my ( $c, $full_path ) = @_; my $config = $c->config->{'Plugin::Static::Simple'}; if ( -e $full_path ) { $c->_debug_msg( "Serving static file: $full_path" ) if $config->{debug}; } else { $c->_debug_msg( "404: file not found: $full_path" ) if $config->{debug}; $c->res->status( 404 ); $c->res->content_type( 'text/html' ); return; } $c->_serve_static( $full_path ); } # looks up the correct MIME type for the current file extension sub _ext_to_type { my ( $c, $full_path ) = @_; my $config = $c->config->{'Plugin::Static::Simple'}; if ( $full_path =~ /.*\.(\S{1,})$/xms ) { my $ext = $1; my $type = $config->{mime_types}{$ext} || $config->{mime_types_obj}->mimeTypeOf( $ext ); if ( $type ) { $c->_debug_msg( "as $type" ) if $config->{debug}; return ( ref $type ) ? $type->type : $type; } else { $c->_debug_msg( "as text/plain (unknown extension $ext)" ) if $config->{debug}; return 'text/plain'; } } else { $c->_debug_msg( 'as text/plain (no extension)' ) if $config->{debug}; return 'text/plain'; } } sub _debug_msg { my ( $c, $msg ) = @_; if ( !defined $c->_static_debug_message ) { $c->_static_debug_message( [] ); } if ( $msg ) { push @{ $c->_static_debug_message }, $msg; } return $c->_static_debug_message; } 1; __END__ =head1 NAME Catalyst::Plugin::Static::Simple - Make serving static pages painless. =head1 SYNOPSIS package MyApp; use Catalyst qw/ Static::Simple /; MyApp->setup; # that's it; static content is automatically served by Catalyst # from the application's root directory, though you can configure # things or bypass Catalyst entirely in a production environment # # one caveat: the files must be served from an absolute path # (i.e. /images/foo.png) =head1 DESCRIPTION The Static::Simple plugin is designed to make serving static content in your application during development quick and easy, without requiring a single line of code from you. This plugin detects static files by looking at the file extension in the URL (such as B<.css> or B<.png> or B<.js>). The plugin uses the lightweight L module to map file extensions to IANA-registered MIME types, and will serve your static files with the correct MIME type directly to the browser, without being processed through Catalyst. Note that actions mapped to paths using periods (.) will still operate properly. If the plugin can not find the file, the request is dispatched to your application instead. This means you are responsible for generating a C<404> error if your applicaton can not process the request: # handled by static::simple, not dispatched to your application /images/exists.png # static::simple will not find the file and let your application # handle the request. You are responsible for generating a file # or returning a 404 error /images/does_not_exist.png Though Static::Simple is designed to work out-of-the-box, you can tweak the operation by adding various configuration options. In a production environment, you will probably want to use your webserver to deliver static content; for an example see L, below. =head1 DEFAULT BEHAVIOUR By default, Static::Simple will deliver all files having extensions (that is, bits of text following a period (C<.>)), I files having the extensions C, C, C, C, and C. These files, and all files without extensions, will be processed through Catalyst. If L doesn't recognize an extension, it will be served as C. To restate: files having the extensions C, C, C, C, and C I be served statically by default, they will be processed by Catalyst. Thus if you want to use C<.html> files from within a Catalyst app as static files, you need to change the configuration of Static::Simple. Note also that files having any other extension I be served statically, so if you're using any other extension for template files, you should also change the configuration. Logging of static files is turned off by default. =head1 ADVANCED CONFIGURATION Configuration is completely optional and is specified within Cconfig-E{Plugin::Static::Simple}>. If you use any of these options, this module will probably feel less "simple" to you! =head2 Enabling request logging Since Catalyst 5.50, logging of static requests is turned off by default; static requests tend to clutter the log output and rarely reveal anything useful. However, if you want to enable logging of static requests, you can do so by setting Cconfig-E{Plugin::Static::Simple}-E{logging}> to 1. =head2 Forcing directories into static mode Define a list of top-level directories beneath your 'root' directory that should always be served in static mode. Regular expressions may be specified using C. MyApp->config( 'Plugin::Static::Simple' => { dirs => [ 'static', qr/^(images|css)/, ], } ); =head2 Including additional directories You may specify a list of directories in which to search for your static files. The directories will be searched in order and will return the first file found. Note that your root directory is B automatically added to the search path when you specify an C. You should use Cconfig-E{root}> to add it. MyApp->config( 'Plugin::Static::Simple' => { include_path => [ '/path/to/overlay', \&incpath_generator, MyApp->config->{root}, ], }, ); With the above setting, a request for the file C will search for the following files, returning the first one found: /path/to/overlay/images/logo.jpg /dynamic/path/images/logo.jpg /your/app/home/root/images/logo.jpg The include path can contain a subroutine reference to dynamically return a list of available directories. This method will receive the C<$c> object as a parameter and should return a reference to a list of directories. Errors can be reported using C. This method will be called every time a file is requested that appears to be a static file (i.e. it has an extension). For example: sub incpath_generator { my $c = shift; if ( $c->session->{customer_dir} ) { return [ $c->session->{customer_dir} ]; } else { die "No customer dir defined."; } } =head2 Ignoring certain types of files There are some file types you may not wish to serve as static files. Most important in this category are your raw template files. By default, files with the extensions C, C, C, C, and C will be ignored by Static::Simple in the interest of security. If you wish to define your own extensions to ignore, use the C option: MyApp->config( 'Plugin::Static::Simple' => { ignore_extensions => [ qw/html asp php/ ], }, ); =head2 Ignoring entire directories To prevent an entire directory from being served statically, you can use the C option. This option contains a list of relative directory paths to ignore. If using C, the path will be checked against every included path. MyApp->config( 'Plugin::Static::Simple' => { ignore_dirs => [ qw/tmpl css/ ], }, ); For example, if combined with the above C setting, this C value will ignore the following directories if they exist: /path/to/overlay/tmpl /path/to/overlay/css /dynamic/path/tmpl /dynamic/path/css /your/app/home/root/tmpl /your/app/home/root/css =head2 Custom MIME types To override or add to the default MIME types set by the L module, you may enter your own extension to MIME type mapping. MyApp->config( 'Plugin::Static::Simple' => { mime_types => { jpg => 'image/jpg', png => 'image/png', }, }, ); =head2 Controlling caching with Expires header The files served by Static::Simple will have a Last-Modified header set, which allows some browsers to cache them for a while. However if you want to explicitly set an Expires header, such as to allow proxies to cache your static content, then you can do so by setting the "expires" config option. The value indicates the number of seconds after access time to allow caching. So a value of zero really means "don't cache at all", and any higher values will keep the file around for that long. MyApp->config( 'Plugin::Static::Simple' => { expires => 3600, # Caching allowed for one hour. }, ); =head2 Compatibility with other plugins Since version 0.12, Static::Simple plays nice with other plugins. It no longer short-circuits the C stage as it was causing too many compatibility issues with other plugins. =head2 Debugging information Enable additional debugging information printed in the Catalyst log. This is automatically enabled when running Catalyst in -Debug mode. MyApp->config( 'Plugin::Static::Simple' => { debug => 1, }, ); =head1 USING WITH APACHE While Static::Simple will work just fine serving files through Catalyst in mod_perl, for increased performance you may wish to have Apache handle the serving of your static files directly. To do this, simply use a dedicated directory for your static files and configure an Apache Location block for that directory This approach is recommended for production installations. SetHandler default-handler Using this approach Apache will bypass any handling of these directories through Catalyst. You can leave Static::Simple as part of your application, and it will continue to function on a development server, or using Catalyst's built-in server. In practice, your Catalyst application is probably (i.e. should be) structured in the recommended way (i.e., that generated by bootstrapping the application with the C script, with a main directory under which is a C directory for module files and a C directory for templates and static files). Thus, unless you break up this structure when deploying your app by moving the static files to a different location in your filesystem, you will need to use an Alias directive in Apache to point to the right place. You will then need to add a Directory block to give permission for Apache to serve these files. The final configuration will look something like this: Alias /myapp/static /filesystem/path/to/MyApp/root/static allow from all SetHandler default-handler If you are running in a VirtualHost, you can just set the DocumentRoot location to the location of your root directory; see L. =head1 PUBLIC METHODS =head2 serve_static_file $file_path Will serve the file located in $file_path statically. This is useful when you need to autogenerate them if they don't exist, or they are stored in a model. package MyApp::Controller::User; sub curr_user_thumb : PathPart("my_thumbnail.png") { my ( $self, $c ) = @_; my $file_path = $c->user->picture_thumbnail_path; $c->serve_static_file($file_path); } =head1 INTERNAL EXTENDED METHODS Static::Simple extends the following steps in the Catalyst process. =head2 prepare_action C is used to first check if the request path is a static file. If so, we skip all other C steps to improve performance. =head2 dispatch C takes the file found during C and writes it to the output. =head2 finalize C serves up final header information and displays any log messages. =head2 setup C initializes all default values. =head1 DEPRECATIONS The old style of configuration using the C<'static'> config key was deprecated in version 0.30. A warning will be issued if this is used, and the contents of the config at this key will be merged with the newer C<'Plugin::Static::Simple'> key. Be aware that if the C<'include_path'> key under C<'static'> exists at all, it will be merged with any content of the same key under C<'Plugin::Static::Simple'>. Be careful not to set this to a non-arrayref, therefore. =head1 SEE ALSO L, L, L =head1 AUTHOR Andy Grundman, =head1 CONTRIBUTORS Marcus Ramberg, Jesse Sheidlower, Guillermo Roditi, Florian Ragwitz, Tomas Doran, Justin Wheeler (dnm) Matt S Trout, Toby Corkindale, =head1 THANKS The authors of Catalyst::Plugin::Static: Sebastian Riedel Christian Hansen Marcus Ramberg For the include_path code from Template Toolkit: Andy Wardley =head1 COPYRIGHT Copyright (c) 2005 - 2011 the Catalyst::Plugin::Static::Simple L and L as listed above. =head1 LICENSE This program is free software, you can redistribute it and/or modify it under the same terms as Perl itself. =cut Catalyst-Plugin-Static-Simple-0.33/inc/Module/000755 000766 000024 00000000000 12424207252 021233 5ustar00johnstaff000000 000000 Catalyst-Plugin-Static-Simple-0.33/inc/Module/AutoInstall.pm000644 000766 000024 00000062254 12424207123 024036 0ustar00johnstaff000000 000000 #line 1 package Module::AutoInstall; use strict; use Cwd (); use File::Spec (); use ExtUtils::MakeMaker (); use vars qw{$VERSION}; BEGIN { $VERSION = '1.12'; } # special map on pre-defined feature sets my %FeatureMap = ( '' => 'Core Features', # XXX: deprecated '-core' => 'Core Features', ); # various lexical flags my ( @Missing, @Existing, %DisabledTests, $UnderCPAN, $InstallDepsTarget, $HasCPANPLUS ); my ( $Config, $CheckOnly, $SkipInstall, $AcceptDefault, $TestOnly, $AllDeps, $UpgradeDeps ); my ( $PostambleActions, $PostambleActionsNoTest, $PostambleActionsUpgradeDeps, $PostambleActionsUpgradeDepsNoTest, $PostambleActionsListDeps, $PostambleActionsListAllDeps, $PostambleUsed, $NoTest); # See if it's a testing or non-interactive session _accept_default( $ENV{AUTOMATED_TESTING} or ! -t STDIN ); _init(); sub _accept_default { $AcceptDefault = shift; } sub _installdeps_target { $InstallDepsTarget = shift; } sub missing_modules { return @Missing; } sub do_install { __PACKAGE__->install( [ $Config ? ( UNIVERSAL::isa( $Config, 'HASH' ) ? %{$Config} : @{$Config} ) : () ], @Missing, ); } # initialize various flags, and/or perform install sub _init { foreach my $arg ( @ARGV, split( /[\s\t]+/, $ENV{PERL_AUTOINSTALL} || $ENV{PERL_EXTUTILS_AUTOINSTALL} || '' ) ) { if ( $arg =~ /^--config=(.*)$/ ) { $Config = [ split( ',', $1 ) ]; } elsif ( $arg =~ /^--installdeps=(.*)$/ ) { __PACKAGE__->install( $Config, @Missing = split( /,/, $1 ) ); exit 0; } elsif ( $arg =~ /^--upgradedeps=(.*)$/ ) { $UpgradeDeps = 1; __PACKAGE__->install( $Config, @Missing = split( /,/, $1 ) ); exit 0; } elsif ( $arg =~ /^--default(?:deps)?$/ ) { $AcceptDefault = 1; } elsif ( $arg =~ /^--check(?:deps)?$/ ) { $CheckOnly = 1; } elsif ( $arg =~ /^--skip(?:deps)?$/ ) { $SkipInstall = 1; } elsif ( $arg =~ /^--test(?:only)?$/ ) { $TestOnly = 1; } elsif ( $arg =~ /^--all(?:deps)?$/ ) { $AllDeps = 1; } } } # overrides MakeMaker's prompt() to automatically accept the default choice sub _prompt { goto &ExtUtils::MakeMaker::prompt unless $AcceptDefault; my ( $prompt, $default ) = @_; my $y = ( $default =~ /^[Yy]/ ); print $prompt, ' [', ( $y ? 'Y' : 'y' ), '/', ( $y ? 'n' : 'N' ), '] '; print "$default\n"; return $default; } # the workhorse sub import { my $class = shift; my @args = @_ or return; my $core_all; print "*** $class version " . $class->VERSION . "\n"; print "*** Checking for Perl dependencies...\n"; my $cwd = Cwd::getcwd(); $Config = []; my $maxlen = length( ( sort { length($b) <=> length($a) } grep { /^[^\-]/ } map { ref($_) ? ( ( ref($_) eq 'HASH' ) ? keys(%$_) : @{$_} ) : '' } map { +{@args}->{$_} } grep { /^[^\-]/ or /^-core$/i } keys %{ +{@args} } )[0] ); # We want to know if we're under CPAN early to avoid prompting, but # if we aren't going to try and install anything anyway then skip the # check entirely since we don't want to have to load (and configure) # an old CPAN just for a cosmetic message $UnderCPAN = _check_lock(1) unless $SkipInstall || $InstallDepsTarget; while ( my ( $feature, $modules ) = splice( @args, 0, 2 ) ) { my ( @required, @tests, @skiptests ); my $default = 1; my $conflict = 0; if ( $feature =~ m/^-(\w+)$/ ) { my $option = lc($1); # check for a newer version of myself _update_to( $modules, @_ ) and return if $option eq 'version'; # sets CPAN configuration options $Config = $modules if $option eq 'config'; # promote every features to core status $core_all = ( $modules =~ /^all$/i ) and next if $option eq 'core'; next unless $option eq 'core'; } print "[" . ( $FeatureMap{ lc($feature) } || $feature ) . "]\n"; $modules = [ %{$modules} ] if UNIVERSAL::isa( $modules, 'HASH' ); unshift @$modules, -default => &{ shift(@$modules) } if ( ref( $modules->[0] ) eq 'CODE' ); # XXX: bugward compatibility while ( my ( $mod, $arg ) = splice( @$modules, 0, 2 ) ) { if ( $mod =~ m/^-(\w+)$/ ) { my $option = lc($1); $default = $arg if ( $option eq 'default' ); $conflict = $arg if ( $option eq 'conflict' ); @tests = @{$arg} if ( $option eq 'tests' ); @skiptests = @{$arg} if ( $option eq 'skiptests' ); next; } printf( "- %-${maxlen}s ...", $mod ); if ( $arg and $arg =~ /^\D/ ) { unshift @$modules, $arg; $arg = 0; } # XXX: check for conflicts and uninstalls(!) them. my $cur = _version_of($mod); if (_version_cmp ($cur, $arg) >= 0) { print "loaded. ($cur" . ( $arg ? " >= $arg" : '' ) . ")\n"; push @Existing, $mod => $arg; $DisabledTests{$_} = 1 for map { glob($_) } @skiptests; } else { if (not defined $cur) # indeed missing { print "missing." . ( $arg ? " (would need $arg)" : '' ) . "\n"; } else { # no need to check $arg as _version_cmp ($cur, undef) would satisfy >= above print "too old. ($cur < $arg)\n"; } push @required, $mod => $arg; } } next unless @required; my $mandatory = ( $feature eq '-core' or $core_all ); if ( !$SkipInstall and ( $CheckOnly or ($mandatory and $UnderCPAN) or $AllDeps or $InstallDepsTarget or _prompt( qq{==> Auto-install the } . ( @required / 2 ) . ( $mandatory ? ' mandatory' : ' optional' ) . qq{ module(s) from CPAN?}, $default ? 'y' : 'n', ) =~ /^[Yy]/ ) ) { push( @Missing, @required ); $DisabledTests{$_} = 1 for map { glob($_) } @skiptests; } elsif ( !$SkipInstall and $default and $mandatory and _prompt( qq{==> The module(s) are mandatory! Really skip?}, 'n', ) =~ /^[Nn]/ ) { push( @Missing, @required ); $DisabledTests{$_} = 1 for map { glob($_) } @skiptests; } else { $DisabledTests{$_} = 1 for map { glob($_) } @tests; } } if ( @Missing and not( $CheckOnly or $UnderCPAN) ) { require Config; my $make = $Config::Config{make}; if ($InstallDepsTarget) { print "*** To install dependencies type '$make installdeps' or '$make installdeps_notest'.\n"; } else { print "*** Dependencies will be installed the next time you type '$make'.\n"; } # make an educated guess of whether we'll need root permission. print " (You may need to do that as the 'root' user.)\n" if eval '$>'; } print "*** $class configuration finished.\n"; chdir $cwd; # import to main:: no strict 'refs'; *{'main::WriteMakefile'} = \&Write if caller(0) eq 'main'; return (@Existing, @Missing); } sub _running_under { my $thing = shift; print <<"END_MESSAGE"; *** Since we're running under ${thing}, I'll just let it take care of the dependency's installation later. END_MESSAGE return 1; } # Check to see if we are currently running under CPAN.pm and/or CPANPLUS; # if we are, then we simply let it taking care of our dependencies sub _check_lock { return unless @Missing or @_; if ($ENV{PERL5_CPANM_IS_RUNNING}) { return _running_under('cpanminus'); } my $cpan_env = $ENV{PERL5_CPAN_IS_RUNNING}; if ($ENV{PERL5_CPANPLUS_IS_RUNNING}) { return _running_under($cpan_env ? 'CPAN' : 'CPANPLUS'); } require CPAN; if ($CPAN::VERSION > '1.89') { if ($cpan_env) { return _running_under('CPAN'); } return; # CPAN.pm new enough, don't need to check further } # last ditch attempt, this -will- configure CPAN, very sorry _load_cpan(1); # force initialize even though it's already loaded # Find the CPAN lock-file my $lock = MM->catfile( $CPAN::Config->{cpan_home}, ".lock" ); return unless -f $lock; # Check the lock local *LOCK; return unless open(LOCK, $lock); if ( ( $^O eq 'MSWin32' ? _under_cpan() : == getppid() ) and ( $CPAN::Config->{prerequisites_policy} || '' ) ne 'ignore' ) { print <<'END_MESSAGE'; *** Since we're running under CPAN, I'll just let it take care of the dependency's installation later. END_MESSAGE return 1; } close LOCK; return; } sub install { my $class = shift; my $i; # used below to strip leading '-' from config keys my @config = ( map { s/^-// if ++$i; $_ } @{ +shift } ); my ( @modules, @installed, @modules_to_upgrade ); while (my ($pkg, $ver) = splice(@_, 0, 2)) { # grep out those already installed if (_version_cmp(_version_of($pkg), $ver) >= 0) { push @installed, $pkg; if ($UpgradeDeps) { push @modules_to_upgrade, $pkg, $ver; } } else { push @modules, $pkg, $ver; } } if ($UpgradeDeps) { push @modules, @modules_to_upgrade; @installed = (); @modules_to_upgrade = (); } return @installed unless @modules; # nothing to do return @installed if _check_lock(); # defer to the CPAN shell print "*** Installing dependencies...\n"; return unless _connected_to('cpan.org'); my %args = @config; my %failed; local *FAILED; if ( $args{do_once} and open( FAILED, '.#autoinstall.failed' ) ) { while () { chomp; $failed{$_}++ } close FAILED; my @newmod; while ( my ( $k, $v ) = splice( @modules, 0, 2 ) ) { push @newmod, ( $k => $v ) unless $failed{$k}; } @modules = @newmod; } if ( _has_cpanplus() and not $ENV{PERL_AUTOINSTALL_PREFER_CPAN} ) { _install_cpanplus( \@modules, \@config ); } else { _install_cpan( \@modules, \@config ); } print "*** $class installation finished.\n"; # see if we have successfully installed them while ( my ( $pkg, $ver ) = splice( @modules, 0, 2 ) ) { if ( _version_cmp( _version_of($pkg), $ver ) >= 0 ) { push @installed, $pkg; } elsif ( $args{do_once} and open( FAILED, '>> .#autoinstall.failed' ) ) { print FAILED "$pkg\n"; } } close FAILED if $args{do_once}; return @installed; } sub _install_cpanplus { my @modules = @{ +shift }; my @config = _cpanplus_config( @{ +shift } ); my $installed = 0; require CPANPLUS::Backend; my $cp = CPANPLUS::Backend->new; my $conf = $cp->configure_object; return unless $conf->can('conf') # 0.05x+ with "sudo" support or _can_write($conf->_get_build('base')); # 0.04x # if we're root, set UNINST=1 to avoid trouble unless user asked for it. my $makeflags = $conf->get_conf('makeflags') || ''; if ( UNIVERSAL::isa( $makeflags, 'HASH' ) ) { # 0.03+ uses a hashref here $makeflags->{UNINST} = 1 unless exists $makeflags->{UNINST}; } else { # 0.02 and below uses a scalar $makeflags = join( ' ', split( ' ', $makeflags ), 'UNINST=1' ) if ( $makeflags !~ /\bUNINST\b/ and eval qq{ $> eq '0' } ); } $conf->set_conf( makeflags => $makeflags ); $conf->set_conf( prereqs => 1 ); while ( my ( $key, $val ) = splice( @config, 0, 2 ) ) { $conf->set_conf( $key, $val ); } my $modtree = $cp->module_tree; while ( my ( $pkg, $ver ) = splice( @modules, 0, 2 ) ) { print "*** Installing $pkg...\n"; MY::preinstall( $pkg, $ver ) or next if defined &MY::preinstall; my $success; my $obj = $modtree->{$pkg}; if ( $obj and _version_cmp( $obj->{version}, $ver ) >= 0 ) { my $pathname = $pkg; $pathname =~ s/::/\\W/; foreach my $inc ( grep { m/$pathname.pm/i } keys(%INC) ) { delete $INC{$inc}; } my $rv = $cp->install( modules => [ $obj->{module} ] ); if ( $rv and ( $rv->{ $obj->{module} } or $rv->{ok} ) ) { print "*** $pkg successfully installed.\n"; $success = 1; } else { print "*** $pkg installation cancelled.\n"; $success = 0; } $installed += $success; } else { print << "."; *** Could not find a version $ver or above for $pkg; skipping. . } MY::postinstall( $pkg, $ver, $success ) if defined &MY::postinstall; } return $installed; } sub _cpanplus_config { my @config = (); while ( @_ ) { my ($key, $value) = (shift(), shift()); if ( $key eq 'prerequisites_policy' ) { if ( $value eq 'follow' ) { $value = CPANPLUS::Internals::Constants::PREREQ_INSTALL(); } elsif ( $value eq 'ask' ) { $value = CPANPLUS::Internals::Constants::PREREQ_ASK(); } elsif ( $value eq 'ignore' ) { $value = CPANPLUS::Internals::Constants::PREREQ_IGNORE(); } else { die "*** Cannot convert option $key = '$value' to CPANPLUS version.\n"; } push @config, 'prereqs', $value; } elsif ( $key eq 'force' ) { push @config, $key, $value; } elsif ( $key eq 'notest' ) { push @config, 'skiptest', $value; } else { die "*** Cannot convert option $key to CPANPLUS version.\n"; } } return @config; } sub _install_cpan { my @modules = @{ +shift }; my @config = @{ +shift }; my $installed = 0; my %args; _load_cpan(); require Config; if (CPAN->VERSION < 1.80) { # no "sudo" support, probe for writableness return unless _can_write( MM->catfile( $CPAN::Config->{cpan_home}, 'sources' ) ) and _can_write( $Config::Config{sitelib} ); } # if we're root, set UNINST=1 to avoid trouble unless user asked for it. my $makeflags = $CPAN::Config->{make_install_arg} || ''; $CPAN::Config->{make_install_arg} = join( ' ', split( ' ', $makeflags ), 'UNINST=1' ) if ( $makeflags !~ /\bUNINST\b/ and eval qq{ $> eq '0' } ); # don't show start-up info $CPAN::Config->{inhibit_startup_message} = 1; # set additional options while ( my ( $opt, $arg ) = splice( @config, 0, 2 ) ) { ( $args{$opt} = $arg, next ) if $opt =~ /^(?:force|notest)$/; # pseudo-option $CPAN::Config->{$opt} = $arg; } if ($args{notest} && (not CPAN::Shell->can('notest'))) { die "Your version of CPAN is too old to support the 'notest' pragma"; } local $CPAN::Config->{prerequisites_policy} = 'follow'; while ( my ( $pkg, $ver ) = splice( @modules, 0, 2 ) ) { MY::preinstall( $pkg, $ver ) or next if defined &MY::preinstall; print "*** Installing $pkg...\n"; my $obj = CPAN::Shell->expand( Module => $pkg ); my $success = 0; if ( $obj and _version_cmp( $obj->cpan_version, $ver ) >= 0 ) { my $pathname = $pkg; $pathname =~ s/::/\\W/; foreach my $inc ( grep { m/$pathname.pm/i } keys(%INC) ) { delete $INC{$inc}; } my $rv = do { if ($args{force}) { CPAN::Shell->force( install => $pkg ) } elsif ($args{notest}) { CPAN::Shell->notest( install => $pkg ) } else { CPAN::Shell->install($pkg) } }; $rv ||= eval { $CPAN::META->instance( 'CPAN::Distribution', $obj->cpan_file, ) ->{install} if $CPAN::META; }; if ( $rv eq 'YES' ) { print "*** $pkg successfully installed.\n"; $success = 1; } else { print "*** $pkg installation failed.\n"; $success = 0; } $installed += $success; } else { print << "."; *** Could not find a version $ver or above for $pkg; skipping. . } MY::postinstall( $pkg, $ver, $success ) if defined &MY::postinstall; } return $installed; } sub _has_cpanplus { return ( $HasCPANPLUS = ( $INC{'CPANPLUS/Config.pm'} or _load('CPANPLUS::Shell::Default') ) ); } # make guesses on whether we're under the CPAN installation directory sub _under_cpan { require Cwd; require File::Spec; my $cwd = File::Spec->canonpath( Cwd::getcwd() ); my $cpan = File::Spec->canonpath( $CPAN::Config->{cpan_home} ); return ( index( $cwd, $cpan ) > -1 ); } sub _update_to { my $class = __PACKAGE__; my $ver = shift; return if _version_cmp( _version_of($class), $ver ) >= 0; # no need to upgrade if ( _prompt( "==> A newer version of $class ($ver) is required. Install?", 'y' ) =~ /^[Nn]/ ) { die "*** Please install $class $ver manually.\n"; } print << "."; *** Trying to fetch it from CPAN... . # install ourselves _load($class) and return $class->import(@_) if $class->install( [], $class, $ver ); print << '.'; exit 1; *** Cannot bootstrap myself. :-( Installation terminated. . } # check if we're connected to some host, using inet_aton sub _connected_to { my $site = shift; return ( ( _load('Socket') and Socket::inet_aton($site) ) or _prompt( qq( *** Your host cannot resolve the domain name '$site', which probably means the Internet connections are unavailable. ==> Should we try to install the required module(s) anyway?), 'n' ) =~ /^[Yy]/ ); } # check if a directory is writable; may create it on demand sub _can_write { my $path = shift; mkdir( $path, 0755 ) unless -e $path; return 1 if -w $path; print << "."; *** You are not allowed to write to the directory '$path'; the installation may fail due to insufficient permissions. . if ( eval '$>' and lc(`sudo -V`) =~ /version/ and _prompt( qq( ==> Should we try to re-execute the autoinstall process with 'sudo'?), ((-t STDIN) ? 'y' : 'n') ) =~ /^[Yy]/ ) { # try to bootstrap ourselves from sudo print << "."; *** Trying to re-execute the autoinstall process with 'sudo'... . my $missing = join( ',', @Missing ); my $config = join( ',', UNIVERSAL::isa( $Config, 'HASH' ) ? %{$Config} : @{$Config} ) if $Config; return unless system( 'sudo', $^X, $0, "--config=$config", "--installdeps=$missing" ); print << "."; *** The 'sudo' command exited with error! Resuming... . } return _prompt( qq( ==> Should we try to install the required module(s) anyway?), 'n' ) =~ /^[Yy]/; } # load a module and return the version it reports sub _load { my $mod = pop; # method/function doesn't matter my $file = $mod; $file =~ s|::|/|g; $file .= '.pm'; local $@; return eval { require $file; $mod->VERSION } || ( $@ ? undef: 0 ); } # report version without loading a module sub _version_of { my $mod = pop; # method/function doesn't matter my $file = $mod; $file =~ s|::|/|g; $file .= '.pm'; foreach my $dir ( @INC ) { next if ref $dir; my $path = File::Spec->catfile($dir, $file); next unless -e $path; require ExtUtils::MM_Unix; return ExtUtils::MM_Unix->parse_version($path); } return undef; } # Load CPAN.pm and it's configuration sub _load_cpan { return if $CPAN::VERSION and $CPAN::Config and not @_; require CPAN; # CPAN-1.82+ adds CPAN::Config::AUTOLOAD to redirect to # CPAN::HandleConfig->load. CPAN reports that the redirection # is deprecated in a warning printed at the user. # CPAN-1.81 expects CPAN::HandleConfig->load, does not have # $CPAN::HandleConfig::VERSION but cannot handle # CPAN::Config->load # Which "versions expect CPAN::Config->load? if ( $CPAN::HandleConfig::VERSION || CPAN::HandleConfig->can('load') ) { # Newer versions of CPAN have a HandleConfig module CPAN::HandleConfig->load; } else { # Older versions had the load method in Config directly CPAN::Config->load; } } # compare two versions, either use Sort::Versions or plain comparison # return values same as <=> sub _version_cmp { my ( $cur, $min ) = @_; return -1 unless defined $cur; # if 0 keep comparing return 1 unless $min; $cur =~ s/\s+$//; # check for version numbers that are not in decimal format if ( ref($cur) or ref($min) or $cur =~ /v|\..*\./ or $min =~ /v|\..*\./ ) { if ( ( $version::VERSION or defined( _load('version') )) and version->can('new') ) { # use version.pm if it is installed. return version->new($cur) <=> version->new($min); } elsif ( $Sort::Versions::VERSION or defined( _load('Sort::Versions') ) ) { # use Sort::Versions as the sorting algorithm for a.b.c versions return Sort::Versions::versioncmp( $cur, $min ); } warn "Cannot reliably compare non-decimal formatted versions.\n" . "Please install version.pm or Sort::Versions.\n"; } # plain comparison local $^W = 0; # shuts off 'not numeric' bugs return $cur <=> $min; } # nothing; this usage is deprecated. sub main::PREREQ_PM { return {}; } sub _make_args { my %args = @_; $args{PREREQ_PM} = { %{ $args{PREREQ_PM} || {} }, @Existing, @Missing } if $UnderCPAN or $TestOnly; if ( $args{EXE_FILES} and -e 'MANIFEST' ) { require ExtUtils::Manifest; my $manifest = ExtUtils::Manifest::maniread('MANIFEST'); $args{EXE_FILES} = [ grep { exists $manifest->{$_} } @{ $args{EXE_FILES} } ]; } $args{test}{TESTS} ||= 't/*.t'; $args{test}{TESTS} = join( ' ', grep { !exists( $DisabledTests{$_} ) } map { glob($_) } split( /\s+/, $args{test}{TESTS} ) ); my $missing = join( ',', @Missing ); my $config = join( ',', UNIVERSAL::isa( $Config, 'HASH' ) ? %{$Config} : @{$Config} ) if $Config; $PostambleActions = ( ($missing and not $UnderCPAN) ? "\$(PERL) $0 --config=$config --installdeps=$missing" : "\$(NOECHO) \$(NOOP)" ); my $deps_list = join( ',', @Missing, @Existing ); $PostambleActionsUpgradeDeps = "\$(PERL) $0 --config=$config --upgradedeps=$deps_list"; my $config_notest = join( ',', (UNIVERSAL::isa( $Config, 'HASH' ) ? %{$Config} : @{$Config}), 'notest', 1 ) if $Config; $PostambleActionsNoTest = ( ($missing and not $UnderCPAN) ? "\$(PERL) $0 --config=$config_notest --installdeps=$missing" : "\$(NOECHO) \$(NOOP)" ); $PostambleActionsUpgradeDepsNoTest = "\$(PERL) $0 --config=$config_notest --upgradedeps=$deps_list"; $PostambleActionsListDeps = '@$(PERL) -le "print for @ARGV" ' . join(' ', map $Missing[$_], grep $_ % 2 == 0, 0..$#Missing); my @all = (@Missing, @Existing); $PostambleActionsListAllDeps = '@$(PERL) -le "print for @ARGV" ' . join(' ', map $all[$_], grep $_ % 2 == 0, 0..$#all); return %args; } # a wrapper to ExtUtils::MakeMaker::WriteMakefile sub Write { require Carp; Carp::croak "WriteMakefile: Need even number of args" if @_ % 2; if ($CheckOnly) { print << "."; *** Makefile not written in check-only mode. . return; } my %args = _make_args(@_); no strict 'refs'; $PostambleUsed = 0; local *MY::postamble = \&postamble unless defined &MY::postamble; ExtUtils::MakeMaker::WriteMakefile(%args); print << "." unless $PostambleUsed; *** WARNING: Makefile written with customized MY::postamble() without including contents from Module::AutoInstall::postamble() -- auto installation features disabled. Please contact the author. . return 1; } sub postamble { $PostambleUsed = 1; my $fragment; $fragment .= <<"AUTO_INSTALL" if !$InstallDepsTarget; config :: installdeps \t\$(NOECHO) \$(NOOP) AUTO_INSTALL $fragment .= <<"END_MAKE"; checkdeps :: \t\$(PERL) $0 --checkdeps installdeps :: \t$PostambleActions installdeps_notest :: \t$PostambleActionsNoTest upgradedeps :: \t$PostambleActionsUpgradeDeps upgradedeps_notest :: \t$PostambleActionsUpgradeDepsNoTest listdeps :: \t$PostambleActionsListDeps listalldeps :: \t$PostambleActionsListAllDeps END_MAKE return $fragment; } 1; __END__ #line 1197 Catalyst-Plugin-Static-Simple-0.33/inc/Module/Install/000755 000766 000024 00000000000 12424207252 022641 5ustar00johnstaff000000 000000 Catalyst-Plugin-Static-Simple-0.33/inc/Module/Install.pm000644 000766 000024 00000030133 12424207123 023174 0ustar00johnstaff000000 000000 #line 1 package Module::Install; # For any maintainers: # The load order for Module::Install is a bit magic. # It goes something like this... # # IF ( host has Module::Install installed, creating author mode ) { # 1. Makefile.PL calls "use inc::Module::Install" # 2. $INC{inc/Module/Install.pm} set to installed version of inc::Module::Install # 3. The installed version of inc::Module::Install loads # 4. inc::Module::Install calls "require Module::Install" # 5. The ./inc/ version of Module::Install loads # } ELSE { # 1. Makefile.PL calls "use inc::Module::Install" # 2. $INC{inc/Module/Install.pm} set to ./inc/ version of Module::Install # 3. The ./inc/ version of Module::Install loads # } use 5.006; use strict 'vars'; use Cwd (); use File::Find (); use File::Path (); use vars qw{$VERSION $MAIN}; BEGIN { # All Module::Install core packages now require synchronised versions. # This will be used to ensure we don't accidentally load old or # different versions of modules. # This is not enforced yet, but will be some time in the next few # releases once we can make sure it won't clash with custom # Module::Install extensions. $VERSION = '1.12'; # Storage for the pseudo-singleton $MAIN = undef; *inc::Module::Install::VERSION = *VERSION; @inc::Module::Install::ISA = __PACKAGE__; } sub import { my $class = shift; my $self = $class->new(@_); my $who = $self->_caller; #------------------------------------------------------------- # all of the following checks should be included in import(), # to allow "eval 'require Module::Install; 1' to test # installation of Module::Install. (RT #51267) #------------------------------------------------------------- # Whether or not inc::Module::Install is actually loaded, the # $INC{inc/Module/Install.pm} is what will still get set as long as # the caller loaded module this in the documented manner. # If not set, the caller may NOT have loaded the bundled version, and thus # they may not have a MI version that works with the Makefile.PL. This would # result in false errors or unexpected behaviour. And we don't want that. my $file = join( '/', 'inc', split /::/, __PACKAGE__ ) . '.pm'; unless ( $INC{$file} ) { die <<"END_DIE" } Please invoke ${\__PACKAGE__} with: use inc::${\__PACKAGE__}; not: use ${\__PACKAGE__}; END_DIE # This reportedly fixes a rare Win32 UTC file time issue, but # as this is a non-cross-platform XS module not in the core, # we shouldn't really depend on it. See RT #24194 for detail. # (Also, this module only supports Perl 5.6 and above). eval "use Win32::UTCFileTime" if $^O eq 'MSWin32' && $] >= 5.006; # If the script that is loading Module::Install is from the future, # then make will detect this and cause it to re-run over and over # again. This is bad. Rather than taking action to touch it (which # is unreliable on some platforms and requires write permissions) # for now we should catch this and refuse to run. if ( -f $0 ) { my $s = (stat($0))[9]; # If the modification time is only slightly in the future, # sleep briefly to remove the problem. my $a = $s - time; if ( $a > 0 and $a < 5 ) { sleep 5 } # Too far in the future, throw an error. my $t = time; if ( $s > $t ) { die <<"END_DIE" } Your installer $0 has a modification time in the future ($s > $t). This is known to create infinite loops in make. Please correct this, then run $0 again. END_DIE } # Build.PL was formerly supported, but no longer is due to excessive # difficulty in implementing every single feature twice. if ( $0 =~ /Build.PL$/i ) { die <<"END_DIE" } Module::Install no longer supports Build.PL. It was impossible to maintain duel backends, and has been deprecated. Please remove all Build.PL files and only use the Makefile.PL installer. END_DIE #------------------------------------------------------------- # To save some more typing in Module::Install installers, every... # use inc::Module::Install # ...also acts as an implicit use strict. $^H |= strict::bits(qw(refs subs vars)); #------------------------------------------------------------- unless ( -f $self->{file} ) { foreach my $key (keys %INC) { delete $INC{$key} if $key =~ /Module\/Install/; } local $^W; require "$self->{path}/$self->{dispatch}.pm"; File::Path::mkpath("$self->{prefix}/$self->{author}"); $self->{admin} = "$self->{name}::$self->{dispatch}"->new( _top => $self ); $self->{admin}->init; @_ = ($class, _self => $self); goto &{"$self->{name}::import"}; } local $^W; *{"${who}::AUTOLOAD"} = $self->autoload; $self->preload; # Unregister loader and worker packages so subdirs can use them again delete $INC{'inc/Module/Install.pm'}; delete $INC{'Module/Install.pm'}; # Save to the singleton $MAIN = $self; return 1; } sub autoload { my $self = shift; my $who = $self->_caller; my $cwd = Cwd::getcwd(); my $sym = "${who}::AUTOLOAD"; $sym->{$cwd} = sub { my $pwd = Cwd::getcwd(); if ( my $code = $sym->{$pwd} ) { # Delegate back to parent dirs goto &$code unless $cwd eq $pwd; } unless ($$sym =~ s/([^:]+)$//) { # XXX: it looks like we can't retrieve the missing function # via $$sym (usually $main::AUTOLOAD) in this case. # I'm still wondering if we should slurp Makefile.PL to # get some context or not ... my ($package, $file, $line) = caller; die <<"EOT"; Unknown function is found at $file line $line. Execution of $file aborted due to runtime errors. If you're a contributor to a project, you may need to install some Module::Install extensions from CPAN (or other repository). If you're a user of a module, please contact the author. EOT } my $method = $1; if ( uc($method) eq $method ) { # Do nothing return; } elsif ( $method =~ /^_/ and $self->can($method) ) { # Dispatch to the root M:I class return $self->$method(@_); } # Dispatch to the appropriate plugin unshift @_, ( $self, $1 ); goto &{$self->can('call')}; }; } sub preload { my $self = shift; unless ( $self->{extensions} ) { $self->load_extensions( "$self->{prefix}/$self->{path}", $self ); } my @exts = @{$self->{extensions}}; unless ( @exts ) { @exts = $self->{admin}->load_all_extensions; } my %seen; foreach my $obj ( @exts ) { while (my ($method, $glob) = each %{ref($obj) . '::'}) { next unless $obj->can($method); next if $method =~ /^_/; next if $method eq uc($method); $seen{$method}++; } } my $who = $self->_caller; foreach my $name ( sort keys %seen ) { local $^W; *{"${who}::$name"} = sub { ${"${who}::AUTOLOAD"} = "${who}::$name"; goto &{"${who}::AUTOLOAD"}; }; } } sub new { my ($class, %args) = @_; delete $INC{'FindBin.pm'}; { # to suppress the redefine warning local $SIG{__WARN__} = sub {}; require FindBin; } # ignore the prefix on extension modules built from top level. my $base_path = Cwd::abs_path($FindBin::Bin); unless ( Cwd::abs_path(Cwd::getcwd()) eq $base_path ) { delete $args{prefix}; } return $args{_self} if $args{_self}; $args{dispatch} ||= 'Admin'; $args{prefix} ||= 'inc'; $args{author} ||= ($^O eq 'VMS' ? '_author' : '.author'); $args{bundle} ||= 'inc/BUNDLES'; $args{base} ||= $base_path; $class =~ s/^\Q$args{prefix}\E:://; $args{name} ||= $class; $args{version} ||= $class->VERSION; unless ( $args{path} ) { $args{path} = $args{name}; $args{path} =~ s!::!/!g; } $args{file} ||= "$args{base}/$args{prefix}/$args{path}.pm"; $args{wrote} = 0; bless( \%args, $class ); } sub call { my ($self, $method) = @_; my $obj = $self->load($method) or return; splice(@_, 0, 2, $obj); goto &{$obj->can($method)}; } sub load { my ($self, $method) = @_; $self->load_extensions( "$self->{prefix}/$self->{path}", $self ) unless $self->{extensions}; foreach my $obj (@{$self->{extensions}}) { return $obj if $obj->can($method); } my $admin = $self->{admin} or die <<"END_DIE"; The '$method' method does not exist in the '$self->{prefix}' path! Please remove the '$self->{prefix}' directory and run $0 again to load it. END_DIE my $obj = $admin->load($method, 1); push @{$self->{extensions}}, $obj; $obj; } sub load_extensions { my ($self, $path, $top) = @_; my $should_reload = 0; unless ( grep { ! ref $_ and lc $_ eq lc $self->{prefix} } @INC ) { unshift @INC, $self->{prefix}; $should_reload = 1; } foreach my $rv ( $self->find_extensions($path) ) { my ($file, $pkg) = @{$rv}; next if $self->{pathnames}{$pkg}; local $@; my $new = eval { local $^W; require $file; $pkg->can('new') }; unless ( $new ) { warn $@ if $@; next; } $self->{pathnames}{$pkg} = $should_reload ? delete $INC{$file} : $INC{$file}; push @{$self->{extensions}}, &{$new}($pkg, _top => $top ); } $self->{extensions} ||= []; } sub find_extensions { my ($self, $path) = @_; my @found; File::Find::find( sub { my $file = $File::Find::name; return unless $file =~ m!^\Q$path\E/(.+)\.pm\Z!is; my $subpath = $1; return if lc($subpath) eq lc($self->{dispatch}); $file = "$self->{path}/$subpath.pm"; my $pkg = "$self->{name}::$subpath"; $pkg =~ s!/!::!g; # If we have a mixed-case package name, assume case has been preserved # correctly. Otherwise, root through the file to locate the case-preserved # version of the package name. if ( $subpath eq lc($subpath) || $subpath eq uc($subpath) ) { my $content = Module::Install::_read($subpath . '.pm'); my $in_pod = 0; foreach ( split /\n/, $content ) { $in_pod = 1 if /^=\w/; $in_pod = 0 if /^=cut/; next if ($in_pod || /^=cut/); # skip pod text next if /^\s*#/; # and comments if ( m/^\s*package\s+($pkg)\s*;/i ) { $pkg = $1; last; } } } push @found, [ $file, $pkg ]; }, $path ) if -d $path; @found; } ##################################################################### # Common Utility Functions sub _caller { my $depth = 0; my $call = caller($depth); while ( $call eq __PACKAGE__ ) { $depth++; $call = caller($depth); } return $call; } # Done in evals to avoid confusing Perl::MinimumVersion eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@; sub _read { local *FH; open( FH, '<', $_[0] ) or die "open($_[0]): $!"; my $string = do { local $/; }; close FH or die "close($_[0]): $!"; return $string; } END_NEW sub _read { local *FH; open( FH, "< $_[0]" ) or die "open($_[0]): $!"; my $string = do { local $/; }; close FH or die "close($_[0]): $!"; return $string; } END_OLD sub _readperl { my $string = Module::Install::_read($_[0]); $string =~ s/(?:\015{1,2}\012|\015|\012)/\n/sg; $string =~ s/(\n)\n*__(?:DATA|END)__\b.*\z/$1/s; $string =~ s/\n\n=\w+.+?\n\n=cut\b.+?\n+/\n\n/sg; return $string; } sub _readpod { my $string = Module::Install::_read($_[0]); $string =~ s/(?:\015{1,2}\012|\015|\012)/\n/sg; return $string if $_[0] =~ /\.pod\z/; $string =~ s/(^|\n=cut\b.+?\n+)[^=\s].+?\n(\n=\w+|\z)/$1$2/sg; $string =~ s/\n*=pod\b[^\n]*\n+/\n\n/sg; $string =~ s/\n*=cut\b[^\n]*\n+/\n\n/sg; $string =~ s/^\n+//s; return $string; } # Done in evals to avoid confusing Perl::MinimumVersion eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@; sub _write { local *FH; open( FH, '>', $_[0] ) or die "open($_[0]): $!"; foreach ( 1 .. $#_ ) { print FH $_[$_] or die "print($_[0]): $!"; } close FH or die "close($_[0]): $!"; } END_NEW sub _write { local *FH; open( FH, "> $_[0]" ) or die "open($_[0]): $!"; foreach ( 1 .. $#_ ) { print FH $_[$_] or die "print($_[0]): $!"; } close FH or die "close($_[0]): $!"; } END_OLD # _version is for processing module versions (eg, 1.03_05) not # Perl versions (eg, 5.8.1). sub _version { my $s = shift || 0; my $d =()= $s =~ /(\.)/g; if ( $d >= 2 ) { # Normalise multipart versions $s =~ s/(\.)(\d{1,3})/sprintf("$1%03d",$2)/eg; } $s =~ s/^(\d+)\.?//; my $l = $1 || 0; my @v = map { $_ . '0' x (3 - length $_) } $s =~ /(\d{1,3})\D?/g; $l = $l . '.' . join '', @v if @v; return $l + 0; } sub _cmp { _version($_[1]) <=> _version($_[2]); } # Cloned from Params::Util::_CLASS sub _CLASS { ( defined $_[0] and ! ref $_[0] and $_[0] =~ m/^[^\W\d]\w*(?:::\w+)*\z/s ) ? $_[0] : undef; } 1; # Copyright 2008 - 2012 Adam Kennedy. Catalyst-Plugin-Static-Simple-0.33/inc/Module/Install/AuthorRequires.pm000644 000766 000024 00000001131 12424207123 026152 0ustar00johnstaff000000 000000 #line 1 use strict; use warnings; package Module::Install::AuthorRequires; use base 'Module::Install::Base'; # cargo cult BEGIN { our $VERSION = '0.02'; our $ISCORE = 1; } sub author_requires { my $self = shift; return $self->{values}->{author_requires} unless @_; my @added; while (@_) { my $mod = shift or last; my $version = shift || 0; push @added, [$mod => $version]; } push @{ $self->{values}->{author_requires} }, @added; $self->admin->author_requires(@added); return map { @$_ } @added; } 1; __END__ #line 92 Catalyst-Plugin-Static-Simple-0.33/inc/Module/Install/AuthorTests.pm000644 000766 000024 00000002215 12424207123 025461 0ustar00johnstaff000000 000000 #line 1 package Module::Install::AuthorTests; use 5.005; use strict; use Module::Install::Base; use Carp (); #line 16 use vars qw{$VERSION $ISCORE @ISA}; BEGIN { $VERSION = '0.002'; $ISCORE = 1; @ISA = qw{Module::Install::Base}; } #line 42 sub author_tests { my ($self, @dirs) = @_; _add_author_tests($self, \@dirs, 0); } #line 56 sub recursive_author_tests { my ($self, @dirs) = @_; _add_author_tests($self, \@dirs, 1); } sub _wanted { my $href = shift; sub { /\.t$/ and -f $_ and $href->{$File::Find::dir} = 1 } } sub _add_author_tests { my ($self, $dirs, $recurse) = @_; return unless $Module::Install::AUTHOR; my @tests = $self->tests ? (split / /, $self->tests) : 't/*.t'; # XXX: pick a default, later -- rjbs, 2008-02-24 my @dirs = @$dirs ? @$dirs : Carp::confess "no dirs given to author_tests"; @dirs = grep { -d } @dirs; if ($recurse) { require File::Find; my %test_dir; File::Find::find(_wanted(\%test_dir), @dirs); $self->tests( join ' ', @tests, map { "$_/*.t" } sort keys %test_dir ); } else { $self->tests( join ' ', @tests, map { "$_/*.t" } sort @dirs ); } } #line 107 1; Catalyst-Plugin-Static-Simple-0.33/inc/Module/Install/AutoInstall.pm000644 000766 000024 00000004162 12424207123 025436 0ustar00johnstaff000000 000000 #line 1 package Module::Install::AutoInstall; use strict; use Module::Install::Base (); use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '1.12'; @ISA = 'Module::Install::Base'; $ISCORE = 1; } sub AutoInstall { $_[0] } sub run { my $self = shift; $self->auto_install_now(@_); } sub write { my $self = shift; $self->auto_install(@_); } sub auto_install { my $self = shift; return if $self->{done}++; # Flatten array of arrays into a single array my @core = map @$_, map @$_, grep ref, $self->build_requires, $self->requires; my @config = @_; # We'll need Module::AutoInstall $self->include('Module::AutoInstall'); require Module::AutoInstall; my @features_require = Module::AutoInstall->import( (@config ? (-config => \@config) : ()), (@core ? (-core => \@core) : ()), $self->features, ); my %seen; my @requires = map @$_, map @$_, grep ref, $self->requires; while (my ($mod, $ver) = splice(@requires, 0, 2)) { $seen{$mod}{$ver}++; } my @build_requires = map @$_, map @$_, grep ref, $self->build_requires; while (my ($mod, $ver) = splice(@build_requires, 0, 2)) { $seen{$mod}{$ver}++; } my @configure_requires = map @$_, map @$_, grep ref, $self->configure_requires; while (my ($mod, $ver) = splice(@configure_requires, 0, 2)) { $seen{$mod}{$ver}++; } my @deduped; while (my ($mod, $ver) = splice(@features_require, 0, 2)) { push @deduped, $mod => $ver unless $seen{$mod}{$ver}++; } $self->requires(@deduped); $self->makemaker_args( Module::AutoInstall::_make_args() ); my $class = ref($self); $self->postamble( "# --- $class section:\n" . Module::AutoInstall::postamble() ); } sub installdeps_target { my ($self, @args) = @_; $self->include('Module::AutoInstall'); require Module::AutoInstall; Module::AutoInstall::_installdeps_target(1); $self->auto_install(@args); } sub auto_install_now { my $self = shift; $self->auto_install(@_); Module::AutoInstall::do_install(); } 1; Catalyst-Plugin-Static-Simple-0.33/inc/Module/Install/Base.pm000644 000766 000024 00000002147 12424207123 024052 0ustar00johnstaff000000 000000 #line 1 package Module::Install::Base; use strict 'vars'; use vars qw{$VERSION}; BEGIN { $VERSION = '1.12'; } # Suspend handler for "redefined" warnings BEGIN { my $w = $SIG{__WARN__}; $SIG{__WARN__} = sub { $w }; } #line 42 sub new { my $class = shift; unless ( defined &{"${class}::call"} ) { *{"${class}::call"} = sub { shift->_top->call(@_) }; } unless ( defined &{"${class}::load"} ) { *{"${class}::load"} = sub { shift->_top->load(@_) }; } bless { @_ }, $class; } #line 61 sub AUTOLOAD { local $@; my $func = eval { shift->_top->autoload } or return; goto &$func; } #line 75 sub _top { $_[0]->{_top}; } #line 90 sub admin { $_[0]->_top->{admin} or Module::Install::Base::FakeAdmin->new; } #line 106 sub is_admin { ! $_[0]->admin->isa('Module::Install::Base::FakeAdmin'); } sub DESTROY {} package Module::Install::Base::FakeAdmin; use vars qw{$VERSION}; BEGIN { $VERSION = $Module::Install::Base::VERSION; } my $fake; sub new { $fake ||= bless(\@_, $_[0]); } sub AUTOLOAD {} sub DESTROY {} # Restore warning handler BEGIN { $SIG{__WARN__} = $SIG{__WARN__}->(); } 1; #line 159 Catalyst-Plugin-Static-Simple-0.33/inc/Module/Install/Can.pm000644 000766 000024 00000006157 12424207123 023706 0ustar00johnstaff000000 000000 #line 1 package Module::Install::Can; use strict; use Config (); use ExtUtils::MakeMaker (); use Module::Install::Base (); use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '1.12'; @ISA = 'Module::Install::Base'; $ISCORE = 1; } # check if we can load some module ### Upgrade this to not have to load the module if possible sub can_use { my ($self, $mod, $ver) = @_; $mod =~ s{::|\\}{/}g; $mod .= '.pm' unless $mod =~ /\.pm$/i; my $pkg = $mod; $pkg =~ s{/}{::}g; $pkg =~ s{\.pm$}{}i; local $@; eval { require $mod; $pkg->VERSION($ver || 0); 1 }; } # Check if we can run some command sub can_run { my ($self, $cmd) = @_; my $_cmd = $cmd; return $_cmd if (-x $_cmd or $_cmd = MM->maybe_command($_cmd)); for my $dir ((split /$Config::Config{path_sep}/, $ENV{PATH}), '.') { next if $dir eq ''; require File::Spec; my $abs = File::Spec->catfile($dir, $cmd); return $abs if (-x $abs or $abs = MM->maybe_command($abs)); } return; } # Can our C compiler environment build XS files sub can_xs { my $self = shift; # Ensure we have the CBuilder module $self->configure_requires( 'ExtUtils::CBuilder' => 0.27 ); # Do we have the configure_requires checker? local $@; eval "require ExtUtils::CBuilder;"; if ( $@ ) { # They don't obey configure_requires, so it is # someone old and delicate. Try to avoid hurting # them by falling back to an older simpler test. return $self->can_cc(); } # Do we have a working C compiler my $builder = ExtUtils::CBuilder->new( quiet => 1, ); unless ( $builder->have_compiler ) { # No working C compiler return 0; } # Write a C file representative of what XS becomes require File::Temp; my ( $FH, $tmpfile ) = File::Temp::tempfile( "compilexs-XXXXX", SUFFIX => '.c', ); binmode $FH; print $FH <<'END_C'; #include "EXTERN.h" #include "perl.h" #include "XSUB.h" int main(int argc, char **argv) { return 0; } int boot_sanexs() { return 1; } END_C close $FH; # Can the C compiler access the same headers XS does my @libs = (); my $object = undef; eval { local $^W = 0; $object = $builder->compile( source => $tmpfile, ); @libs = $builder->link( objects => $object, module_name => 'sanexs', ); }; my $result = $@ ? 0 : 1; # Clean up all the build files foreach ( $tmpfile, $object, @libs ) { next unless defined $_; 1 while unlink; } return $result; } # Can we locate a (the) C compiler sub can_cc { my $self = shift; my @chunks = split(/ /, $Config::Config{cc}) or return; # $Config{cc} may contain args; try to find out the program part while (@chunks) { return $self->can_run("@chunks") || (pop(@chunks), next); } return; } # Fix Cygwin bug on maybe_command(); if ( $^O eq 'cygwin' ) { require ExtUtils::MM_Cygwin; require ExtUtils::MM_Win32; if ( ! defined(&ExtUtils::MM_Cygwin::maybe_command) ) { *ExtUtils::MM_Cygwin::maybe_command = sub { my ($self, $file) = @_; if ($file =~ m{^/cygdrive/}i and ExtUtils::MM_Win32->can('maybe_command')) { ExtUtils::MM_Win32->maybe_command($file); } else { ExtUtils::MM_Unix->maybe_command($file); } } } } 1; __END__ #line 236 Catalyst-Plugin-Static-Simple-0.33/inc/Module/Install/Fetch.pm000644 000766 000024 00000004627 12424207124 024237 0ustar00johnstaff000000 000000 #line 1 package Module::Install::Fetch; use strict; use Module::Install::Base (); use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '1.12'; @ISA = 'Module::Install::Base'; $ISCORE = 1; } sub get_file { my ($self, %args) = @_; my ($scheme, $host, $path, $file) = $args{url} =~ m|^(\w+)://([^/]+)(.+)/(.+)| or return; if ( $scheme eq 'http' and ! eval { require LWP::Simple; 1 } ) { $args{url} = $args{ftp_url} or (warn("LWP support unavailable!\n"), return); ($scheme, $host, $path, $file) = $args{url} =~ m|^(\w+)://([^/]+)(.+)/(.+)| or return; } $|++; print "Fetching '$file' from $host... "; unless (eval { require Socket; Socket::inet_aton($host) }) { warn "'$host' resolve failed!\n"; return; } return unless $scheme eq 'ftp' or $scheme eq 'http'; require Cwd; my $dir = Cwd::getcwd(); chdir $args{local_dir} or return if exists $args{local_dir}; if (eval { require LWP::Simple; 1 }) { LWP::Simple::mirror($args{url}, $file); } elsif (eval { require Net::FTP; 1 }) { eval { # use Net::FTP to get past firewall my $ftp = Net::FTP->new($host, Passive => 1, Timeout => 600); $ftp->login("anonymous", 'anonymous@example.com'); $ftp->cwd($path); $ftp->binary; $ftp->get($file) or (warn("$!\n"), return); $ftp->quit; } } elsif (my $ftp = $self->can_run('ftp')) { eval { # no Net::FTP, fallback to ftp.exe require FileHandle; my $fh = FileHandle->new; local $SIG{CHLD} = 'IGNORE'; unless ($fh->open("|$ftp -n")) { warn "Couldn't open ftp: $!\n"; chdir $dir; return; } my @dialog = split(/\n/, <<"END_FTP"); open $host user anonymous anonymous\@example.com cd $path binary get $file $file quit END_FTP foreach (@dialog) { $fh->print("$_\n") } $fh->close; } } else { warn "No working 'ftp' program available!\n"; chdir $dir; return; } unless (-f $file) { warn "Fetching failed: $@\n"; chdir $dir; return; } return if exists $args{size} and -s $file != $args{size}; system($args{run}) if exists $args{run}; unlink($file) if $args{remove}; print(((!exists $args{check_for} or -e $args{check_for}) ? "done!" : "failed! ($!)"), "\n"); chdir $dir; return !$?; } 1; Catalyst-Plugin-Static-Simple-0.33/inc/Module/Install/Include.pm000644 000766 000024 00000001015 12424207123 024554 0ustar00johnstaff000000 000000 #line 1 package Module::Install::Include; use strict; use Module::Install::Base (); use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '1.12'; @ISA = 'Module::Install::Base'; $ISCORE = 1; } sub include { shift()->admin->include(@_); } sub include_deps { shift()->admin->include_deps(@_); } sub auto_include { shift()->admin->auto_include(@_); } sub auto_include_deps { shift()->admin->auto_include_deps(@_); } sub auto_include_dependent_dists { shift()->admin->auto_include_dependent_dists(@_); } 1; Catalyst-Plugin-Static-Simple-0.33/inc/Module/Install/Makefile.pm000644 000766 000024 00000027437 12424207123 024726 0ustar00johnstaff000000 000000 #line 1 package Module::Install::Makefile; use strict 'vars'; use ExtUtils::MakeMaker (); use Module::Install::Base (); use Fcntl qw/:flock :seek/; use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '1.12'; @ISA = 'Module::Install::Base'; $ISCORE = 1; } sub Makefile { $_[0] } my %seen = (); sub prompt { shift; # Infinite loop protection my @c = caller(); if ( ++$seen{"$c[1]|$c[2]|$_[0]"} > 3 ) { die "Caught an potential prompt infinite loop ($c[1]|$c[2]|$_[0])"; } # In automated testing or non-interactive session, always use defaults if ( ($ENV{AUTOMATED_TESTING} or -! -t STDIN) and ! $ENV{PERL_MM_USE_DEFAULT} ) { local $ENV{PERL_MM_USE_DEFAULT} = 1; goto &ExtUtils::MakeMaker::prompt; } else { goto &ExtUtils::MakeMaker::prompt; } } # Store a cleaned up version of the MakeMaker version, # since we need to behave differently in a variety of # ways based on the MM version. my $makemaker = eval $ExtUtils::MakeMaker::VERSION; # If we are passed a param, do a "newer than" comparison. # Otherwise, just return the MakeMaker version. sub makemaker { ( @_ < 2 or $makemaker >= eval($_[1]) ) ? $makemaker : 0 } # Ripped from ExtUtils::MakeMaker 6.56, and slightly modified # as we only need to know here whether the attribute is an array # or a hash or something else (which may or may not be appendable). my %makemaker_argtype = ( C => 'ARRAY', CONFIG => 'ARRAY', # CONFIGURE => 'CODE', # ignore DIR => 'ARRAY', DL_FUNCS => 'HASH', DL_VARS => 'ARRAY', EXCLUDE_EXT => 'ARRAY', EXE_FILES => 'ARRAY', FUNCLIST => 'ARRAY', H => 'ARRAY', IMPORTS => 'HASH', INCLUDE_EXT => 'ARRAY', LIBS => 'ARRAY', # ignore '' MAN1PODS => 'HASH', MAN3PODS => 'HASH', META_ADD => 'HASH', META_MERGE => 'HASH', PL_FILES => 'HASH', PM => 'HASH', PMLIBDIRS => 'ARRAY', PMLIBPARENTDIRS => 'ARRAY', PREREQ_PM => 'HASH', CONFIGURE_REQUIRES => 'HASH', SKIP => 'ARRAY', TYPEMAPS => 'ARRAY', XS => 'HASH', # VERSION => ['version',''], # ignore # _KEEP_AFTER_FLUSH => '', clean => 'HASH', depend => 'HASH', dist => 'HASH', dynamic_lib=> 'HASH', linkext => 'HASH', macro => 'HASH', postamble => 'HASH', realclean => 'HASH', test => 'HASH', tool_autosplit => 'HASH', # special cases where you can use makemaker_append CCFLAGS => 'APPENDABLE', DEFINE => 'APPENDABLE', INC => 'APPENDABLE', LDDLFLAGS => 'APPENDABLE', LDFROM => 'APPENDABLE', ); sub makemaker_args { my ($self, %new_args) = @_; my $args = ( $self->{makemaker_args} ||= {} ); foreach my $key (keys %new_args) { if ($makemaker_argtype{$key}) { if ($makemaker_argtype{$key} eq 'ARRAY') { $args->{$key} = [] unless defined $args->{$key}; unless (ref $args->{$key} eq 'ARRAY') { $args->{$key} = [$args->{$key}] } push @{$args->{$key}}, ref $new_args{$key} eq 'ARRAY' ? @{$new_args{$key}} : $new_args{$key}; } elsif ($makemaker_argtype{$key} eq 'HASH') { $args->{$key} = {} unless defined $args->{$key}; foreach my $skey (keys %{ $new_args{$key} }) { $args->{$key}{$skey} = $new_args{$key}{$skey}; } } elsif ($makemaker_argtype{$key} eq 'APPENDABLE') { $self->makemaker_append($key => $new_args{$key}); } } else { if (defined $args->{$key}) { warn qq{MakeMaker attribute "$key" is overriden; use "makemaker_append" to append values\n}; } $args->{$key} = $new_args{$key}; } } return $args; } # For mm args that take multiple space-separated args, # append an argument to the current list. sub makemaker_append { my $self = shift; my $name = shift; my $args = $self->makemaker_args; $args->{$name} = defined $args->{$name} ? join( ' ', $args->{$name}, @_ ) : join( ' ', @_ ); } sub build_subdirs { my $self = shift; my $subdirs = $self->makemaker_args->{DIR} ||= []; for my $subdir (@_) { push @$subdirs, $subdir; } } sub clean_files { my $self = shift; my $clean = $self->makemaker_args->{clean} ||= {}; %$clean = ( %$clean, FILES => join ' ', grep { length $_ } ($clean->{FILES} || (), @_), ); } sub realclean_files { my $self = shift; my $realclean = $self->makemaker_args->{realclean} ||= {}; %$realclean = ( %$realclean, FILES => join ' ', grep { length $_ } ($realclean->{FILES} || (), @_), ); } sub libs { my $self = shift; my $libs = ref $_[0] ? shift : [ shift ]; $self->makemaker_args( LIBS => $libs ); } sub inc { my $self = shift; $self->makemaker_args( INC => shift ); } sub _wanted_t { } sub tests_recursive { my $self = shift; my $dir = shift || 't'; unless ( -d $dir ) { die "tests_recursive dir '$dir' does not exist"; } my %tests = map { $_ => 1 } split / /, ($self->tests || ''); require File::Find; File::Find::find( sub { /\.t$/ and -f $_ and $tests{"$File::Find::dir/*.t"} = 1 }, $dir ); $self->tests( join ' ', sort keys %tests ); } sub write { my $self = shift; die "&Makefile->write() takes no arguments\n" if @_; # Check the current Perl version my $perl_version = $self->perl_version; if ( $perl_version ) { eval "use $perl_version; 1" or die "ERROR: perl: Version $] is installed, " . "but we need version >= $perl_version"; } # Make sure we have a new enough MakeMaker require ExtUtils::MakeMaker; if ( $perl_version and $self->_cmp($perl_version, '5.006') >= 0 ) { # This previous attempted to inherit the version of # ExtUtils::MakeMaker in use by the module author, but this # was found to be untenable as some authors build releases # using future dev versions of EU:MM that nobody else has. # Instead, #toolchain suggests we use 6.59 which is the most # stable version on CPAN at time of writing and is, to quote # ribasushi, "not terminally fucked, > and tested enough". # TODO: We will now need to maintain this over time to push # the version up as new versions are released. $self->build_requires( 'ExtUtils::MakeMaker' => 6.59 ); $self->configure_requires( 'ExtUtils::MakeMaker' => 6.59 ); } else { # Allow legacy-compatibility with 5.005 by depending on the # most recent EU:MM that supported 5.005. $self->build_requires( 'ExtUtils::MakeMaker' => 6.36 ); $self->configure_requires( 'ExtUtils::MakeMaker' => 6.36 ); } # Generate the MakeMaker params my $args = $self->makemaker_args; $args->{DISTNAME} = $self->name; $args->{NAME} = $self->module_name || $self->name; $args->{NAME} =~ s/-/::/g; $args->{VERSION} = $self->version or die <<'EOT'; ERROR: Can't determine distribution version. Please specify it explicitly via 'version' in Makefile.PL, or set a valid $VERSION in a module, and provide its file path via 'version_from' (or 'all_from' if you prefer) in Makefile.PL. EOT if ( $self->tests ) { my @tests = split ' ', $self->tests; my %seen; $args->{test} = { TESTS => (join ' ', grep {!$seen{$_}++} @tests), }; } elsif ( $Module::Install::ExtraTests::use_extratests ) { # Module::Install::ExtraTests doesn't set $self->tests and does its own tests via harness. # So, just ignore our xt tests here. } elsif ( -d 'xt' and ($Module::Install::AUTHOR or $ENV{RELEASE_TESTING}) ) { $args->{test} = { TESTS => join( ' ', map { "$_/*.t" } grep { -d $_ } qw{ t xt } ), }; } if ( $] >= 5.005 ) { $args->{ABSTRACT} = $self->abstract; $args->{AUTHOR} = join ', ', @{$self->author || []}; } if ( $self->makemaker(6.10) ) { $args->{NO_META} = 1; #$args->{NO_MYMETA} = 1; } if ( $self->makemaker(6.17) and $self->sign ) { $args->{SIGN} = 1; } unless ( $self->is_admin ) { delete $args->{SIGN}; } if ( $self->makemaker(6.31) and $self->license ) { $args->{LICENSE} = $self->license; } my $prereq = ($args->{PREREQ_PM} ||= {}); %$prereq = ( %$prereq, map { @$_ } # flatten [module => version] map { @$_ } grep $_, ($self->requires) ); # Remove any reference to perl, PREREQ_PM doesn't support it delete $args->{PREREQ_PM}->{perl}; # Merge both kinds of requires into BUILD_REQUIRES my $build_prereq = ($args->{BUILD_REQUIRES} ||= {}); %$build_prereq = ( %$build_prereq, map { @$_ } # flatten [module => version] map { @$_ } grep $_, ($self->configure_requires, $self->build_requires) ); # Remove any reference to perl, BUILD_REQUIRES doesn't support it delete $args->{BUILD_REQUIRES}->{perl}; # Delete bundled dists from prereq_pm, add it to Makefile DIR my $subdirs = ($args->{DIR} || []); if ($self->bundles) { my %processed; foreach my $bundle (@{ $self->bundles }) { my ($mod_name, $dist_dir) = @$bundle; delete $prereq->{$mod_name}; $dist_dir = File::Basename::basename($dist_dir); # dir for building this module if (not exists $processed{$dist_dir}) { if (-d $dist_dir) { # List as sub-directory to be processed by make push @$subdirs, $dist_dir; } # Else do nothing: the module is already present on the system $processed{$dist_dir} = undef; } } } unless ( $self->makemaker('6.55_03') ) { %$prereq = (%$prereq,%$build_prereq); delete $args->{BUILD_REQUIRES}; } if ( my $perl_version = $self->perl_version ) { eval "use $perl_version; 1" or die "ERROR: perl: Version $] is installed, " . "but we need version >= $perl_version"; if ( $self->makemaker(6.48) ) { $args->{MIN_PERL_VERSION} = $perl_version; } } if ($self->installdirs) { warn qq{old INSTALLDIRS (probably set by makemaker_args) is overriden by installdirs\n} if $args->{INSTALLDIRS}; $args->{INSTALLDIRS} = $self->installdirs; } my %args = map { ( $_ => $args->{$_} ) } grep {defined($args->{$_} ) } keys %$args; my $user_preop = delete $args{dist}->{PREOP}; if ( my $preop = $self->admin->preop($user_preop) ) { foreach my $key ( keys %$preop ) { $args{dist}->{$key} = $preop->{$key}; } } my $mm = ExtUtils::MakeMaker::WriteMakefile(%args); $self->fix_up_makefile($mm->{FIRST_MAKEFILE} || 'Makefile'); } sub fix_up_makefile { my $self = shift; my $makefile_name = shift; my $top_class = ref($self->_top) || ''; my $top_version = $self->_top->VERSION || ''; my $preamble = $self->preamble ? "# Preamble by $top_class $top_version\n" . $self->preamble : ''; my $postamble = "# Postamble by $top_class $top_version\n" . ($self->postamble || ''); local *MAKEFILE; open MAKEFILE, "+< $makefile_name" or die "fix_up_makefile: Couldn't open $makefile_name: $!"; eval { flock MAKEFILE, LOCK_EX }; my $makefile = do { local $/; }; $makefile =~ s/\b(test_harness\(\$\(TEST_VERBOSE\), )/$1'inc', /; $makefile =~ s/( -I\$\(INST_ARCHLIB\))/ -Iinc$1/g; $makefile =~ s/( "-I\$\(INST_LIB\)")/ "-Iinc"$1/g; $makefile =~ s/^(FULLPERL = .*)/$1 "-Iinc"/m; $makefile =~ s/^(PERL = .*)/$1 "-Iinc"/m; # Module::Install will never be used to build the Core Perl # Sometimes PERL_LIB and PERL_ARCHLIB get written anyway, which breaks # PREFIX/PERL5LIB, and thus, install_share. Blank them if they exist $makefile =~ s/^PERL_LIB = .+/PERL_LIB =/m; #$makefile =~ s/^PERL_ARCHLIB = .+/PERL_ARCHLIB =/m; # Perl 5.005 mentions PERL_LIB explicitly, so we have to remove that as well. $makefile =~ s/(\"?)-I\$\(PERL_LIB\)\1//g; # XXX - This is currently unused; not sure if it breaks other MM-users # $makefile =~ s/^pm_to_blib\s+:\s+/pm_to_blib :: /mg; seek MAKEFILE, 0, SEEK_SET; truncate MAKEFILE, 0; print MAKEFILE "$preamble$makefile$postamble" or die $!; close MAKEFILE or die $!; 1; } sub preamble { my ($self, $text) = @_; $self->{preamble} = $text . $self->{preamble} if defined $text; $self->{preamble}; } sub postamble { my ($self, $text) = @_; $self->{postamble} ||= $self->admin->postamble; $self->{postamble} .= $text if defined $text; $self->{postamble} } 1; __END__ #line 544 Catalyst-Plugin-Static-Simple-0.33/inc/Module/Install/Metadata.pm000644 000766 000024 00000043302 12424207123 024716 0ustar00johnstaff000000 000000 #line 1 package Module::Install::Metadata; use strict 'vars'; use Module::Install::Base (); use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '1.12'; @ISA = 'Module::Install::Base'; $ISCORE = 1; } my @boolean_keys = qw{ sign }; my @scalar_keys = qw{ name module_name abstract version distribution_type tests installdirs }; my @tuple_keys = qw{ configure_requires build_requires requires recommends bundles resources }; my @resource_keys = qw{ homepage bugtracker repository }; my @array_keys = qw{ keywords author }; *authors = \&author; sub Meta { shift } sub Meta_BooleanKeys { @boolean_keys } sub Meta_ScalarKeys { @scalar_keys } sub Meta_TupleKeys { @tuple_keys } sub Meta_ResourceKeys { @resource_keys } sub Meta_ArrayKeys { @array_keys } foreach my $key ( @boolean_keys ) { *$key = sub { my $self = shift; if ( defined wantarray and not @_ ) { return $self->{values}->{$key}; } $self->{values}->{$key} = ( @_ ? $_[0] : 1 ); return $self; }; } foreach my $key ( @scalar_keys ) { *$key = sub { my $self = shift; return $self->{values}->{$key} if defined wantarray and !@_; $self->{values}->{$key} = shift; return $self; }; } foreach my $key ( @array_keys ) { *$key = sub { my $self = shift; return $self->{values}->{$key} if defined wantarray and !@_; $self->{values}->{$key} ||= []; push @{$self->{values}->{$key}}, @_; return $self; }; } foreach my $key ( @resource_keys ) { *$key = sub { my $self = shift; unless ( @_ ) { return () unless $self->{values}->{resources}; return map { $_->[1] } grep { $_->[0] eq $key } @{ $self->{values}->{resources} }; } return $self->{values}->{resources}->{$key} unless @_; my $uri = shift or die( "Did not provide a value to $key()" ); $self->resources( $key => $uri ); return 1; }; } foreach my $key ( grep { $_ ne "resources" } @tuple_keys) { *$key = sub { my $self = shift; return $self->{values}->{$key} unless @_; my @added; while ( @_ ) { my $module = shift or last; my $version = shift || 0; push @added, [ $module, $version ]; } push @{ $self->{values}->{$key} }, @added; return map {@$_} @added; }; } # Resource handling my %lc_resource = map { $_ => 1 } qw{ homepage license bugtracker repository }; sub resources { my $self = shift; while ( @_ ) { my $name = shift or last; my $value = shift or next; if ( $name eq lc $name and ! $lc_resource{$name} ) { die("Unsupported reserved lowercase resource '$name'"); } $self->{values}->{resources} ||= []; push @{ $self->{values}->{resources} }, [ $name, $value ]; } $self->{values}->{resources}; } # Aliases for build_requires that will have alternative # meanings in some future version of META.yml. sub test_requires { shift->build_requires(@_) } sub install_requires { shift->build_requires(@_) } # Aliases for installdirs options sub install_as_core { $_[0]->installdirs('perl') } sub install_as_cpan { $_[0]->installdirs('site') } sub install_as_site { $_[0]->installdirs('site') } sub install_as_vendor { $_[0]->installdirs('vendor') } sub dynamic_config { my $self = shift; my $value = @_ ? shift : 1; if ( $self->{values}->{dynamic_config} ) { # Once dynamic we never change to static, for safety return 0; } $self->{values}->{dynamic_config} = $value ? 1 : 0; return 1; } # Convenience command sub static_config { shift->dynamic_config(0); } sub perl_version { my $self = shift; return $self->{values}->{perl_version} unless @_; my $version = shift or die( "Did not provide a value to perl_version()" ); # Normalize the version $version = $self->_perl_version($version); # We don't support the really old versions unless ( $version >= 5.005 ) { die "Module::Install only supports 5.005 or newer (use ExtUtils::MakeMaker)\n"; } $self->{values}->{perl_version} = $version; } sub all_from { my ( $self, $file ) = @_; unless ( defined($file) ) { my $name = $self->name or die( "all_from called with no args without setting name() first" ); $file = join('/', 'lib', split(/-/, $name)) . '.pm'; $file =~ s{.*/}{} unless -e $file; unless ( -e $file ) { die("all_from cannot find $file from $name"); } } unless ( -f $file ) { die("The path '$file' does not exist, or is not a file"); } $self->{values}{all_from} = $file; # Some methods pull from POD instead of code. # If there is a matching .pod, use that instead my $pod = $file; $pod =~ s/\.pm$/.pod/i; $pod = $file unless -e $pod; # Pull the different values $self->name_from($file) unless $self->name; $self->version_from($file) unless $self->version; $self->perl_version_from($file) unless $self->perl_version; $self->author_from($pod) unless @{$self->author || []}; $self->license_from($pod) unless $self->license; $self->abstract_from($pod) unless $self->abstract; return 1; } sub provides { my $self = shift; my $provides = ( $self->{values}->{provides} ||= {} ); %$provides = (%$provides, @_) if @_; return $provides; } sub auto_provides { my $self = shift; return $self unless $self->is_admin; unless (-e 'MANIFEST') { warn "Cannot deduce auto_provides without a MANIFEST, skipping\n"; return $self; } # Avoid spurious warnings as we are not checking manifest here. local $SIG{__WARN__} = sub {1}; require ExtUtils::Manifest; local *ExtUtils::Manifest::manicheck = sub { return }; require Module::Build; my $build = Module::Build->new( dist_name => $self->name, dist_version => $self->version, license => $self->license, ); $self->provides( %{ $build->find_dist_packages || {} } ); } sub feature { my $self = shift; my $name = shift; my $features = ( $self->{values}->{features} ||= [] ); my $mods; if ( @_ == 1 and ref( $_[0] ) ) { # The user used ->feature like ->features by passing in the second # argument as a reference. Accomodate for that. $mods = $_[0]; } else { $mods = \@_; } my $count = 0; push @$features, ( $name => [ map { ref($_) ? ( ref($_) eq 'HASH' ) ? %$_ : @$_ : $_ } @$mods ] ); return @$features; } sub features { my $self = shift; while ( my ( $name, $mods ) = splice( @_, 0, 2 ) ) { $self->feature( $name, @$mods ); } return $self->{values}->{features} ? @{ $self->{values}->{features} } : (); } sub no_index { my $self = shift; my $type = shift; push @{ $self->{values}->{no_index}->{$type} }, @_ if $type; return $self->{values}->{no_index}; } sub read { my $self = shift; $self->include_deps( 'YAML::Tiny', 0 ); require YAML::Tiny; my $data = YAML::Tiny::LoadFile('META.yml'); # Call methods explicitly in case user has already set some values. while ( my ( $key, $value ) = each %$data ) { next unless $self->can($key); if ( ref $value eq 'HASH' ) { while ( my ( $module, $version ) = each %$value ) { $self->can($key)->($self, $module => $version ); } } else { $self->can($key)->($self, $value); } } return $self; } sub write { my $self = shift; return $self unless $self->is_admin; $self->admin->write_meta; return $self; } sub version_from { require ExtUtils::MM_Unix; my ( $self, $file ) = @_; $self->version( ExtUtils::MM_Unix->parse_version($file) ); # for version integrity check $self->makemaker_args( VERSION_FROM => $file ); } sub abstract_from { require ExtUtils::MM_Unix; my ( $self, $file ) = @_; $self->abstract( bless( { DISTNAME => $self->name }, 'ExtUtils::MM_Unix' )->parse_abstract($file) ); } # Add both distribution and module name sub name_from { my ($self, $file) = @_; if ( Module::Install::_read($file) =~ m/ ^ \s* package \s* ([\w:]+) [\s|;]* /ixms ) { my ($name, $module_name) = ($1, $1); $name =~ s{::}{-}g; $self->name($name); unless ( $self->module_name ) { $self->module_name($module_name); } } else { die("Cannot determine name from $file\n"); } } sub _extract_perl_version { if ( $_[0] =~ m/ ^\s* (?:use|require) \s* v? ([\d_\.]+) \s* ; /ixms ) { my $perl_version = $1; $perl_version =~ s{_}{}g; return $perl_version; } else { return; } } sub perl_version_from { my $self = shift; my $perl_version=_extract_perl_version(Module::Install::_read($_[0])); if ($perl_version) { $self->perl_version($perl_version); } else { warn "Cannot determine perl version info from $_[0]\n"; return; } } sub author_from { my $self = shift; my $content = Module::Install::_read($_[0]); if ($content =~ m/ =head \d \s+ (?:authors?)\b \s* ([^\n]*) | =head \d \s+ (?:licen[cs]e|licensing|copyright|legal)\b \s* .*? copyright .*? \d\d\d[\d.]+ \s* (?:\bby\b)? \s* ([^\n]*) /ixms) { my $author = $1 || $2; # XXX: ugly but should work anyway... if (eval "require Pod::Escapes; 1") { # Pod::Escapes has a mapping table. # It's in core of perl >= 5.9.3, and should be installed # as one of the Pod::Simple's prereqs, which is a prereq # of Pod::Text 3.x (see also below). $author =~ s{ E<( (\d+) | ([A-Za-z]+) )> } { defined $2 ? chr($2) : defined $Pod::Escapes::Name2character_number{$1} ? chr($Pod::Escapes::Name2character_number{$1}) : do { warn "Unknown escape: E<$1>"; "E<$1>"; }; }gex; } elsif (eval "require Pod::Text; 1" && $Pod::Text::VERSION < 3) { # Pod::Text < 3.0 has yet another mapping table, # though the table name of 2.x and 1.x are different. # (1.x is in core of Perl < 5.6, 2.x is in core of # Perl < 5.9.3) my $mapping = ($Pod::Text::VERSION < 2) ? \%Pod::Text::HTML_Escapes : \%Pod::Text::ESCAPES; $author =~ s{ E<( (\d+) | ([A-Za-z]+) )> } { defined $2 ? chr($2) : defined $mapping->{$1} ? $mapping->{$1} : do { warn "Unknown escape: E<$1>"; "E<$1>"; }; }gex; } else { $author =~ s{E}{<}g; $author =~ s{E}{>}g; } $self->author($author); } else { warn "Cannot determine author info from $_[0]\n"; } } #Stolen from M::B my %license_urls = ( perl => 'http://dev.perl.org/licenses/', apache => 'http://apache.org/licenses/LICENSE-2.0', apache_1_1 => 'http://apache.org/licenses/LICENSE-1.1', artistic => 'http://opensource.org/licenses/artistic-license.php', artistic_2 => 'http://opensource.org/licenses/artistic-license-2.0.php', lgpl => 'http://opensource.org/licenses/lgpl-license.php', lgpl2 => 'http://opensource.org/licenses/lgpl-2.1.php', lgpl3 => 'http://opensource.org/licenses/lgpl-3.0.html', bsd => 'http://opensource.org/licenses/bsd-license.php', gpl => 'http://opensource.org/licenses/gpl-license.php', gpl2 => 'http://opensource.org/licenses/gpl-2.0.php', gpl3 => 'http://opensource.org/licenses/gpl-3.0.html', mit => 'http://opensource.org/licenses/mit-license.php', mozilla => 'http://opensource.org/licenses/mozilla1.1.php', open_source => undef, unrestricted => undef, restrictive => undef, unknown => undef, ); sub license { my $self = shift; return $self->{values}->{license} unless @_; my $license = shift or die( 'Did not provide a value to license()' ); $license = __extract_license($license) || lc $license; $self->{values}->{license} = $license; # Automatically fill in license URLs if ( $license_urls{$license} ) { $self->resources( license => $license_urls{$license} ); } return 1; } sub _extract_license { my $pod = shift; my $matched; return __extract_license( ($matched) = $pod =~ m/ (=head \d \s+ L(?i:ICEN[CS]E|ICENSING)\b.*?) (=head \d.*|=cut.*|)\z /xms ) || __extract_license( ($matched) = $pod =~ m/ (=head \d \s+ (?:C(?i:OPYRIGHTS?)|L(?i:EGAL))\b.*?) (=head \d.*|=cut.*|)\z /xms ); } sub __extract_license { my $license_text = shift or return; my @phrases = ( '(?:under )?the same (?:terms|license) as (?:perl|the perl (?:\d )?programming language)' => 'perl', 1, '(?:under )?the terms of (?:perl|the perl programming language) itself' => 'perl', 1, 'Artistic and GPL' => 'perl', 1, 'GNU general public license' => 'gpl', 1, 'GNU public license' => 'gpl', 1, 'GNU lesser general public license' => 'lgpl', 1, 'GNU lesser public license' => 'lgpl', 1, 'GNU library general public license' => 'lgpl', 1, 'GNU library public license' => 'lgpl', 1, 'GNU Free Documentation license' => 'unrestricted', 1, 'GNU Affero General Public License' => 'open_source', 1, '(?:Free)?BSD license' => 'bsd', 1, 'Artistic license 2\.0' => 'artistic_2', 1, 'Artistic license' => 'artistic', 1, 'Apache (?:Software )?license' => 'apache', 1, 'GPL' => 'gpl', 1, 'LGPL' => 'lgpl', 1, 'BSD' => 'bsd', 1, 'Artistic' => 'artistic', 1, 'MIT' => 'mit', 1, 'Mozilla Public License' => 'mozilla', 1, 'Q Public License' => 'open_source', 1, 'OpenSSL License' => 'unrestricted', 1, 'SSLeay License' => 'unrestricted', 1, 'zlib License' => 'open_source', 1, 'proprietary' => 'proprietary', 0, ); while ( my ($pattern, $license, $osi) = splice(@phrases, 0, 3) ) { $pattern =~ s#\s+#\\s+#gs; if ( $license_text =~ /\b$pattern\b/i ) { return $license; } } return ''; } sub license_from { my $self = shift; if (my $license=_extract_license(Module::Install::_read($_[0]))) { $self->license($license); } else { warn "Cannot determine license info from $_[0]\n"; return 'unknown'; } } sub _extract_bugtracker { my @links = $_[0] =~ m#L<( https?\Q://rt.cpan.org/\E[^>]+| https?\Q://github.com/\E[\w_]+/[\w_]+/issues| https?\Q://code.google.com/p/\E[\w_\-]+/issues/list )>#gx; my %links; @links{@links}=(); @links=keys %links; return @links; } sub bugtracker_from { my $self = shift; my $content = Module::Install::_read($_[0]); my @links = _extract_bugtracker($content); unless ( @links ) { warn "Cannot determine bugtracker info from $_[0]\n"; return 0; } if ( @links > 1 ) { warn "Found more than one bugtracker link in $_[0]\n"; return 0; } # Set the bugtracker bugtracker( $links[0] ); return 1; } sub requires_from { my $self = shift; my $content = Module::Install::_readperl($_[0]); my @requires = $content =~ m/^use\s+([^\W\d]\w*(?:::\w+)*)\s+(v?[\d\.]+)/mg; while ( @requires ) { my $module = shift @requires; my $version = shift @requires; $self->requires( $module => $version ); } } sub test_requires_from { my $self = shift; my $content = Module::Install::_readperl($_[0]); my @requires = $content =~ m/^use\s+([^\W\d]\w*(?:::\w+)*)\s+([\d\.]+)/mg; while ( @requires ) { my $module = shift @requires; my $version = shift @requires; $self->test_requires( $module => $version ); } } # Convert triple-part versions (eg, 5.6.1 or 5.8.9) to # numbers (eg, 5.006001 or 5.008009). # Also, convert double-part versions (eg, 5.8) sub _perl_version { my $v = $_[-1]; $v =~ s/^([1-9])\.([1-9]\d?\d?)$/sprintf("%d.%03d",$1,$2)/e; $v =~ s/^([1-9])\.([1-9]\d?\d?)\.(0|[1-9]\d?\d?)$/sprintf("%d.%03d%03d",$1,$2,$3 || 0)/e; $v =~ s/(\.\d\d\d)000$/$1/; $v =~ s/_.+$//; if ( ref($v) ) { # Numify $v = $v + 0; } return $v; } sub add_metadata { my $self = shift; my %hash = @_; for my $key (keys %hash) { warn "add_metadata: $key is not prefixed with 'x_'.\n" . "Use appopriate function to add non-private metadata.\n" unless $key =~ /^x_/; $self->{values}->{$key} = $hash{$key}; } } ###################################################################### # MYMETA Support sub WriteMyMeta { die "WriteMyMeta has been deprecated"; } sub write_mymeta_yaml { my $self = shift; # We need YAML::Tiny to write the MYMETA.yml file unless ( eval { require YAML::Tiny; 1; } ) { return 1; } # Generate the data my $meta = $self->_write_mymeta_data or return 1; # Save as the MYMETA.yml file print "Writing MYMETA.yml\n"; YAML::Tiny::DumpFile('MYMETA.yml', $meta); } sub write_mymeta_json { my $self = shift; # We need JSON to write the MYMETA.json file unless ( eval { require JSON; 1; } ) { return 1; } # Generate the data my $meta = $self->_write_mymeta_data or return 1; # Save as the MYMETA.yml file print "Writing MYMETA.json\n"; Module::Install::_write( 'MYMETA.json', JSON->new->pretty(1)->canonical->encode($meta), ); } sub _write_mymeta_data { my $self = shift; # If there's no existing META.yml there is nothing we can do return undef unless -f 'META.yml'; # We need Parse::CPAN::Meta to load the file unless ( eval { require Parse::CPAN::Meta; 1; } ) { return undef; } # Merge the perl version into the dependencies my $val = $self->Meta->{values}; my $perl = delete $val->{perl_version}; if ( $perl ) { $val->{requires} ||= []; my $requires = $val->{requires}; # Canonize to three-dot version after Perl 5.6 if ( $perl >= 5.006 ) { $perl =~ s{^(\d+)\.(\d\d\d)(\d*)}{join('.', $1, int($2||0), int($3||0))}e } unshift @$requires, [ perl => $perl ]; } # Load the advisory META.yml file my @yaml = Parse::CPAN::Meta::LoadFile('META.yml'); my $meta = $yaml[0]; # Overwrite the non-configure dependency hashes delete $meta->{requires}; delete $meta->{build_requires}; delete $meta->{recommends}; if ( exists $val->{requires} ) { $meta->{requires} = { map { @$_ } @{ $val->{requires} } }; } if ( exists $val->{build_requires} ) { $meta->{build_requires} = { map { @$_ } @{ $val->{build_requires} } }; } return $meta; } 1; Catalyst-Plugin-Static-Simple-0.33/inc/Module/Install/Win32.pm000644 000766 000024 00000003403 12424207124 024077 0ustar00johnstaff000000 000000 #line 1 package Module::Install::Win32; use strict; use Module::Install::Base (); use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '1.12'; @ISA = 'Module::Install::Base'; $ISCORE = 1; } # determine if the user needs nmake, and download it if needed sub check_nmake { my $self = shift; $self->load('can_run'); $self->load('get_file'); require Config; return unless ( $^O eq 'MSWin32' and $Config::Config{make} and $Config::Config{make} =~ /^nmake\b/i and ! $self->can_run('nmake') ); print "The required 'nmake' executable not found, fetching it...\n"; require File::Basename; my $rv = $self->get_file( url => 'http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/Nmake15.exe', ftp_url => 'ftp://ftp.microsoft.com/Softlib/MSLFILES/Nmake15.exe', local_dir => File::Basename::dirname($^X), size => 51928, run => 'Nmake15.exe /o > nul', check_for => 'Nmake.exe', remove => 1, ); die <<'END_MESSAGE' unless $rv; ------------------------------------------------------------------------------- Since you are using Microsoft Windows, you will need the 'nmake' utility before installation. It's available at: http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/Nmake15.exe or ftp://ftp.microsoft.com/Softlib/MSLFILES/Nmake15.exe Please download the file manually, save it to a directory in %PATH% (e.g. C:\WINDOWS\COMMAND\), then launch the MS-DOS command line shell, "cd" to that directory, and run "Nmake15.exe" from there; that will create the 'nmake.exe' file needed by this module. You may then resume the installation process described in README. ------------------------------------------------------------------------------- END_MESSAGE } 1; Catalyst-Plugin-Static-Simple-0.33/inc/Module/Install/WriteAll.pm000644 000766 000024 00000002376 12424207124 024730 0ustar00johnstaff000000 000000 #line 1 package Module::Install::WriteAll; use strict; use Module::Install::Base (); use vars qw{$VERSION @ISA $ISCORE}; BEGIN { $VERSION = '1.12'; @ISA = qw{Module::Install::Base}; $ISCORE = 1; } sub WriteAll { my $self = shift; my %args = ( meta => 1, sign => 0, inline => 0, check_nmake => 1, @_, ); $self->sign(1) if $args{sign}; $self->admin->WriteAll(%args) if $self->is_admin; $self->check_nmake if $args{check_nmake}; unless ( $self->makemaker_args->{PL_FILES} ) { # XXX: This still may be a bit over-defensive... unless ($self->makemaker(6.25)) { $self->makemaker_args( PL_FILES => {} ) if -f 'Build.PL'; } } # Until ExtUtils::MakeMaker support MYMETA.yml, make sure # we clean it up properly ourself. $self->realclean_files('MYMETA.yml'); if ( $args{inline} ) { $self->Inline->write; } else { $self->Makefile->write; } # The Makefile write process adds a couple of dependencies, # so write the META.yml files after the Makefile. if ( $args{meta} ) { $self->Meta->write; } # Experimental support for MYMETA if ( $ENV{X_MYMETA} ) { if ( $ENV{X_MYMETA} eq 'JSON' ) { $self->Meta->write_mymeta_json; } else { $self->Meta->write_mymeta_yaml; } } return 1; } 1;