Updated PAR support
[catagits/Catalyst-Runtime.git] / lib / Module / Install / Catalyst.pm
1 package Module::Install::Catalyst;
2
3 use strict;
4 use base 'Module::Install::Base';
5 use File::Find;
6 use FindBin;
7 use File::Copy::Recursive 'rcopy';
8 use File::Spec ();
9
10 our @IGNORE =
11   qw/Build Build.PL Changes MANIFEST META.yml Makefile.PL Makefile README
12   _build blib lib script t inc/;
13 our $ENGINE    = 'CGI';
14 our $CORE      = 0;
15 our $MULTIARCH = 0;
16
17 =head1 NAME
18
19 Module::Install::Catalyst - Module::Install extension for Catalyst
20
21 =head1 SYNOPSIS
22
23 See L<Catalyst>
24
25 =head1 DESCRIPTION
26
27 L<Module::Install> extension for Catalyst.
28
29 =head1 METHODS
30
31 =head2 catalyst_files
32
33 =cut
34
35 sub catalyst_files {
36     my $self = shift;
37
38     chdir $FindBin::Bin;
39
40     my @files;
41     opendir CATDIR, '.';
42   CATFILES: for my $name ( readdir CATDIR ) {
43         for my $ignore (@IGNORE) {
44             next CATFILES if $name =~ /^$ignore$/;
45             next CATFILES if $name !~ /\w/;
46         }
47         push @files, $name;
48     }
49     closedir CATDIR;
50     my @path = split '::', $self->name;
51     for my $orig (@files) {
52         my $path = File::Spec->catdir( 'blib', 'lib', @path, $orig );
53         rcopy( $orig, $path );
54     }
55 }
56
57 =head2 catalyst_ignore_all(\@ignore)
58
59 =cut
60
61 sub catalyst_ignore_all {
62     my ( $self, $ignore ) = @_;
63     @IGNORE = @$ignore;
64 }
65
66 =head2 catalyst_ignore(\@ignore)
67
68 =cut
69
70 sub catalyst_ignore {
71     my ( $self, @ignore ) = @_;
72     push @IGNORE, @ignore;
73 }
74
75 =head2 catalyst_par($name)
76
77 =cut
78
79 # Workaround for a namespace conflict
80 sub catalyst_par { Catalyst::Module::Install::_catalyst_par(@_) }
81
82 =head2 catalyst_par_core($core)
83
84 =cut
85
86 sub catalyst_par_core {
87     my ( $self, $core ) = @_;
88     $CORE = $core;
89 }
90
91 =head2 catalyst_par_engine($engine)
92
93 =cut
94
95 sub catalyst_par_engine {
96     my ( $self, $engine ) = @_;
97     $ENGINE = $engine;
98 }
99
100 =head2 catalyst_par_multiarch($multiarch)
101
102 =cut
103
104 sub catalyst_par_multiarch {
105     my ( $self, $multiarch ) = @_;
106     $MULTIARCH = $multiarch;
107 }
108
109 package Catalyst::Module::Install;
110
111 use strict;
112 use FindBin;
113 use File::Copy::Recursive 'rmove';
114 use File::Spec ();
115
116 sub _catalyst_par {
117     my ( $self, $par ) = @_;
118
119     my $name = $self->name;
120     $name =~ s/::/_/g;
121     $name = lc $name;
122     $par ||= "$name.par";
123     my $engine = $Module::Install::Catalyst::ENGINE || 'CGI';
124
125     # Check for PAR
126     eval "use PAR ()";
127     die "Please install PAR" if $@;
128     eval "use PAR::Packer ()";
129     die "Please install PAR::Packer" if $@;
130     eval "use App::Packer::PAR ()";
131     die "Please install App::Packer::PAR" if $@;
132     eval "use Module::ScanDeps ()";
133     die "Please install Module::ScanDeps" if $@;
134
135     my $root = $FindBin::Bin;
136     my $path = File::Spec->catfile( 'blib', 'lib', split( '::', $self->name ) );
137     $path .= '.pm';
138     unless ( -f $path ) {
139         print qq/Not writing PAR, "$path" doesn't exist\n/;
140         return 0;
141     }
142     print qq/Writing PAR "$par"\n/;
143     chdir File::Spec->catdir( $root, 'blib' );
144
145     my $par_pl = 'par.pl';
146     unlink $par_pl;
147
148     my $version = $Catalyst::VERSION;
149     my $class   = $self->name;
150
151     my $tmp_file = IO::File->new(" > $par_pl ");
152     print $tmp_file <<"EOF";
153 die "$class on Catalyst $version\n" if \$0 !~ /par.pl\.\\w+\$/;
154 BEGIN { \$ENV{CATALYST_ENGINE} = '$engine' };
155 use lib "lib";
156 require $class;
157 import $class;
158 require Catalyst::Helper;
159 require Catalyst::Test;
160 require Catalyst::Engine::HTTP;
161 require Catalyst::Engine::CGI;
162 require Catalyst::Controller;
163 require Catalyst::Model;
164 require Catalyst::View;
165 EOF
166     $tmp_file->close;
167
168     # Create package
169     local $SIG{__WARN__} = sub { };
170     open my $olderr, '>&STDERR';
171     open STDERR, '>', File::Spec->devnull;
172     my %opt = (
173         'x' => 1,
174         'n' => 0,
175         'o' => $par,
176         'a' => [ grep( !/par.pl/, glob '.' ) ],
177         'p' => 1,
178         'B' => $Module::Install::Catalyst::CORE,
179         'm' => $Module::Install::Catalyst::MULTIARCH
180     );
181     App::Packer::PAR->new(
182         frontend  => 'Module::ScanDeps',
183         backend   => 'PAR::Packer',
184         frontopts => \%opt,
185         backopts  => \%opt,
186         args      => ['par.pl'],
187     )->go;
188
189     open STDERR, '>&', $olderr;
190
191     unlink $par_pl;
192     chdir $root;
193     rmove( File::Spec->catfile( 'blib', $par ), $par );
194     return 1;
195 }
196
197 =head1 AUTHOR
198
199 Sebastian Riedel, C<sri@oook.de>
200
201 =head1 LICENSE
202
203 This library is free software, you can redistribute it and/or modify it under
204 the same terms as Perl itself.
205
206 =cut
207
208 1;