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