File Coverage

inc/Module/Build/Functions.pm
Criterion Covered Total %
statement 71 569 12.4
branch 6 240 2.5
condition 8 67 11.9
subroutine 15 81 18.5
pod n/a
total 100 957 10.4


line stmt bran cond sub pod time code
1             #line 1
2             package Module::Build::Functions;
3              
4 1     1   11 #<<<
  1         3  
  1         108  
5 1     1   38 use strict;
  1         5  
  1         70  
6 1     1   1366 use 5.00503;
  1         7  
  1         212  
7 1     1   9 use vars qw( $VERSION @EXPORT $AUTOLOAD %ARGS);
  1         2  
  1         121  
8 1     1   17294 use Carp qw( croak carp confess );
  1         1363  
  1         109  
9 1     1   8 use File::Spec::Functions qw( catdir catfile );
  1         3  
  1         19  
10 1     1   8 use Exporter qw();
  1         1  
  1         28  
11 1     1   101 use Cwd qw();
  1         2  
  1         117  
12 1     1   7 use File::Find qw();
  1         1  
  1         28  
13 1     1   1261 use File::Path qw();
  1         1462  
  1         46  
14 1     1   7 use FindBin;
  1         2  
  1         19731  
15             use Config;
16              
17             # The equivalent of "use warnings" pre-5.006.
18             local $^W = 1;
19             my $object = undef;
20             my $class = 'Module::Build';
21             my $mb_required = 0;
22             my $object_created = 0;
23             my $export_to = undef;
24             my $sharemod_used = 1;
25             my (%FLAGS, %ALIASES, %ARRAY, %HASH, @AUTOLOADED, @DEFINED);
26             my @install_types;
27             my %config;
28             #>>>
29              
30             # Whether or not inc::Module::Build::Functions is actually loaded, the
31             # $INC{inc/Module/Build/Functions.pm} is what will still get set as long as
32             # the caller loaded this module in the documented manner.
33             # If not set, the caller may NOT have loaded the bundled version, and thus
34             # they may not have a MBF version that works with the Build.PL. This would
35             # result in false errors or unexpected behaviour. And we don't want that.
36             my $file = join( '/', 'inc', split /::/, __PACKAGE__ ) . '.pm';
37             unless ( $INC{$file} ) {
38             die <<"END_DIE" }
39              
40             Please invoke ${\__PACKAGE__} with:
41              
42             use inc::${\__PACKAGE__};
43              
44             not:
45              
46             use ${\__PACKAGE__};
47              
48             END_DIE
49              
50             # To save some more typing in Module::Build::Functions installers, every...
51             # use inc::Module::Build::Functions
52             # ...also acts as an implicit use strict.
53             $^H |= strict::bits(qw(refs subs vars));
54              
55             # import which will also perform self-bundling
56 1     1   4 sub import {
57             $export_to = caller;
58 1         3
59             my $class = shift;
60 1         5  
61             %config = @_;
62 1   50     9  
63 1 50 33     12 $config{prefix} ||= 'inc';
64 1   33     97 $config{author} ||= ( $^O eq 'VMS' ? '_author' : '.author' );
65             $config{base} ||= Cwd::abs_path($FindBin::Bin);
66              
67             # Stripping leading prefix, if this import was called
68 1         24 # from loader (inc::Module::Build::Functions)
69             $class =~ s/^\Q$config{prefix}\E:://;
70 1   33     8  
71 1   33     35 $config{name} ||= $class;
72             $config{version} ||= $class->VERSION;
73 1 50       7  
74 1         4 unless ( $config{path} ) {
75 1         6 $config{path} = $config{name};
76             $config{path} =~ s!::!/!g;
77 1   33     12 }
78             $config{file} ||= "$config{base}/$config{prefix}/$config{path}.pm";
79 1 50 33     33  
      33        
80 0         0 unless ( -f $config{file} || $0 ne 'Build.PL' && $0 ne 'Makefile.PL' ) {
81             File::Path::mkpath("$config{prefix}/$config{author}");
82              
83 0         0 # Bundling its own copy to ./inc
84             _copy( $INC{"$config{path}.pm"} => $config{file} );
85 0 0       0  
  0         0  
86 0         0 unless ( grep { $_ eq $config{prefix} } @INC ) {
87             unshift @INC, $config{prefix};
88             }
89             }
90 1 50       6
91 1         3 if (defined $config{build_class}) {
92             $DB::single = 1;
93 1         4
94             build_class($config{build_class});
95             }
96              
97             {
98             # The export should be performed 1 level up, since we call
99 0         0 # Exporter's 'import' from our 'import'
  0         0  
100             local $Exporter::ExportLevel = 1;
101              
102 0         0 # Delegating back to Exporter's import
103             &Exporter::import($class);
104             }
105             } ## end sub import
106              
107              
108             # Copy a single package to inc/, with its @ISA tree (note, dependencies are skipped)
109 0     0   0 sub copy_package {
110             my ( $pkg, $skip_isa ) = @_;
111 0         0  
112 0         0 my $file = $pkg;
113             $file =~ s!::!/!g;
114 0         0  
115             my $pathname = "$file.pm";
116              
117 0 0       0 # Do not re-require packages
118 0 0       0 eval "require $pkg" unless $INC{$pathname};
119             die "The package [$pkg] not found and cannot be added to ./inc" if $@;
120 0         0  
121 0 0       0 $file = "$config{prefix}/$file.pm";
122             return if -f $file; # prevents infinite recursion
123 0         0  
124             _copy( $INC{$pathname} => $file );
125 0 0       0  
126 0         0 unless ($skip_isa) {
127             my @isa = eval '@' . $pkg . '::ISA';
128 0         0  
129             copy_package($_) foreach (@isa);
130             }
131             } ## end sub copy_package
132              
133             # POD-stripping enabled copy function
134 0     0   0 sub _copy {
135             my ( $from, $to ) = @_;
136 0         0  
137 0         0 my @parts = split( '/', $to );
138             File::Path::mkpath( [ join( '/', @parts[ 0 .. $#parts - 1 ] ) ] );
139 0         0  
140             chomp $to;
141 0         0  
142 0 0       0 local ( *FROM, *TO, $_ );
143 0 0       0 open FROM, "< $from" or die "Can't open $from for input:\n$!";
144 0         0 open TO, "> $to" or die "Can't open $to for output:\n$!";
145             print TO "#line 1\n";
146 0         0  
147             my $content;
148             my $in_pod;
149 0         0  
150 0 0 0     0 while () {
    0          
    0          
151 0         0 if (/^=(?:b(?:egin|ack)|head\d|(?:po|en)d|item|(?:ove|fo)r)/) {
152             $in_pod = 1;
153 0         0 } elsif ( /^=cut\s*\z/ and $in_pod ) {
154 0         0 $in_pod = 0;
155             print TO "#line $.\n";
156 0         0 } elsif ( !$in_pod ) {
157             print TO $_;
158             }
159             }
160 0         0  
161 0         0 close FROM;
162             close TO;
163 0         0  
164             print "include $to\n";
165             } ## end sub _copy
166              
167 1     1   5 BEGIN {
168             $VERSION = '0.04';
169 1         4  
170             *inc::Module::Build::Functions::VERSION = *VERSION;
171              
172             # Very important line which turns a loader (inc::Module::Build::Functions)
173 1         28 # into our subclass, thus provides an 'import' function to it
174             @inc::Module::Build::Functions::ISA = __PACKAGE__;
175 1         29257  
176             require Module::Build;
177              
178             # Module implementation here
179              
180 1 50       364657 # Set defaults.
181 1         5 if ( $Module::Build::VERSION >= 0.28 ) {
182 1         4 $ARGS{create_packlist} = 1;
183             $mb_required = '0.28';
184             }
185              
186 1         28 %FLAGS = (
187             'create_makefile_pl' => [ '0.19', 0 ],
188             'c_source' => [ '0.04', 0 ],
189             'dist_abstract' => [ '0.20', 0 ],
190             'dist_name' => [ '0.11', 0 ],
191             'dist_version' => [ '0.11', 0 ],
192             'dist_version_from' => [ '0.11', 0 ],
193             'installdirs' => [ '0.19', 0 ],
194             'license' => [ '0.11', 0 ],
195             'create_packlist' => [ '0.28', 1 ],
196             'create_readme' => [ '0.22', 1 ],
197             'create_license' => [ '0.31', 1 ],
198             'dynamic_config' => [ '0.07', 1 ],
199             'use_tap_harness' => [ '0.30', 1 ],
200             'sign' => [ '0.16', 1 ],
201             'recursive_test_files' => [ '0.28', 1 ],
202             'auto_configure_requires' => [ '0.34', 1 ],
203             );
204 1         21  
205             %ALIASES = (
206             'test_requires' => 'build_requires',
207             'abstract' => 'dist_abstract',
208             'name' => 'module_name',
209             'author' => 'dist_author',
210             'version' => 'dist_version',
211             'version_from' => 'dist_version_from',
212             'extra_compiler_flag' => 'extra_compiler_flags',
213             'extra_linker_flag' => 'extra_linker_flags',
214             'include_dir' => 'include_dirs',
215             'pl_file' => 'PL_files',
216             'pl_files' => 'PL_files',
217             'PL_file' => 'PL_files',
218             'pm_file' => 'pm_files',
219             'pod_file' => 'pod_files',
220             'xs_file' => 'xs_files',
221             'test_file' => 'test_files',
222             'script_file' => 'script_files',
223             );
224 1         7  
225             %ARRAY = (
226             'autosplit' => '0.04',
227             'add_to_cleanup' => '0.19',
228             'include_dirs' => '0.24',
229             'dist_author' => '0.20',
230             );
231 1         15  
232             %HASH = (
233             'configure_requires' => [ '0.30', 1 ],
234             'build_requires' => [ '0.07', 1 ],
235             'conflicts' => [ '0.07', 1 ],
236             'recommends' => [ '0.08', 1 ],
237             'requires' => [ '0.07', 1 ],
238             'get_options' => [ '0.26', 0 ],
239             'meta_add' => [ '0.28', 0 ],
240             'pm_files' => [ '0.19', 0 ],
241             'pod_files' => [ '0.19', 0 ],
242             'xs_files' => [ '0.19', 0 ],
243             'install_path' => [ '0.19', 0 ],
244             );
245 1         34  
246             @AUTOLOADED = ( keys %HASH, keys %ARRAY, keys %ALIASES, keys %FLAGS );
247 1         28  
248             @DEFINED = qw(
249             all_from abstract_from author_from license_from perl_version
250             perl_version_from install_script install_as_core install_as_cpan
251             install_as_site install_as_vendor WriteAll auto_install auto_bundle
252             bundle bundle_deps auto_bundle_deps can_use can_run can_cc
253             requires_external_bin requires_external_cc get_file check_nmake
254             interactive release_testing automated_testing win32 winlike
255             author_context install_share auto_features extra_compiler_flags
256             extra_linker_flags module_name no_index PL_files script_files test_files
257             tap_harness_args subclass create_build_script get_builder build_class
258             repository bugtracker meta_merge cygwin
259 1         16 );
260             @EXPORT = ( 'AUTOLOAD', @DEFINED, @AUTOLOADED );
261 1         30818
262             $DB::single = 1;
263              
264             } ## end BEGIN
265              
266             # The autoload handles 4 types of "similar" routines, for 45 names.
267 0     0   0 sub AUTOLOAD {
268 0         0 my $full_sub = $AUTOLOAD;
269             my ($sub) = $AUTOLOAD =~ m{\A.*::([^:]*)\z}x;
270 0 0       0  
271 0         0 if ( exists $ALIASES{$sub} ) {
272 0         0 my $alias = $ALIASES{$sub};
273             eval <<"END_OF_CODE";
274             sub $full_sub {
275             $alias(\@_);
276             return;
277             }
278 0         0 END_OF_CODE
  0         0  
279             goto &{$full_sub};
280             }
281 0 0       0  
282 0         0 if ( exists $FLAGS{$sub} ) {
283 0 0       0 my $boolean_version = $FLAGS{$sub}[0];
284 0 0       0 my $boolean_default = $FLAGS{$sub}[1] ? ' || 1' : q{};
285 0         0 my $boolean_normal = $FLAGS{$sub}[1] ? q{!!} : q{};
286             eval <<"END_OF_CODE";
287             sub $full_sub {
288             my \$argument = shift$boolean_default;
289             \$ARGS{$sub} = $boolean_normal \$argument;
290             _mb_required('$boolean_version');
291             return;
292             }
293 0         0 END_OF_CODE
  0         0  
294             goto &{$full_sub};
295             } ## end if ( exists $FLAGS{$sub...})
296 0 0       0  
297             if ( exists $ARRAY{$sub} ) {
298 0         0  
299 0         0 my $array_version = $ARRAY{$sub};
300             my $code_array = <<"END_OF_CODE";
301             sub $full_sub {
302             my \$argument = shift;
303             if ( 'ARRAY' eq ref \$argument ) {
304             foreach my \$f ( \@{\$argument} ) {
305             $sub(\$f);
306             }
307             return;
308             }
309            
310             my \@array;
311             if (exists \$ARGS{$sub}) {
312             \$ARGS{$sub} = [ \@{ \$ARGS{$sub} }, \$argument ];
313             } else {
314             \$ARGS{$sub} = [ \$argument ];
315             }
316             _mb_required('$array_version');
317             return;
318             }
319 0         0 END_OF_CODE
320 0         0 eval $code_array;
  0         0  
321             goto &{$full_sub};
322             } ## end if ( exists $ARRAY{$sub...})
323 0 0       0  
324 0         0 if ( exists $HASH{$sub} ) {
325 0         0 _create_hashref($sub);
326 0 0       0 my $hash_version = $HASH{$sub}[0];
327 0         0 my $hash_default = $HASH{$sub}[1] ? ' || 0' : q{};
328             my $code_hash = <<"END_OF_CODE";
329             sub $full_sub {
330             my \$argument1 = shift;
331             my \$argument2 = shift$hash_default;
332             if ( 'HASH' eq ref \$argument1 ) {
333             my ( \$k, \$v );
334             while ( ( \$k, \$v ) = each \%{\$argument1} ) {
335             $sub( \$k, \$v );
336             }
337             return;
338             }
339              
340             \$ARGS{$sub}{\$argument1} = \$argument2;
341             _mb_required('$hash_version');
342             return;
343             }
344 0         0 END_OF_CODE
345 0         0 eval $code_hash;
  0         0  
346             goto &{$full_sub};
347             } ## end if ( exists $HASH{$sub...})
348 0         0  
349             croak "$sub cannot be found";
350             } ## end sub AUTOLOAD
351              
352 0     0   0 sub _mb_required {
353 0 0       0 my $version = shift;
354 0         0 if ( $version > $mb_required ) {
355             $mb_required = $version;
356 0         0 }
357             return;
358             }
359              
360 0 0   0   0 sub _installdir {
361 0 0       0 return $Config{'sitelibexp'} unless ( defined $ARGS{install_type} );
362 0 0       0 return $Config{'sitelibexp'} if ( 'site' eq $ARGS{install_type} );
363 0 0       0 return $Config{'privlibexp'} if ( 'perl' eq $ARGS{install_type} );
364 0         0 return $Config{'vendorlibexp'} if ( 'vendor' eq $ARGS{install_type} );
365             croak 'Invalid install type';
366             }
367              
368 0     0   0 sub _create_arrayref {
369 0 0       0 my $name = shift;
370 0         0 unless ( exists $ARGS{$name} ) {
371             $ARGS{$name} = [];
372 0         0 }
373             return;
374             }
375              
376              
377 0     0   0 sub _create_hashref {
378 0 0       0 my $name = shift;
379 0         0 unless ( exists $ARGS{$name} ) {
380             $ARGS{$name} = {};
381 0         0 }
382             return;
383             }
384              
385 0     0   0 sub _create_hashref_arrayref {
386 0         0 my $name1 = shift;
387 0 0       0 my $name2 = shift;
388 0         0 unless ( exists $ARGS{$name1}{$name2} ) {
389             $ARGS{$name1}{$name2} = [];
390 0         0 }
391             return;
392             }
393              
394 0     0   0 sub _slurp_file {
395 0         0 my $name = shift;
396             my $file_handle;
397 0 0       0  
398 0         0 if ( $] < 5.006 ) {
399 0         0 require Symbol;
400 0 0       0 $file_handle = Symbol::gensym();
401             open $file_handle, "<$name"
402             or croak $!;
403 0 0       0 } else {
404             open $file_handle, '<', $name
405             or croak $!;
406             }
407 0         0  
408 0         0 local $/ = undef; # enable localized slurp mode
409             my $content = <$file_handle>;
410 0         0  
411 0         0 close $file_handle;
412             return $content;
413             } ## end sub _slurp_file
414              
415             # Module::Install syntax below.
416              
417 0     0   0 sub all_from {
418             my $file = shift;
419 0         0  
420 0         0 abstract_from($file);
421 0         0 author_from($file);
422 0         0 version_from($file);
423 0         0 license_from($file);
424 0         0 perl_version_from($file);
425             return;
426             }
427              
428 0     0   0 sub abstract_from {
429             my $file = shift;
430 0         0  
431 0         0 require ExtUtils::MM_Unix;
432             abstract(
433             bless( { DISTNAME => $ARGS{module_name} }, 'ExtUtils::MM_Unix' )
434             ->parse_abstract($file) );
435 0         0  
436             return;
437             }
438              
439             # Borrowed from Module::Install::Metadata->author_from
440 0     0   0 sub author_from {
441 0         0 my $file = shift;
442 0         0 my $content = _slurp_file($file);
443             my $author;
444 0 0       0  
    0          
445             if ($content =~ m{
446             =head \d \s+ (?:authors?)\b \s*
447             (.*?)
448             =head \d
449             }ixms
450             )
451             {
452              
453 0         0 # Grab all author lines.
454             my $authors = $1;
455              
456 0         0 # Now break up each line.
457 0         0 while ( $authors =~ m{\G([^\n]+) \s*}gcixms ) {
458             $author = $1;
459              
460 0         0 # Convert E and E into the right characters.
461 0         0 $author =~ s{E}{<}g;
462             $author =~ s{E}{>}g;
463              
464 0 0       0 # Remove new-style C<< >> markers.
465 0         0 if ( $author =~ m{\A(.*?) \s* C<< \s* (.*?) \s* >>}msx ) {
466             $author = "$1 $2";
467 0         0 }
468             dist_author($author);
469             } ## end while ( $authors =~ m{\G([^\n]+) \s*}gcixms)
470             } elsif (
471             $content =~ m{
472             =head \d \s+ (?:licen[cs]e|licensing|copyright|legal)\b \s*
473             .*? copyright .*? \d\d\d[\d.]+ \s* (?:\bby\b)? \s*
474             ([^\n]*)
475             }ixms
476             )
477 0         0 {
478             $author = $1;
479              
480 0         0 # Convert E and E into the right characters.
481 0         0 $author =~ s{E}{<}g;
482             $author =~ s{E}{>}g;
483              
484 0 0       0 # Remove new-style C<< >> markers.
485 0         0 if ( $author =~ m{\A(.*?) \s* C<< \s* (.*?) \s* >>}msx ) {
486             $author = "$1 $2";
487 0         0 }
488             dist_author($author);
489 0         0 } else {
490             carp "Cannot determine author info from $file";
491             }
492 0         0  
493             return;
494             } ## end sub author_from
495              
496             # Borrowed from Module::Install::Metadata->license_from
497 0     0   0 sub license_from {
498 0         0 my $file = shift;
499 0 0       0 my $content = _slurp_file($file);
500             if ($content =~ m{
501             (
502             =head \d \s+
503             (?:licen[cs]e|licensing|copyright|legal)\b
504             .*?
505             )
506             (=head\\d.*|=cut.*|)
507             \z
508             }ixms
509             )
510 0         0 {
511             my $license_text = $1;
512 0         0 #<<<
513             my @phrases = (
514             'under the same (?:terms|license) as perl itself' => 'perl', 1,
515             'GNU general public license' => 'gpl', 1,
516             'GNU public license' => 'gpl', 1,
517             'GNU lesser general public license' => 'lgpl', 1,
518             'GNU lesser public license' => 'lgpl', 1,
519             'GNU library general public license' => 'lgpl', 1,
520             'GNU library public license' => 'lgpl', 1,
521             'BSD license' => 'bsd', 1,
522             'Artistic license' => 'artistic', 1,
523             'GPL' => 'gpl', 1,
524             'LGPL' => 'lgpl', 1,
525             'BSD' => 'bsd', 1,
526             'Artistic' => 'artistic', 1,
527             'MIT' => 'mit', 1,
528             'proprietary' => 'restrictive', 0,
529             );
530 0         0 #>>>
531 0         0 while ( my ( $pattern, $license, $osi ) = splice @phrases, 0, 3 ) {
532 0 0       0 $pattern =~ s{\s+}{\\s+}g;
533 0         0 if ( $license_text =~ /\b$pattern\b/ix ) {
534 0         0 license($license);
535             return;
536             }
537             }
538             } ## end if ( $content =~ m{ ) (})
539 0         0  
540 0         0 carp "Cannot determine license info from $file";
541 0         0 license('unknown');
542             return;
543             } ## end sub license_from
544              
545 0     0   0 sub perl_version {
546 0         0 requires( 'perl', @_ );
547             return;
548             }
549              
550             # Borrowed from Module::Install::Metadata->license_from
551 0     0   0 sub perl_version_from {
552 0         0 my $file = shift;
553 0 0       0 my $content = _slurp_file($file);
554             if ($content =~ m{
555             ^ # Start of LINE, not start of STRING.
556             (?:use|require) \s*
557             v?
558             ([\d_\.]+)
559             \s* ;
560             }ixms
561             )
562 0         0 {
563 0         0 my $perl_version = $1;
564 0         0 $perl_version =~ s{_}{}g;
565             perl_version($perl_version);
566 0         0 } else {
567             carp "Cannot determine perl version info from $file";
568             }
569 0         0  
570             return;
571             } ## end sub perl_version_from
572              
573 0     0   0 sub install_script {
574 0         0 my @scripts = @_;
575 0 0 0     0 foreach my $script (@scripts) {
    0          
576 0         0 if ( -f $script ) {
577             script_files($_);
578 0         0 } elsif ( -d 'script' and -f "script/$script" ) {
579             script_files("script/$script");
580 0         0 } else {
581             croak "Cannot find script '$script'";
582             }
583             }
584 0         0  
585             return;
586             } ## end sub install_script
587              
588 0     0   0 sub install_as_core {
589             return installdirs('perl');
590             }
591              
592 0     0   0 sub install_as_cpan {
593             return installdirs('site');
594             }
595              
596 0     0   0 sub install_as_site {
597             return installdirs('site');
598             }
599              
600 0     0   0 sub install_as_vendor {
601             return installdirs('vendor');
602             }
603              
604 0     0   0 sub WriteAll { ## no critic(Capitalization)
605 0         0 my $answer = create_build_script();
606             return $answer;
607             }
608              
609             # Module::Install::AutoInstall
610              
611 0     0   0 sub auto_install {
612             croak 'auto_install is deprecated';
613             }
614              
615             # Module::Install::Bundle
616              
617 0     0   0 sub auto_bundle {
618             croak 'auto_bundle is deprecated';
619             }
620              
621 0     0   0 sub bundle {
622             croak 'bundle is deprecated';
623             }
624              
625 0     0   0 sub bundle_deps {
626             croak 'bundle_deps is deprecated';
627             }
628              
629 0     0   0 sub auto_bundle_deps {
630             croak 'auto_bundle_deps is deprecated';
631             }
632              
633             # Module::Install::Can
634              
635 0     0   0 sub can_use {
636             my ( $mod, $ver ) = @_;
637 0         0  
638 0         0 my $file = $mod;
639 0 0       0 $file =~ s{::|\\}{/}g;
640             $file .= '.pm' unless $file =~ /\.pm$/i;
641 0         0  
642 0   0     0 local $@ = undef;
  0         0  
  0         0  
  0         0  
643             return eval { require $file; $mod->VERSION( $ver || 0 ); 1 };
644             }
645              
646 0     0   0 sub can_run {
647 0         0 my $cmd = shift;
648 0 0       0 require ExtUtils::MakeMaker;
649             if ( $^O eq 'cygwin' ) {
650              
651 0         0 # MM->maybe_command is fixed in 6.51_01 for Cygwin.
652             ExtUtils::MakeMaker->import(6.52);
653             }
654 0         0  
655 0 0 0     0 my $_cmd = $cmd;
656             return $_cmd if ( -x $_cmd or $_cmd = MM->maybe_command($_cmd) );
657 0         0  
658             for my $dir ( ( split /$Config::Config{path_sep}/x, $ENV{PATH} ), q{.} )
659 0 0       0 {
660 0         0 next if $dir eq q{};
661 0 0 0     0 my $abs = File::Spec->catfile( $dir, $cmd );
662             return $abs if ( -x $abs or $abs = MM->maybe_command($abs) );
663             }
664 0         0  
665             return;
666             } ## end sub can_run
667              
668 0     0   0 sub can_cc {
669 0         0 return eval {
670 0         0 require ExtUtils::CBuilder;
671             ExtUtils::CBuilder->new()->have_compiler();
672             };
673             }
674              
675             # Module::Install::External
676              
677 0     0   0 sub requires_external_bin {
678 0 0       0 my ( $bin, $version ) = @_;
679 0         0 if ($version) {
680             croak 'requires_external_bin does not support versions yet';
681             }
682              
683 0         0 # Locate the bin
684 0         0 print "Locating required external dependency bin: $bin...";
685 0 0       0 my $found_bin = can_run($bin);
686 0         0 if ($found_bin) {
687             print " found at $found_bin.\n";
688 0         0 } else {
689 0         0 print " missing.\n";
690 0         0 print "Unresolvable missing external dependency.\n";
691 0         0 print "Please install '$bin' seperately and try again.\n";
  0         0  
692             print {*STDERR}
693 0         0 "NA: Unable to build distribution on this platform.\n";
694             exit 0;
695             }
696 0         0  
697             return 1;
698             } ## end sub requires_external_bin
699              
700 0 0   0   0 sub requires_external_cc {
701 0         0 unless ( can_cc() ) {
702 0         0 print "Unresolvable missing external dependency.\n";
703 0         0 print "This package requires a C compiler.\n";
  0         0  
704             print {*STDERR}
705 0         0 "NA: Unable to build distribution on this platform.\n";
706             exit 0;
707             }
708 0         0  
709             return 1;
710             }
711              
712             # Module::Install::Fetch
713              
714 0     0   0 sub get_file {
715             croak
716             'get_file is not supported - replace by code in a Module::Build subclass.';
717             }
718              
719             # Module::Install::Win32
720              
721 0     0   0 sub check_nmake {
722             croak
723             'check_nmake is not supported - replace by code in a Module::Build subclass.';
724             }
725              
726             # Module::Install::With
727              
728 0     0   0 sub release_testing {
729             return !!$ENV{RELEASE_TESTING};
730             }
731              
732 0     0   0 sub automated_testing {
733             return !!$ENV{AUTOMATED_TESTING};
734             }
735              
736             # Mostly borrowed from Scalar::Util::openhandle, since I should
737             # not use modules that were non-core in 5.005.
738 0     0   0 sub _openhandle {
739 0   0     0 my $fh = shift;
740             my $rt = reftype($fh) || q{};
741 0 0       0  
    0          
742             return ( ( defined fileno $fh ) ? $fh : undef )
743             if $rt eq 'IO';
744 0 0       0  
745 0         0 if ( $rt ne 'GLOB' ) {
746             return;
747             }
748 0 0 0     0  
749             return ( tied *{$fh} or defined fileno $fh ) ? $fh : undef;
750             } ## end sub _openhandle
751              
752             # Mostly borrowed from IO::Interactive::is_interactive, since I should
753             # not use modules that were non-core in 5.005.
754             sub interactive {
755              
756             # If we're doing automated testing, we assume that we don't have
757 0 0   0   0 # a terminal, even if we otherwise would.
758             return 0 if automated_testing();
759              
760 0 0       0 # Not interactive if output is not to terminal...
761             return 0 if not -t *STDOUT;
762              
763 0 0       0 # If *ARGV is opened, we're interactive if...
764             if ( _openhandle(*ARGV) ) {
765              
766 0 0 0     0 # ...it's currently opened to the magic '-' file
767             return -t *STDIN if defined $ARGV && $ARGV eq q{-};
768              
769 0 0 0     0 # ...it's at end-of-file and the next file is the magic '-' file
770             return @ARGV > 0 && $ARGV[0] eq q{-} && -t *STDIN if eof *ARGV;
771              
772 0         0 # ...it's directly attached to the terminal
773             return -t *ARGV;
774             }
775              
776             # If *ARGV isn't opened, it will be interactive if *STDIN is attached
777             # to a terminal.
778 0         0 else {
779             return -t *STDIN;
780             }
781             } ## end sub interactive
782              
783 0     0   0 sub win32 {
784             return !!( $^O eq 'MSWin32' );
785             }
786              
787 0     0   0 sub cygwin {
788             return !!( $^O eq 'cygwin' );
789             }
790              
791 0   0 0   0 sub winlike {
792             return !!( $^O eq 'MSWin32' or $^O eq 'cygwin' );
793             }
794              
795 0 0   0   0 sub author_context {
796 0 0       0 return 1 if -d 'inc/.author';
797 0 0       0 return 1 if -d 'inc/_author';
798 0 0       0 return 1 if -d '.svn';
799 0 0       0 return 1 if -f '.cvsignore';
800 0 0       0 return 1 if -f '.gitignore';
801 0         0 return 1 if -f 'MANIFEST.SKIP';
802             return 0;
803             }
804              
805             # Module::Install::Share
806              
807 0     0   0 sub _scan_dir {
808             my ( $srcdir, $destdir, $unixdir, $type, $files ) = @_;
809 0         0  
810             my $type_files = $type . '_files';
811 0 0       0  
812             $ARGS{$type_files} = {} unless exists $ARGS{"$type_files"};
813 0         0  
814             my $dir_handle;
815 0 0       0  
816 0         0 if ( $] < 5.006 ) {
817 0         0 require Symbol;
818             $dir_handle = Symbol::gensym();
819             }
820 0 0       0  
821             opendir $dir_handle, $srcdir or croak $!;
822              
823 0         0 FILE:
824 0 0       0 foreach my $direntry ( readdir $dir_handle ) {
825 0 0       0 if ( -d catdir( $srcdir, $direntry ) ) {
826 0 0       0 next FILE if ( $direntry eq q{.} );
827 0         0 next FILE if ( $direntry eq q{..} );
828             _scan_dir(
829             catdir( $srcdir, $direntry ),
830             catdir( $destdir, $direntry ),
831             File::Spec::Unix->catdir( $unixdir, $direntry ),
832             $type,
833             $files
834             );
835 0         0 } else {
836 0         0 my $sourcefile = catfile( $srcdir, $direntry );
837 0 0       0 my $unixfile = File::Spec::Unix->catfile( $unixdir, $direntry );
838 0         0 if ( exists $files->{$unixfile} ) {
839             $ARGS{$type_files}{$sourcefile} =
840             catfile( $destdir, $direntry );
841             }
842             }
843             } ## end foreach my $direntry ( readdir...)
844 0         0  
845             closedir $dir_handle;
846 0         0  
847             return;
848             } ## end sub _scan_dir
849              
850 0 0   0   0 sub install_share {
851 0 0       0 my $dir = @_ ? pop : 'share';
852             my $type = @_ ? shift : 'dist';
853 0 0 0     0  
      0        
854             unless ( defined $type
855             and ( ( $type eq 'module' ) or ( $type eq 'dist' ) ) )
856 0         0 {
857             croak "Illegal or invalid share dir type '$type'";
858 0 0 0     0 }
859 0         0 unless ( defined $dir and -d $dir ) {
860             croak 'Illegal or missing directory install_share param';
861             }
862 0         0  
863 0         0 require File::Spec::Unix;
864 0         0 require ExtUtils::Manifest;
865 0 0       0 my $files = ExtUtils::Manifest::maniread();
866 0         0 if ( 0 == scalar(%$files) ) {
867             croak 'Empty or no MANIFEST file';
868 0         0 }
869             my $installation_path;
870             my $sharecode;
871 0 0       0  
872 0 0       0 if ( $type eq 'dist' ) {
873             croak 'Too many parameters to install_share' if @_;
874 0         0  
875             my $dist = $ARGS{'dist_name'};
876 0         0  
877             $installation_path =
878 0         0 catdir( _installdir(), qw(auto share dist), $dist );
879 0         0 _scan_dir( $dir, 'share', $dir, 'share', $files );
880 0         0 push @install_types, 'share';
881             $sharecode = 'share';
882 0         0 } else {
883             my $module = shift;
884 0 0       0  
885 0         0 unless ( defined $module ) {
886             croak "Missing or invalid module name '$module'";
887             }
888 0         0  
889 0         0 $module =~ s/::/-/g;
890             $installation_path =
891 0         0 catdir( _installdir(), qw(auto share module), $module );
892 0         0 $sharecode = 'share_d' . $sharemod_used;
893 0         0 _scan_dir( $dir, $sharecode, $dir, $sharecode, $files );
894 0         0 push @install_types, $sharecode;
895             $sharemod_used++;
896             } ## end else [ if ( $type eq 'dist' )]
897              
898 0         0 # Set the path to install to.
899             install_path( $sharecode, $installation_path );
900              
901 0 0       0 # This helps for testing purposes...
902             if ( $Module::Build::VERSION >= 0.31 ) {
903 0     0   0 Module::Build->add_property( $sharecode . '_files',
  0         0  
904             default => sub { return {} } );
905             }
906              
907 0         0 # 99% of the time we don't want to index a shared dir
908             no_index($dir);
909              
910 0         0 # This construction requires 0.26.
911 0         0 _mb_required('0.26');
912             return;
913             } ## end sub install_share
914              
915             # Module::Build syntax
916              
917 0     0   0 sub _af_hashref {
918 0 0       0 my $feature = shift;
919 0         0 unless ( exists $ARGS{auto_features} ) {
920             $ARGS{auto_features} = {};
921 0 0       0 }
922 0         0 unless ( exists $ARGS{auto_features}{$feature} ) {
923 0         0 $ARGS{auto_features}{$feature} = {};
924             $ARGS{auto_features}{$feature}{requires} = {};
925 0         0 }
926             return;
927             }
928              
929 0     0   0 sub auto_features {
930 0         0 my $feature = shift;
931 0         0 my $type = shift;
932 0         0 my $param1 = shift;
933 0         0 my $param2 = shift;
934             _af_hashref($type);
935 0 0       0  
    0          
936 0         0 if ( 'description' eq $type ) {
937             $ARGS{auto_features}{$feature}{description} = $param1;
938 0         0 } elsif ( 'requires' eq $type ) {
939             $ARGS{auto_features}{$feature}{requires}{$param1} = $param2;
940 0         0 } else {
941             croak "Invalid type $type for auto_features";
942 0         0 }
943 0         0 _mb_required('0.26');
944             return;
945             } ## end sub auto_features
946              
947 0     0   0 sub extra_compiler_flags {
948 0 0       0 my $flag = shift;
949 0         0 if ( 'ARRAY' eq ref $flag ) {
  0         0  
950 0         0 foreach my $f ( @{$flag} ) {
951             extra_compiler_flags($f);
952             }
953             }
954 0 0       0  
955 0         0 if ( $flag =~ m{\s} ) {
956 0         0 my @flags = split m{\s+}, $flag;
957 0         0 foreach my $f (@flags) {
958             extra_compiler_flags($f);
959             }
960 0         0 } else {
961 0         0 _create_arrayref('extra_compiler_flags');
  0         0  
962             push @{ $ARGS{'extra_compiler_flags'} }, $flag;
963 0         0 }
964 0         0 _mb_required('0.19');
965             return;
966             } ## end sub extra_compiler_flags
967              
968 0     0   0 sub extra_linker_flags {
969 0 0       0 my $flag = shift;
970 0         0 if ( 'ARRAY' eq ref $flag ) {
  0         0  
971 0         0 foreach my $f ( @{$flag} ) {
972             extra_linker_flags($f);
973             }
974             }
975 0 0       0  
976 0         0 if ( $flag =~ m{\s} ) {
977 0         0 my @flags = split m{\s+}, $flag;
978 0         0 foreach my $f (@flags) {
979             extra_linker_flags($f);
980             }
981 0         0 } else {
982 0         0 _create_arrayref('extra_linker_flags');
  0         0  
983             push @{ $ARGS{'extra_linker_flags'} }, $flag;
984 0         0 }
985 0         0 _mb_required('0.19');
986             return;
987             } ## end sub extra_linker_flags
988              
989 0     0   0 sub module_name {
990 0         0 my ($name) = shift;
991 0 0       0 $ARGS{'module_name'} = $name;
992 0         0 unless ( exists $ARGS{'dist_name'} ) {
993 0         0 my $dist_name = $name;
994 0         0 $dist_name =~ s/::/-/g;
995             dist_name($dist_name);
996 0         0 }
997 0         0 _mb_required('0.03');
998             return;
999             }
1000              
1001 0     0   0 sub no_index {
1002 0   0     0 my $name = pop;
1003             my $type = shift || 'directory';
1004              
1005             # TODO: compatibility code.
1006 0         0  
1007 0         0 _create_hashref('no_index');
1008 0         0 _create_hashref_arrayref( 'no_index', $type );
  0         0  
1009 0         0 push @{ $ARGS{'no_index'}{$type} }, $name;
1010 0         0 _mb_required('0.28');
1011             return;
1012             } ## end sub no_index
1013              
1014 0     0   0 sub PL_files { ## no critic(Capitalization)
1015 0   0     0 my $pl_file = shift;
1016 0 0       0 my $pm_file = shift || [];
1017 0         0 if ( 'HASH' eq ref $pl_file ) {
1018 0         0 my ( $k, $v );
  0         0  
1019 0         0 while ( ( $k, $v ) = each %{$pl_file} ) {
1020             PL_files( $k, $v );
1021             }
1022             }
1023 0         0  
1024 0         0 _create_hashref('PL_files');
1025 0         0 $ARGS{PL_files}{$pl_file} = $pm_file;
1026 0         0 _mb_required('0.06');
1027             return;
1028             } ## end sub PL_files
1029              
1030 0     0   0 sub meta_merge {
1031 0         0 my $key = shift;
1032 0 0       0 my $value = shift;
1033 0         0 if ( 'HASH' eq ref $key ) {
1034 0         0 my ( $k, $v );
  0         0  
1035 0         0 while ( ( $k, $v ) = each %{$key} ) {
1036             meta_merge( $k, $v );
1037 0         0 }
1038             return;
1039             }
1040              
1041 0 0       0 # Allow omitting hashrefs, if there's one more parameter.
    0          
1042 0         0 if ( 1 == scalar @_ ) {
1043 0         0 meta_merge( $key, { $value => shift } );
1044             return;
1045 0         0 } elsif ( 0 != scalar @_ ) {
1046             confess 'Too many parameters to meta_merge';
1047             }
1048 0 0 0     0  
1049             if ( ( defined $ARGS{meta_merge}{$key} )
1050             and ( ref $value ne ref $ARGS{meta_merge}{$key} ) )
1051 0         0 {
1052             confess
1053             'Mismatch between value to merge into meta information and value already there';
1054             }
1055 0 0       0  
    0          
1056 0         0 if ( 'HASH' eq ref $ARGS{meta_merge}{$key} ) {
1057 0         0 $ARGS{meta_merge}{$key} =
  0         0  
1058             { ( %{ $ARGS{meta_merge}{$key} } ), ( %{$value} ) };
1059 0         0 } elsif ( 'ARRAY' eq ref $ARGS{meta_merge}{$key} ) {
1060 0         0 $ARGS{meta_merge}{$key} =
  0         0  
1061             \( @{ $ARGS{meta_merge}{$key} }, @{$value} );
1062 0         0 } else {
1063             $ARGS{meta_merge}{$key} = $value;
1064             }
1065 0         0  
1066 0         0 _mb_required('0.28');
1067             return;
1068             } ## end sub meta_merge
1069              
1070              
1071 0     0   0 sub repository {
1072 0         0 my $url = shift;
1073 0         0 meta_merge( 'resources', 'repository' => $url );
1074             return;
1075             }
1076              
1077 0     0   0 sub bugtracker {
1078 0         0 my $url = shift;
1079 0         0 meta_merge( 'resources', 'bugtracker' => $url );
1080             return;
1081             }
1082              
1083 0     0   0 sub script_files {
1084 0 0       0 my $file = shift;
1085 0         0 if ( 'ARRAY' eq ref $file ) {
  0         0  
1086 0         0 foreach my $f ( @{$file} ) {
1087             script_files($f);
1088             }
1089             }
1090 0 0       0  
1091 0 0       0 if ( -d $file ) {
1092 0 0       0 if ( exists $ARGS{'script_files'} ) {
1093 0         0 if ( 'ARRAY' eq ref $ARGS{'script_files'} ) {
1094             croak
1095             "cannot add directory $file to a list of script_files";
1096 0         0 } else {
1097             croak
1098             "attempt to overwrite string script_files with $file failed";
1099             }
1100 0         0 } else {
1101             $ARGS{'script_files'} = $file;
1102             }
1103 0         0 } else {
1104 0         0 _create_arrayref('script_files');
  0         0  
1105             push @{ $ARGS{'script_files'} }, $file;
1106 0         0 }
1107 0         0 _mb_required('0.18');
1108             return;
1109             } ## end sub script_files
1110              
1111 0     0   0 sub test_files {
1112 0 0       0 my $file = shift;
1113 0         0 if ( 'ARRAY' eq ref $file ) {
  0         0  
1114 0         0 foreach my $f ( @{$file} ) {
1115             test_files($f);
1116             }
1117             }
1118 0 0       0  
1119 0 0       0 if ( $file =~ /[*?]/ ) {
1120 0 0       0 if ( exists $ARGS{'test_files'} ) {
1121 0         0 if ( 'ARRAY' eq ref $ARGS{'test_files'} ) {
1122             croak 'cannot add a glob to a list of test_files';
1123 0         0 } else {
1124             croak 'attempt to overwrite string test_files failed';
1125             }
1126 0         0 } else {
1127             $ARGS{'test_files'} = $file;
1128             }
1129 0         0 } else {
1130 0         0 _create_arrayref('test_files');
  0         0  
1131             push @{ $ARGS{'test_files'} }, $file;
1132 0         0 }
1133 0         0 _mb_required('0.23');
1134             return;
1135             } ## end sub test_files
1136              
1137 0     0   0 sub tap_harness_args {
1138 0         0 my ($thargs) = shift;
1139 0         0 $ARGS{'tap_harness_args'} = $thargs;
1140 0         0 use_tap_harness(1);
1141             return;
1142             }
1143              
1144 1     1   4 sub build_class {
1145             my $further_class = $ARGS{build_class} = shift;
1146 1         82
1147 1 50       83 eval "require $further_class;";
1148             die "Can't find custom build class '$further_class'" if $@;
1149 0          
1150             copy_package($further_class, 'true');
1151 0          
1152             sync_interface($further_class);
1153 0          
1154 0           _mb_required('0.28');
1155             return;
1156             }
1157              
1158             sub subclass {
1159 0     0     # '$class->' will enable the further subclassing of custom subclass
1160 0           sync_interface($class->subclass(@_));
1161             return;
1162             }
1163              
1164 0     0     sub create_build_script {
1165 0           get_builder();
1166 0           $object->create_build_script;
1167             return $object;
1168             }
1169              
1170             # Required to get a builder for later use.
1171             sub get_builder {
1172 0 0   0      
  0            
1173 0           if ( $mb_required < 0.07 ) { $mb_required = '0.07'; }
1174             build_requires( 'Module::Build', $mb_required );
1175 0 0          
1176 0           if ( $mb_required > 0.2999 ) {
1177             configure_requires( 'Module::Build', $mb_required );
1178             }
1179 0 0          
1180 0           unless ( defined $object ) {
1181 0           $object = $class->new(%ARGS);
1182             $object_created = 1;
1183             }
1184 0            
1185 0           foreach my $type (@install_types) {
1186             $object->add_build_element($type);
1187             }
1188 0            
1189             return $object;
1190             } ## end sub get_builder
1191              
1192              
1193             sub sync_interface {
1194 0     0     # subclass needs be already 'required', as it will be introspected
1195             my $subclass = shift;
1196            
1197 0           # Properties of current builder class
1198             my @current_all_properties = $class->valid_properties;
1199            
1200 0           # Hashed variant for convenient checking of presense
  0            
1201             my %current_all_properties = map { $_ => '' } @current_all_properties;
1202            
1203            
1204 0           # Properties of subclass
1205 0           my @all_properties = $subclass->valid_properties;
  0            
1206 0           my %array_properties = map { $_ => '' } $subclass->array_properties;
  0            
1207             my %hash_properties = map { $_ => '' } $subclass->hash_properties;
1208 0          
1209             $class = $subclass;
1210 0          
1211             foreach my $property (@all_properties) {
1212 0 0         # Skipping already presented properties
1213             next if defined $current_all_properties{$property};
1214 0 0        
    0          
1215 0           if (defined $hash_properties{$property}) {
1216             additional_hash($property)
1217 0           } elsif (defined $array_properties{$property}) {
1218             additional_array($property)
1219 0           } else {
1220             additional_flag($property)
1221             }
1222             }
1223             }
1224              
1225              
1226 0     0     sub additional {
1227 0 0         my ($additional_type, $additional_name) = @_;
1228 0           if (not defined $additional_name) {
1229             croak 'additional requires a name.';
1230             }
1231 0 0        
1232 0           unless($class->valid_property($additional_name)) {
1233             croak "Property '$additional_name' not found in $class";
1234             }
1235 0 0        
    0          
    0          
1236 0           if ( 'array' eq lc $additional_type ) {
1237             $ARRAY{$additional_name} = 0.07;
1238 0           } elsif ( 'hash' eq lc $additional_type ) {
1239             $HASH{$additional_name} = [ 0.07, 0 ];
1240 0           } elsif ( 'flag' eq lc $additional_type ) {
1241             $FLAGS{$additional_name} = [ 0.07, 0 ];
1242 0           } else {
1243             croak 'additional requires two parameters: a type (array, hash, or flag) and a name.';
1244             }
1245 1     1   20
  1         5  
  1         357  
1246             no strict 'refs';
1247 0          
1248             my $symbol = "${export_to}::$additional_name";
1249            
1250 0           # Create a stub in the caller package
  0            
1251             \&{$symbol};
1252             }
1253              
1254 0     0     sub additional_array {
1255 0 0         my $additional_name = shift;
1256 0           croak 'additional_array needs a name to define' if not defined $additional_name;
1257             additional('array', $additional_name);
1258             }
1259              
1260 0     0     sub additional_flag {
1261 0 0         my $additional_name = shift;
1262 0           croak 'additional_flag needs a name to define' if not defined $additional_name;
1263             additional('flag', $additional_name);
1264             }
1265              
1266 0     0     sub additional_hash {
1267 0 0         my $additional_name = shift;
1268 0           croak 'additional_hash needs a name to define' if not defined $additional_name;
1269             additional('hash', $additional_name);
1270             }
1271              
1272 0     0     sub _debug_print {
1273 0           require Data::Dumper;
1274             my $d = Data::Dumper->new( [ \%ARGS, \$mb_required ],
1275 0           [qw(*ARGS *mb_required)] );
1276 0           print $d->Indent(1)->Dump();
1277             return;
1278             }
1279              
1280             1;