File Coverage

inc/Module/Install.pm
Criterion Covered Total %
statement 137 177 77.4
branch 31 74 41.8
condition 10 33 30.3
subroutine 21 23 91.3
pod 0 7 0.0
total 199 314 63.3


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              
20 1     1   48 BEGIN {
21             require 5.004;
22 1     1   4 }
  1         2  
  1         28  
23             use strict 'vars';
24 1     1   5  
  1         1  
  1         90  
25             use vars qw{$VERSION};
26             BEGIN {
27             # All Module::Install core packages now require synchronised versions.
28             # This will be used to ensure we don't accidentally load old or
29             # different versions of modules.
30             # This is not enforced yet, but will be some time in the next few
31             # releases once we can make sure it won't clash with custom
32 1     1   2 # Module::Install extensions.
33             $VERSION = '0.75';
34 1         2  
35 1         219 *inc::Module::Install::VERSION = *VERSION;
36             @inc::Module::Install::ISA = __PACKAGE__;
37              
38             }
39              
40              
41              
42              
43              
44             # Whether or not inc::Module::Install is actually loaded, the
45             # $INC{inc/Module/Install.pm} is what will still get set as long as
46             # the caller loaded module this in the documented manner.
47             # If not set, the caller may NOT have loaded the bundled version, and thus
48             # they may not have a MI version that works with the Makefile.PL. This would
49             # result in false errors or unexpected behaviour. And we don't want that.
50             my $file = join( '/', 'inc', split /::/, __PACKAGE__ ) . '.pm';
51             unless ( $INC{$file} ) { die <<"END_DIE" }
52              
53             Please invoke ${\__PACKAGE__} with:
54              
55             use inc::${\__PACKAGE__};
56              
57             not:
58              
59             use ${\__PACKAGE__};
60              
61             END_DIE
62              
63              
64              
65              
66              
67             # If the script that is loading Module::Install is from the future,
68             # then make will detect this and cause it to re-run over and over
69             # again. This is bad. Rather than taking action to touch it (which
70             # is unreliable on some platforms and requires write permissions)
71             # for now we should catch this and refuse to run.
72             if ( -f $0 and (stat($0))[9] > time ) { die <<"END_DIE" }
73              
74             Your installer $0 has a modification time in the future.
75              
76             This is known to create infinite loops in make.
77              
78             Please correct this, then run $0 again.
79              
80             END_DIE
81              
82              
83              
84              
85              
86             # Build.PL was formerly supported, but no longer is due to excessive
87             # difficulty in implementing every single feature twice.
88             if ( $0 =~ /Build.PL$/i ) { die <<"END_DIE" }
89              
90             Module::Install no longer supports Build.PL.
91              
92             It was impossible to maintain duel backends, and has been deprecated.
93              
94             Please remove all Build.PL files and only use the Makefile.PL installer.
95              
96             END_DIE
97              
98              
99              
100              
101              
102             # To save some more typing in Module::Install installers, every...
103             # use inc::Module::Install
104             # ...also acts as an implicit use strict.
105             $^H |= strict::bits(qw(refs subs vars));
106              
107              
108              
109              
110 1     1   4  
  1         2  
  1         20  
111 1     1   5 use Cwd ();
  1         2  
  1         12  
112 1     1   4 use File::Find ();
  1         1  
  1         1836  
113 1     1   974 use File::Path ();
  1         1124  
  1         2058  
114             use FindBin;
115              
116 5     5 0 16 sub autoload {
117 5         42 my $self = shift;
118 5         38476 my $who = $self->_caller;
119 5         108 my $cwd = Cwd::cwd();
120             my $sym = "${who}::AUTOLOAD";
121 18     18   134792 $sym->{$cwd} = sub {
122 18 50       570 my $pwd = Cwd::cwd();
123             if ( my $code = $sym->{$pwd} ) {
124 18 50       124 # delegate back to parent dirs
125             goto &$code unless $cwd eq $pwd;
126 18 50       674 }
127 18         755 $$sym =~ /([^:]+)$/ or die "Cannot autoload $who - $sym";
128 18 50       258 unshift @_, ( $self, $1 );
  18         588  
129 5         474 goto &{$self->can('call')} unless uc($1) eq $1;
130             };
131             }
132              
133 1     1   2 sub import {
134 1         5 my $class = shift;
135 1         6 my $self = $class->new(@_);
136             my $who = $self->_caller;
137 1 50       41  
138 0         0 unless ( -f $self->{file} ) {
139 0         0 require "$self->{path}/$self->{dispatch}.pm";
140 0         0 File::Path::mkpath("$self->{prefix}/$self->{author}");
141 0         0 $self->{admin} = "$self->{name}::$self->{dispatch}"->new( _top => $self );
142 0         0 $self->{admin}->init;
143 0         0 @_ = ($class, _self => $self);
  0         0  
144             goto &{"$self->{name}::import"};
145             }
146 1         8  
  1         18  
147 1         14 *{"${who}::AUTOLOAD"} = $self->autoload;
148             $self->preload;
149              
150 1         8 # Unregister loader and worker packages so subdirs can use them again
151 1         10 delete $INC{"$self->{file}"};
152             delete $INC{"$self->{path}.pm"};
153 1         2084  
154             return 1;
155             }
156              
157 1     1 0 8 sub preload {
158 1 50       19 my $self = shift;
159 1         16 unless ( $self->{extensions} ) {
160             $self->load_extensions(
161             "$self->{prefix}/$self->{path}", $self
162             );
163             }
164 1         2  
  1         5  
165 1 50       4 my @exts = @{$self->{extensions}};
166 0         0 unless ( @exts ) {
167 0         0 my $admin = $self->{admin};
168             @exts = $admin->load_all_extensions;
169             }
170 1         2  
171 1         2 my %seen;
172 9         11 foreach my $obj ( @exts ) {
  164         792  
173 155 100       576 while (my ($method, $glob) = each %{ref($obj) . '::'}) {
174 124 100       250 next unless $obj->can($method);
175 122 100       242 next if $method =~ /^_/;
176 111         264 next if $method eq uc($method);
177             $seen{$method}++;
178             }
179             }
180 1         5  
181 1         55 my $who = $self->_caller;
182 77         359 foreach my $name ( sort keys %seen ) {
183 14     14   119 *{"${who}::$name"} = sub {
  14         148  
184 14         31 ${"${who}::AUTOLOAD"} = "${who}::$name";
  14         247  
185 77         278 goto &{"${who}::AUTOLOAD"};
186             };
187             }
188             }
189              
190 1     1 0 2 sub new {
191             my ($class, %args) = @_;
192              
193 1         37 # ignore the prefix on extension modules built from top level.
194 1 50       4956 my $base_path = Cwd::abs_path($FindBin::Bin);
195 0         0 unless ( Cwd::abs_path(Cwd::cwd()) eq $base_path ) {
196             delete $args{prefix};
197             }
198 1 50       17  
199             return $args{_self} if $args{_self};
200 1   50     107  
201 1   50     30 $args{dispatch} ||= 'Admin';
202 1 50 33     54 $args{prefix} ||= 'inc';
203 1   50     17 $args{author} ||= ($^O eq 'VMS' ? '_author' : '.author');
204 1   33     17 $args{bundle} ||= 'inc/BUNDLES';
205 1         42 $args{base} ||= $base_path;
206 1   33     13 $class =~ s/^\Q$args{prefix}\E:://;
207 1   33     42 $args{name} ||= $class;
208 1 50       10 $args{version} ||= $class->VERSION;
209 1         6 unless ( $args{path} ) {
210 1         5 $args{path} = $args{name};
211             $args{path} =~ s!::!/!g;
212 1   33     15 }
213 1         5 $args{file} ||= "$args{base}/$args{prefix}/$args{path}.pm";
214             $args{wrote} = 0;
215 1         15  
216             bless( \%args, $class );
217             }
218              
219 18     18 0 93 sub call {
220 18 50       195 my ($self, $method) = @_;
221 18         102 my $obj = $self->load($method) or return;
222 18         104 splice(@_, 0, 2, $obj);
  18         1279  
223             goto &{$obj->can($method)};
224             }
225              
226 18     18 0 82 sub load {
227             my ($self, $method) = @_;
228 18 50       126  
229             $self->load_extensions(
230             "$self->{prefix}/$self->{path}", $self
231             ) unless $self->{extensions};
232 18         40  
  18         351  
233 118 100       2535 foreach my $obj (@{$self->{extensions}}) {
234             return $obj if $obj->can($method);
235             }
236 0 0       0  
237             my $admin = $self->{admin} or die <<"END_DIE";
238             The '$method' method does not exist in the '$self->{prefix}' path!
239             Please remove the '$self->{prefix}' directory and run $0 again to load it.
240             END_DIE
241 0         0  
242 0         0 my $obj = $admin->load($method, 1);
  0         0  
243             push @{$self->{extensions}}, $obj;
244 0         0  
245             $obj;
246             }
247              
248 1     1 0 4 sub load_extensions {
249             my ($self, $path, $top) = @_;
250 1 50       9  
  10         43  
251 0         0 unless ( grep { lc $_ eq lc $self->{prefix} } @INC ) {
252             unshift @INC, $self->{prefix};
253             }
254 1         6  
255 9         13 foreach my $rv ( $self->find_extensions($path) ) {
  9         27  
256 9 50       33 my ($file, $pkg) = @{$rv};
257             next if $self->{pathnames}{$pkg};
258 9         14  
259 9         17 local $@;
  9         4796  
  9         134  
260 9 50       35 my $new = eval { require $file; $pkg->can('new') };
261 0 0       0 unless ( $new ) {
262 0         0 warn $@ if $@;
263             next;
264 9         43 }
265 9         15 $self->{pathnames}{$pkg} = delete $INC{$file};
  9         20  
  9         29  
266             push @{$self->{extensions}}, &{$new}($pkg, _top => $top );
267             }
268 1   50     13  
269             $self->{extensions} ||= [];
270             }
271              
272 1     1 0 2 sub find_extensions {
273             my ($self, $path) = @_;
274 1         3  
275             my @found;
276 10     10   15 File::Find::find( sub {
277 10 100       265 my $file = $File::Find::name;
278 9         29 return unless $file =~ m!^\Q$path\E/(.+)\.pm\Z!is;
279 9 50       34 my $subpath = $1;
280             return if lc($subpath) eq lc($self->{dispatch});
281 9         23  
282 9         22 $file = "$self->{path}/$subpath.pm";
283 9         15 my $pkg = "$self->{name}::$subpath";
284             $pkg =~ s!/!::!g;
285              
286             # If we have a mixed-case package name, assume case has been preserved
287             # correctly. Otherwise, root through the file to locate the case-preserved
288 9 50 33     60 # version of the package name.
289 0         0 if ( $subpath eq lc($subpath) || $subpath eq uc($subpath) ) {
290 0         0 my $content = Module::Install::_read($subpath . '.pm');
291 0         0 my $in_pod = 0;
292 0 0       0 foreach ( split //, $content ) {
293 0 0       0 $in_pod = 1 if /^=\w/;
294 0 0 0     0 $in_pod = 0 if /^=cut/;
295 0 0       0 next if ($in_pod || /^=cut/); # skip pod text
296 0 0       0 next if /^\s*#/; # and comments
297 0         0 if ( m/^\s*package\s+($pkg)\s*;/i ) {
298 0         0 $pkg = $1;
299             last;
300             }
301             }
302             }
303 9         109  
304 1 50       246 push @found, [ $file, $pkg ];
305             }, $path ) if -d $path;
306 1         22  
307             @found;
308             }
309              
310              
311              
312              
313              
314             #####################################################################
315             # Utility Functions
316              
317 7     7   14 sub _caller {
318 7         34 my $depth = 0;
319 7         26 my $call = caller($depth);
320 9         12 while ( $call eq __PACKAGE__ ) {
321 9         124 $depth++;
322             $call = caller($depth);
323 7         26 }
324             return $call;
325             }
326              
327 1     1   9 sub _read {
328 1 50       61 local *FH;
329 1         4 open FH, "< $_[0]" or die "open($_[0]): $!";
  1         9  
  1         89  
330 1 50       18 my $str = do { local $/; };
331 1         49 close FH or die "close($_[0]): $!";
332             return $str;
333             }
334              
335 0     0     sub _write {
336 0 0         local *FH;
337 0 0         open FH, "> $_[0]" or die "open($_[0]): $!";
  0            
338 0 0         foreach ( 1 .. $#_ ) { print FH $_[$_] or die "print($_[0]): $!" }
339             close FH or die "close($_[0]): $!";
340             }
341              
342 0   0 0     sub _version {
343 0           my $s = shift || 0;
344 0   0       $s =~ s/^(\d+)\.?//;
345 0           my $l = $1 || 0;
  0            
346 0 0         my @v = map { $_ . '0' x (3 - length $_) } $s =~ /(\d{1,3})\D?/g;
347 0           $l = $l . '.' . join '', @v if @v;
348             return $l + 0;
349             }
350              
351             1;
352              
353             # Copyright 2008 Adam Kennedy.