File Coverage

blib/lib/Module/Install/Package.pm
Criterion Covered Total %
statement 17 138 12.3
branch 1 84 1.1
condition 0 19 0.0
subroutine 6 33 18.1
pod 0 4 0.0
total 24 278 8.6


line stmt bran cond sub pod time code
1             ##
2             # name: Module::Install::Package
3             # abstract: Module::Install support for Module::Package
4             # author: Ingy döt Net
5             # license: perl
6             # copyright: 2011
7             # see:
8             # - Module::Package
9              
10             # This module contains the Module::Package logic that must be available to
11             # both the Author and the End User. Author-only logic goes in a
12             # Module::Package::Plugin subclass.
13             package Module::Install::Package;
14 1     1   1617 use strict;
  1         2  
  1         44  
15 1     1   6 use Module::Install::Base;
  1         3  
  1         30  
16 1     1   7 use vars qw'@ISA $VERSION';
  1         2  
  1         1710  
17             @ISA = 'Module::Install::Base';
18             $VERSION = '0.30';
19              
20             #-----------------------------------------------------------------------------#
21             # XXX BOOTBUGHACK
22             # This is here to try to get us out of Module-Package-0.11 cpantesters hell...
23             # Remove this when the situation has blown over.
24             sub pkg {
25 0     0 0   *inc::Module::Package::VERSION = sub { $VERSION };
  0     0      
26 0           my $self = shift;
27 0           $self->module_package_internals_init($@);
28             }
29              
30             #-----------------------------------------------------------------------------#
31             # We allow the author to specify key/value options after the plugin. These
32             # options need to be available both at author time and install time.
33             #-----------------------------------------------------------------------------#
34             # OO accessor for command line options:
35             sub package_options {
36 0 0   0 0   @_>1?($_[0]->{package_options}=$_[1]):$_[0]->{package_options}}
37              
38             my $default_options = {
39             deps_list => 1,
40             install_bin => 1,
41             install_share => 1,
42             manifest_skip => 1,
43             requires_from => 1,
44             };
45              
46             #-----------------------------------------------------------------------------#
47             # Module::Install plugin directives. Use long, ugly names to not pollute the
48             # Module::Install plugin namespace. These are only intended to be called from
49             # Module::Package.
50             #-----------------------------------------------------------------------------#
51              
52             # Module::Package starts off life as a normal call to this Module::Install
53             # plugin directive:
54             my $module_install_plugin;
55             my $module_package_plugin;
56             my $module_package_dist_plugin;
57             # XXX ARGVHACK This @argv thing is a temporary fix for an ugly bug somewhere in the
58             # Wikitext module usage.
59             my @argv;
60             sub module_package_internals_init {
61 0     0 0   my $self = $module_install_plugin = shift;
62 0           my ($plugin_spec, %options) = @_;
63 0           $self->package_options({%$default_options, %options});
64              
65 0 0         if ($module_install_plugin->is_admin) {
66 0           $module_package_plugin = $self->_load_plugin($plugin_spec);
67 0           $module_package_plugin->mi($module_install_plugin);
68 0           $module_package_plugin->version_check($VERSION);
69             }
70             else {
71 0           $module_package_dist_plugin = $self->_load_dist_plugin($plugin_spec);
72 0 0         $module_package_dist_plugin->mi($module_install_plugin) if ref $module_package_dist_plugin;
73             }
74             # NOTE - This is the point in time where the body of Makefile.PL runs...
75 0           return;
76              
77             sub INIT {
78             return unless $module_install_plugin;
79             return if $Module::Package::ERROR;
80             eval {
81             if ($module_install_plugin->is_admin) {
82             $module_package_plugin->initial();
83             $module_package_plugin->main();
84             }
85             else {
86             $module_install_plugin->_initial();
87             $module_package_dist_plugin->_initial() if ref $module_package_dist_plugin;
88             $module_install_plugin->_main();
89             $module_package_dist_plugin->_main() if ref $module_package_dist_plugin;
90             }
91             };
92             if ($@) {
93             $Module::Package::ERROR = $@;
94             die $@;
95             }
96             @argv = @ARGV; # XXX ARGVHACK
97             }
98              
99             # If this Module::Install plugin was used (by Module::Package) then wrap
100             # up any loose ends. This will get called after Makefile.PL has completed.
101             sub END {
102 1     1   1042 @ARGV = @argv; # XXX ARGVHACK
103 1 50       14 return unless $module_install_plugin;
104 0 0         return if $Module::Package::ERROR;
105             $module_package_plugin
106             ? do {
107 0           $module_package_plugin->final;
108 0           $module_package_plugin->replicate_module_package;
109             }
110 0 0         : do {
111 0           $module_install_plugin->_final;
112 0 0         $module_package_dist_plugin->_final() if ref $module_package_dist_plugin;
113             }
114             }
115             }
116              
117             # Module::Package, Module::Install::Package and Module::Package::Plugin
118             # must all have the same version. Seems wise.
119             sub module_package_internals_version_check {
120 0     0 0   my ($self, $version) = @_;
121 0 0         return if $version < 0.1800001; # XXX BOOTBUGHACK!!
122 0 0         die <<"..." unless $version == $VERSION;
123              
124             Error! Something has gone awry:
125             Module::Package version=$version is using
126             Module::Install::Package version=$VERSION
127             If you are the author of this module, try upgrading Module::Package.
128             Otherwise, please notify the author of this error.
129              
130             ...
131             }
132              
133             # Find and load the author side plugin:
134             sub _load_plugin {
135 0     0     my ($self, $spec, $namespace) = @_;
136 0   0       $spec ||= '';
137 0   0       $namespace ||= 'Module::Package';
138 0           my $version = '';
139 0           $Module::Package::plugin_version = 0;
140 0 0         if ($spec =~ s/\s+(\S+)\s*//) {
141 0           $version = $1;
142 0           $Module::Package::plugin_version = $version;
143             }
144 0 0         my ($module, $plugin) =
    0          
    0          
    0          
145             not($spec) ? ('Plugin', "Plugin::basic") :
146             ($spec =~ /^\w(\w|::)*$/) ? ($spec, $spec) :
147             ($spec =~ /^:(\w+)$/) ? ('Plugin', "Plugin::$1") :
148             ($spec =~ /^(\S*\w):(\w+)$/) ? ($1, "$1::$2") :
149             die "$spec is invalid";
150 0           $module = "${namespace}::${module}";
151 0           $plugin = "${namespace}::${plugin}";
152 0 0         eval "use $module $version (); 1" or die $@;
153 0           return $plugin->new();
154             }
155              
156             # Find and load the user side plugin:
157             sub _load_dist_plugin {
158 0     0     my ($self, $spec, $namespace) = @_;
159 0   0       $spec ||= '';
160 0   0       $namespace ||= 'Module::Package::Dist';
161 0           my $r = eval { $self->_load_plugin($spec, $namespace); };
  0            
162 0 0         return $r if ref $r;
163 0           return;
164             }
165              
166             #-----------------------------------------------------------------------------#
167             # These are the user side analogs to the author side plugin API calls.
168             # Prefix with '_' to not pollute Module::Install plugin space.
169             #-----------------------------------------------------------------------------#
170             sub _initial {
171 0     0     my ($self) = @_;
172             }
173              
174             sub _main {
175 0     0     my ($self) = @_;
176             }
177              
178             # NOTE These must match Module::Package::Plugin::final.
179             sub _final {
180 0     0     my ($self) = @_;
181 0           $self->_all_from;
182 0           $self->_requires_from;
183 0           $self->_install_bin;
184 0           $self->_install_share;
185 0           $self->_WriteAll;
186             }
187              
188             #-----------------------------------------------------------------------------#
189             # This section is where all the useful code bits go. These bits are needed by
190             # both Author and User side runs.
191             #-----------------------------------------------------------------------------#
192              
193             my $all_from = 0;
194             sub _all_from {
195 0     0     my $self = shift;
196 0 0         return if $all_from++;
197 0 0         return if $self->name;
198 0 0 0       my $file = shift || "$main::PM" or die "all_from has no file";
199 0           $self->all_from($file);
200             }
201              
202             my $requires_from = 0;
203             sub _requires_from {
204 0     0     my $self = shift;
205 0 0         return if $requires_from++;
206 0 0         return unless $self->package_options->{requires_from};
207 0 0 0       my $file = shift || "$main::PM" or die "requires_from has no file";
208 0           $self->requires_from($main::PM)
209             }
210              
211             my $install_bin = 0;
212             sub _install_bin {
213 0     0     my $self = shift;
214 0 0         return if $install_bin++;
215 0 0         return unless $self->package_options->{install_bin};
216 0 0         return unless -d 'bin';
217 0           my @bin;
218             File::Find::find(sub {
219 0 0   0     return unless -f $_;
220 0           push @bin, $File::Find::name;
221 0           }, 'bin');
222 0           $self->install_script($_) for @bin;
223             }
224              
225             my $install_share = 0;
226             sub _install_share {
227 0     0     my $self = shift;
228 0 0         return if $install_share++;
229 0 0         return unless $self->package_options->{install_share};
230 0 0         return unless -d 'share';
231 0           $self->install_share;
232             }
233              
234             my $WriteAll = 0;
235             sub _WriteAll {
236 0     0     my $self = shift;
237 0 0         return if $WriteAll++;
238 0           $self->WriteAll(@_);
239             }
240              
241             # Base package for Module::Package plugin distributed components.
242             package Module::Package::Dist;
243              
244             sub new {
245 0     0     my ($class, %args) = @_;
246 0           bless \%args, $class;
247             }
248              
249             sub mi {
250 0 0   0     @_ > 1 ? ($_[0]->{mi}=$_[1]) : $_[0]->{mi};
251             }
252              
253             sub _initial {
254 0     0     my ($self) = @_;
255             }
256              
257             sub _main {
258 0     0     my ($self) = @_;
259             }
260              
261             sub _final {
262 0     0     my ($self) = @_;
263             }
264              
265             1;
266              
267             #-----------------------------------------------------------------------------#
268             # Take a guess at the primary .pm and .pod files for 'all_from', and friends.
269             # Put them in global magical vars in the main:: namespace.
270             #-----------------------------------------------------------------------------#
271             package Module::Package::PM;
272             use overload '""' => sub {
273 0 0   0   0 $_[0]->guess_pm unless @{$_[0]};
  0         0  
274 0         0 return $_[0]->[0];
275 1     1   8 };
  1         2  
  1         13  
276 0     0     sub set { $_[0]->[0] = $_[1] }
277             sub guess_pm {
278 0     0     my $pm = '';
279 0           my $self = shift;
280 0 0         if (-e 'META.yml') {
281 0 0         open META, 'META.yml' or die "Can't open 'META.yml' for input:\n$!";
282 0           my $meta = do { local $/; };
  0            
  0            
283 0           close META;
284 0 0         $meta =~ /^module_name: (\S+)$/m
285             or die "Can't get module_name from META.yml";
286 0           $pm = $1;
287 0           $pm =~ s!::!/!g;
288 0           $pm = "lib/$pm.pm";
289             }
290             else {
291 0           require File::Find;
292 0           my @array = ();
293             File::Find::find(sub {
294 0 0   0     return unless /\.pm$/;
295 0           my $name = $File::Find::name;
296 0           my $num = ($name =~ s!/+!/!g);
297 0   0       my $ary = $array[$num] ||= [];
298 0           push @$ary, $name;
299 0           }, 'lib');
300 0   0       shift @array while @array and not defined $array[0];
301 0 0         die "Can't guess main module" unless @array;
302 0 0         (($pm) = sort @{$array[0]}) or
  0            
303             die "Can't guess main module";
304             }
305 0           my $pmc = $pm . 'c';
306 0 0         $pm = $pmc if -e $pmc;
307 0           $self->set($pm);
308             }
309             $main::PM = bless [$main::PM ? ($main::PM) : ()], __PACKAGE__;
310              
311             package Module::Package::POD;
312             use overload '""' => sub {
313 0 0   0   0 return $_[0]->[0] if @{$_[0]};
  0         0  
314 0 0       0 (my $pod = "$main::PM") =~ s/\.pm/.pod/
315             or die "Module::Package's \$main::PM value should end in '.pm'";
316 0 0       0 return -e $pod ? $pod : '';
317 1     1   538 };
  1         4  
  1         15  
318 0     0     sub set { $_[0][0] = $_[1] }
319             $main::POD = bless [$main::POD ? ($main::POD) : ()], __PACKAGE__;
320              
321             1;
322              
323             =head1 SYNOPSIS
324              
325             use inc::Module::Package ;
326              
327             =head1 DESCRIPTION
328              
329             This Module::Install plugin provides user-side support for L.