File Coverage

inc/Module/Install.pm
Criterion Covered Total %
statement 22 233 9.4
branch 0 100 0.0
condition 0 45 0.0
subroutine 7 27 25.9
pod 0 7 0.0
total 29 412 7.0


line stmt bran cond sub pod time code
1             #line 1
2             package Module::Install;
3              
4             # For any maintainers:
5             # The load order for Module::Install is a bit magic.
6             # It goes something like this...
7             #
8             # IF ( host has Module::Install installed, creating author mode ) {
9             # 1. Makefile.PL calls "use inc::Module::Install"
10             # 2. $INC{inc/Module/Install.pm} set to installed version of inc::Module::Install
11             # 3. The installed version of inc::Module::Install loads
12             # 4. inc::Module::Install calls "require Module::Install"
13             # 5. The ./inc/ version of Module::Install loads
14             # } ELSE {
15             # 1. Makefile.PL calls "use inc::Module::Install"
16             # 2. $INC{inc/Module/Install.pm} set to ./inc/ version of Module::Install
17             # 3. The ./inc/ version of Module::Install loads
18             # }
19 1     1   28  
  1         3  
  1         45  
20 1     1   5 use 5.005;
  1         3  
  1         27  
21 1     1   6 use strict 'vars';
  1         1  
  1         24  
22 1     1   6 use Cwd ();
  1         2  
  1         26  
23 1     1   6 use File::Find ();
  1         2  
  1         22  
24             use File::Path ();
25 1     1   5  
  1         2  
  1         110  
26             use vars qw{$VERSION $MAIN};
27             BEGIN {
28             # All Module::Install core packages now require synchronised versions.
29             # This will be used to ensure we don't accidentally load old or
30             # different versions of modules.
31             # This is not enforced yet, but will be some time in the next few
32             # releases once we can make sure it won't clash with custom
33 1     1   2 # Module::Install extensions.
34             $VERSION = '1.01';
35              
36 1         2 # Storage for the pseudo-singleton
37             $MAIN = undef;
38 1         3  
39 1         3272 *inc::Module::Install::VERSION = *VERSION;
40             @inc::Module::Install::ISA = __PACKAGE__;
41              
42             }
43              
44 0     0     sub import {
45 0           my $class = shift;
46 0           my $self = $class->new(@_);
47             my $who = $self->_caller;
48              
49             #-------------------------------------------------------------
50             # all of the following checks should be included in import(),
51             # to allow "eval 'require Module::Install; 1' to test
52             # installation of Module::Install. (RT #51267)
53             #-------------------------------------------------------------
54              
55             # Whether or not inc::Module::Install is actually loaded, the
56             # $INC{inc/Module/Install.pm} is what will still get set as long as
57             # the caller loaded module this in the documented manner.
58             # If not set, the caller may NOT have loaded the bundled version, and thus
59             # they may not have a MI version that works with the Makefile.PL. This would
60 0           # result in false errors or unexpected behaviour. And we don't want that.
61 0 0         my $file = join( '/', 'inc', split /::/, __PACKAGE__ ) . '.pm';
  0            
62             unless ( $INC{$file} ) { die <<"END_DIE" }
63 0            
  0            
64             Please invoke ${\__PACKAGE__} with:
65 0            
66             use inc::${\__PACKAGE__};
67              
68             not:
69              
70             use ${\__PACKAGE__};
71              
72             END_DIE
73              
74             # This reportedly fixes a rare Win32 UTC file time issue, but
75             # as this is a non-cross-platform XS module not in the core,
76             # we shouldn't really depend on it. See RT #24194 for detail.
77 0 0 0       # (Also, this module only supports Perl 5.6 and above).
78             eval "use Win32::UTCFileTime" if $^O eq 'MSWin32' && $] >= 5.006;
79              
80             # If the script that is loading Module::Install is from the future,
81             # then make will detect this and cause it to re-run over and over
82             # again. This is bad. Rather than taking action to touch it (which
83             # is unreliable on some platforms and requires write permissions)
84 0 0         # for now we should catch this and refuse to run.
85 0           if ( -f $0 ) {
86             my $s = (stat($0))[9];
87              
88             # If the modification time is only slightly in the future,
89 0           # sleep briefly to remove the problem.
90 0 0 0       my $a = $s - time;
  0            
91             if ( $a > 0 and $a < 5 ) { sleep 5 }
92              
93 0           # Too far in the future, throw an error.
94 0 0         my $t = time;
  0            
95             if ( $s > $t ) { die <<"END_DIE" }
96              
97             Your installer $0 has a modification time in the future ($s > $t).
98              
99             This is known to create infinite loops in make.
100              
101             Please correct this, then run $0 again.
102              
103             END_DIE
104             }
105              
106              
107             # Build.PL was formerly supported, but no longer is due to excessive
108 0 0         # difficulty in implementing every single feature twice.
  0            
109             if ( $0 =~ /Build.PL$/i ) { die <<"END_DIE" }
110              
111             Module::Install no longer supports Build.PL.
112              
113             It was impossible to maintain duel backends, and has been deprecated.
114              
115             Please remove all Build.PL files and only use the Makefile.PL installer.
116              
117             END_DIE
118              
119             #-------------------------------------------------------------
120              
121             # To save some more typing in Module::Install installers, every...
122             # use inc::Module::Install
123 0           # ...also acts as an implicit use strict.
124             $^H |= strict::bits(qw(refs subs vars));
125              
126             #-------------------------------------------------------------
127 0 0          
128 0           unless ( -f $self->{file} ) {
129 0 0         foreach my $key (keys %INC) {
130             delete $INC{$key} if $key =~ /Module\/Install/;
131             }
132 0            
133 0           local $^W;
134 0           require "$self->{path}/$self->{dispatch}.pm";
135 0           File::Path::mkpath("$self->{prefix}/$self->{author}");
136 0           $self->{admin} = "$self->{name}::$self->{dispatch}"->new( _top => $self );
137 0           $self->{admin}->init;
138 0           @_ = ($class, _self => $self);
  0            
139             goto &{"$self->{name}::import"};
140             }
141 0            
142 0           local $^W;
  0            
143 0           *{"${who}::AUTOLOAD"} = $self->autoload;
144             $self->preload;
145              
146 0           # Unregister loader and worker packages so subdirs can use them again
147 0           delete $INC{'inc/Module/Install.pm'};
148             delete $INC{'Module/Install.pm'};
149              
150 0           # Save to the singleton
151             $MAIN = $self;
152 0            
153             return 1;
154             }
155              
156 0     0 0   sub autoload {
157 0           my $self = shift;
158 0           my $who = $self->_caller;
159 0           my $cwd = Cwd::cwd();
160             my $sym = "${who}::AUTOLOAD";
161 0     0     $sym->{$cwd} = sub {
162 0 0         my $pwd = Cwd::cwd();
163             if ( my $code = $sym->{$pwd} ) {
164 0 0         # Delegate back to parent dirs
165             goto &$code unless $cwd eq $pwd;
166 0 0         }
167             unless ($$sym =~ s/([^:]+)$//) {
168             # XXX: it looks like we can't retrieve the missing function
169             # via $$sym (usually $main::AUTOLOAD) in this case.
170             # I'm still wondering if we should slurp Makefile.PL to
171 0           # get some context or not ...
172 0           my ($package, $file, $line) = caller;
173             die <<"EOT";
174             Unknown function is found at $file line $line.
175             Execution of $file aborted due to runtime errors.
176              
177             If you're a contributor to a project, you may need to install
178             some Module::Install extensions from CPAN (or other repository).
179             If you're a user of a module, please contact the author.
180             EOT
181 0           }
182 0 0 0       my $method = $1;
    0          
183             if ( uc($method) eq $method ) {
184 0           # Do nothing
185             return;
186             } elsif ( $method =~ /^_/ and $self->can($method) ) {
187 0           # Dispatch to the root M:I class
188             return $self->$method(@_);
189             }
190              
191 0           # Dispatch to the appropriate plugin
192 0           unshift @_, ( $self, $1 );
  0            
193 0           goto &{$self->can('call')};
194             };
195             }
196              
197 0     0 0   sub preload {
198 0 0         my $self = shift;
199 0           unless ( $self->{extensions} ) {
200             $self->load_extensions(
201             "$self->{prefix}/$self->{path}", $self
202             );
203             }
204 0            
  0            
205 0 0         my @exts = @{$self->{extensions}};
206 0           unless ( @exts ) {
207             @exts = $self->{admin}->load_all_extensions;
208             }
209 0            
210 0           my %seen;
211 0           foreach my $obj ( @exts ) {
  0            
212 0 0         while (my ($method, $glob) = each %{ref($obj) . '::'}) {
213 0 0         next unless $obj->can($method);
214 0 0         next if $method =~ /^_/;
215 0           next if $method eq uc($method);
216             $seen{$method}++;
217             }
218             }
219 0            
220 0           my $who = $self->_caller;
221 0           foreach my $name ( sort keys %seen ) {
222 0           local $^W;
223 0     0     *{"${who}::$name"} = sub {
  0            
224 0           ${"${who}::AUTOLOAD"} = "${who}::$name";
  0            
225 0           goto &{"${who}::AUTOLOAD"};
226             };
227             }
228             }
229              
230 0     0 0   sub new {
231             my ($class, %args) = @_;
232 0            
233             delete $INC{'FindBin.pm'};
234             {
235 0     0     # to suppress the redefine warning
  0            
  0            
236 0           local $SIG{__WARN__} = sub {};
237             require FindBin;
238             }
239              
240 0           # ignore the prefix on extension modules built from top level.
241 0 0         my $base_path = Cwd::abs_path($FindBin::Bin);
242 0           unless ( Cwd::abs_path(Cwd::cwd()) eq $base_path ) {
243             delete $args{prefix};
244 0 0         }
245             return $args{_self} if $args{_self};
246 0   0        
247 0   0       $args{dispatch} ||= 'Admin';
248 0 0 0       $args{prefix} ||= 'inc';
249 0   0       $args{author} ||= ($^O eq 'VMS' ? '_author' : '.author');
250 0   0       $args{bundle} ||= 'inc/BUNDLES';
251 0           $args{base} ||= $base_path;
252 0   0       $class =~ s/^\Q$args{prefix}\E:://;
253 0   0       $args{name} ||= $class;
254 0 0         $args{version} ||= $class->VERSION;
255 0           unless ( $args{path} ) {
256 0           $args{path} = $args{name};
257             $args{path} =~ s!::!/!g;
258 0   0       }
259 0           $args{file} ||= "$args{base}/$args{prefix}/$args{path}.pm";
260             $args{wrote} = 0;
261 0            
262             bless( \%args, $class );
263             }
264              
265 0     0 0   sub call {
266 0 0         my ($self, $method) = @_;
267 0           my $obj = $self->load($method) or return;
268 0           splice(@_, 0, 2, $obj);
  0            
269             goto &{$obj->can($method)};
270             }
271              
272 0     0 0   sub load {
273             my ($self, $method) = @_;
274 0 0          
275             $self->load_extensions(
276             "$self->{prefix}/$self->{path}", $self
277             ) unless $self->{extensions};
278 0            
  0            
279 0 0         foreach my $obj (@{$self->{extensions}}) {
280             return $obj if $obj->can($method);
281             }
282 0 0          
283             my $admin = $self->{admin} or die <<"END_DIE";
284             The '$method' method does not exist in the '$self->{prefix}' path!
285             Please remove the '$self->{prefix}' directory and run $0 again to load it.
286             END_DIE
287 0            
288 0           my $obj = $admin->load($method, 1);
  0            
289             push @{$self->{extensions}}, $obj;
290 0            
291             $obj;
292             }
293              
294 0     0 0   sub load_extensions {
295             my ($self, $path, $top) = @_;
296 0            
297 0 0         my $should_reload = 0;
  0 0          
298 0           unless ( grep { ! ref $_ and lc $_ eq lc $self->{prefix} } @INC ) {
299 0           unshift @INC, $self->{prefix};
300             $should_reload = 1;
301             }
302 0            
303 0           foreach my $rv ( $self->find_extensions($path) ) {
  0            
304 0 0         my ($file, $pkg) = @{$rv};
305             next if $self->{pathnames}{$pkg};
306 0            
307 0           local $@;
  0            
  0            
  0            
308 0 0         my $new = eval { local $^W; require $file; $pkg->can('new') };
309 0 0         unless ( $new ) {
310 0           warn $@ if $@;
311             next;
312 0 0         }
313             $self->{pathnames}{$pkg} =
314 0           $should_reload ? delete $INC{$file} : $INC{$file};
  0            
  0            
315             push @{$self->{extensions}}, &{$new}($pkg, _top => $top );
316             }
317 0   0        
318             $self->{extensions} ||= [];
319             }
320              
321 0     0 0   sub find_extensions {
322             my ($self, $path) = @_;
323 0            
324             my @found;
325 0     0     File::Find::find( sub {
326 0 0         my $file = $File::Find::name;
327 0           return unless $file =~ m!^\Q$path\E/(.+)\.pm\Z!is;
328 0 0         my $subpath = $1;
329             return if lc($subpath) eq lc($self->{dispatch});
330 0            
331 0           $file = "$self->{path}/$subpath.pm";
332 0           my $pkg = "$self->{name}::$subpath";
333             $pkg =~ s!/!::!g;
334              
335             # If we have a mixed-case package name, assume case has been preserved
336             # correctly. Otherwise, root through the file to locate the case-preserved
337 0 0 0       # version of the package name.
338 0           if ( $subpath eq lc($subpath) || $subpath eq uc($subpath) ) {
339 0           my $content = Module::Install::_read($subpath . '.pm');
340 0           my $in_pod = 0;
341 0 0         foreach ( split //, $content ) {
342 0 0         $in_pod = 1 if /^=\w/;
343 0 0 0       $in_pod = 0 if /^=cut/;
344 0 0         next if ($in_pod || /^=cut/); # skip pod text
345 0 0         next if /^\s*#/; # and comments
346 0           if ( m/^\s*package\s+($pkg)\s*;/i ) {
347 0           $pkg = $1;
348             last;
349             }
350             }
351             }
352 0            
353 0 0         push @found, [ $file, $pkg ];
354             }, $path ) if -d $path;
355 0            
356             @found;
357             }
358              
359              
360              
361              
362              
363             #####################################################################
364             # Common Utility Functions
365              
366 0     0     sub _caller {
367 0           my $depth = 0;
368 0           my $call = caller($depth);
369 0           while ( $call eq __PACKAGE__ ) {
370 0           $depth++;
371             $call = caller($depth);
372 0           }
373             return $call;
374             }
375              
376 0 0   0     # Done in evals to avoid confusing Perl::MinimumVersion
  0 0          
  0            
  0            
  0            
  0            
  0            
377             eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@;
378             sub _read {
379             local *FH;
380             open( FH, '<', $_[0] ) or die "open($_[0]): $!";
381             my $string = do { local $/; };
382             close FH or die "close($_[0]): $!";
383             return $string;
384             }
385             END_NEW
386             sub _read {
387             local *FH;
388             open( FH, "< $_[0]" ) or die "open($_[0]): $!";
389             my $string = do { local $/; };
390             close FH or die "close($_[0]): $!";
391             return $string;
392             }
393             END_OLD
394              
395 0     0     sub _readperl {
396 0           my $string = Module::Install::_read($_[0]);
397 0           $string =~ s/(?:\015{1,2}\012|\015|\012)/\n/sg;
398 0           $string =~ s/(\n)\n*__(?:DATA|END)__\b.*\z/$1/s;
399 0           $string =~ s/\n\n=\w+.+?\n\n=cut\b.+?\n+/\n\n/sg;
400             return $string;
401             }
402              
403 0     0     sub _readpod {
404 0           my $string = Module::Install::_read($_[0]);
405 0 0         $string =~ s/(?:\015{1,2}\012|\015|\012)/\n/sg;
406 0           return $string if $_[0] =~ /\.pod\z/;
407 0           $string =~ s/(^|\n=cut\b.+?\n+)[^=\s].+?\n(\n=\w+|\z)/$1$2/sg;
408 0           $string =~ s/\n*=pod\b[^\n]*\n+/\n\n/sg;
409 0           $string =~ s/\n*=cut\b[^\n]*\n+/\n\n/sg;
410 0           $string =~ s/^\n+//s;
411             return $string;
412             }
413              
414 0 0   0     # Done in evals to avoid confusing Perl::MinimumVersion
  0 0          
  0 0          
  0            
  0            
415             eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@;
416             sub _write {
417             local *FH;
418             open( FH, '>', $_[0] ) or die "open($_[0]): $!";
419             foreach ( 1 .. $#_ ) {
420             print FH $_[$_] or die "print($_[0]): $!";
421             }
422             close FH or die "close($_[0]): $!";
423             }
424             END_NEW
425             sub _write {
426             local *FH;
427             open( FH, "> $_[0]" ) or die "open($_[0]): $!";
428             foreach ( 1 .. $#_ ) {
429             print FH $_[$_] or die "print($_[0]): $!";
430             }
431             close FH or die "close($_[0]): $!";
432             }
433             END_OLD
434              
435             # _version is for processing module versions (eg, 1.03_05) not
436             # Perl versions (eg, 5.8.1).
437 0   0 0     sub _version ($) {
438 0           my $s = shift || 0;
439 0 0         my $d =()= $s =~ /(\.)/g;
440             if ( $d >= 2 ) {
441 0           # Normalise multipart versions
  0            
442             $s =~ s/(\.)(\d{1,3})/sprintf("$1%03d",$2)/eg;
443 0           }
444 0   0       $s =~ s/^(\d+)\.?//;
445 0           my $l = $1 || 0;
446 0           my @v = map {
447             $_ . '0' x (3 - length $_)
448 0 0         } $s =~ /(\d{1,3})\D?/g;
449 0           $l = $l . '.' . join '', @v if @v;
450             return $l + 0;
451             }
452              
453 0     0     sub _cmp ($$) {
454             _version($_[0]) <=> _version($_[1]);
455             }
456              
457             # Cloned from Params::Util::_CLASS
458             sub _CLASS ($) {
459 0 0 0 0     (
460             defined $_[0]
461             and
462             ! ref $_[0]
463             and
464             $_[0] =~ m/^[^\W\d]\w*(?:::\w+)*\z/s
465             ) ? $_[0] : undef;
466             }
467              
468             1;
469              
470             # Copyright 2008 - 2011 Adam Kennedy.