File Coverage

blib/lib/ExtUtils/MakeMaker/CPANfile.pm
Criterion Covered Total %
statement 26 93 27.9
branch 0 56 0.0
condition 0 5 0.0
subroutine 8 13 61.5
pod n/a
total 34 167 20.3


line stmt bran cond sub pod time code
1             package ExtUtils::MakeMaker::CPANfile;
2              
3 1     1   1074 use strict;
  1         3  
  1         38  
4 1     1   6 use warnings;
  1         3  
  1         40  
5 1     1   30109 use ExtUtils::MakeMaker ();
  1         193860  
  1         39  
6 1     1   786 use File::Spec::Functions qw/catfile rel2abs/;
  1         848  
  1         85  
7 1     1   4915 use Module::CPANfile;
  1         40745  
  1         45  
8 1     1   11 use version;
  1         2  
  1         13  
9              
10             our $VERSION = "0.07";
11              
12             sub import {
13 1     1   15 my $class = shift;
14 1         3 my $orig = \&ExtUtils::MakeMaker::WriteMakefile;
15             my $writer = sub {
16 0     0   0 my %params = @_;
17              
18             # Do nothing if not called from Makefile.PL
19 0         0 my ($caller, $file, $line) = caller;
20 0 0       0 (my $root = rel2abs($file)) =~ s/Makefile\.PL$//i or return;
21              
22 0 0       0 if (my $file = eval { Module::CPANfile->load(catfile($root, "cpanfile")) }) {
  0         0  
23 0         0 my $prereqs = $file->prereqs;
24              
25             # Runtime requires => PREREQ_PM
26 0         0 _merge(
27             \%params,
28             _get($prereqs, 'runtime', 'requires'),
29             'PREREQ_PM',
30             );
31              
32             # Build requires => BUILD_REQUIRES / PREREQ_PM
33 0 0       0 _merge(
34             \%params,
35             _get($prereqs, 'build', 'requires'),
36             _eumm('6.56') ? 'BUILD_REQUIRES' : 'PREREQ_PM',
37             );
38              
39             # Test requires => TEST_REQUIRES / BUILD_REQUIRES / PREREQ_PM
40 0 0       0 _merge(
    0          
41             \%params,
42             _get($prereqs, 'test', 'requires'),
43             _eumm('6.63_03') ? 'TEST_REQUIRES' :
44             _eumm('6.56') ? 'BUILD_REQUIRES' : 'PREREQ_PM',
45             );
46              
47             # Configure requires => CONFIGURE_REQUIRES / ignored
48 0 0       0 _merge(
49             \%params,
50             _get($prereqs, 'configure', 'requires'),
51             _eumm('6.52') ? 'CONFIGURE_REQUIRES' : undef,
52             );
53              
54             # Add myself to configure requires (if possible)
55 0 0       0 _merge(
56             \%params,
57             {'ExtUtils::MakeMaker::CPANfile' => $VERSION},
58             _eumm('6.52') ? 'CONFIGURE_REQUIRES' : undef,
59             );
60              
61             # Set dynamic_config to 0 if not set explicitly
62 0 0 0     0 if (!exists $params{META_ADD}{dynamic_config} &&
63             !exists $params{META_MERGE}{dynamic_config}) {
64 0         0 $params{META_MERGE}{dynamic_config} = 0;
65             }
66              
67             # recommends, suggests, conflicts
68 0         0 my $requires_2_0;
69 0         0 for my $type (qw/recommends suggests conflicts/) {
70 0         0 for my $phase (qw/configure build test runtime develop/) {
71 0 0       0 my %tmp = %{$params{META_MERGE}{prereqs}{$phase} || {}};
  0         0  
72 0         0 _merge(
73             \%tmp,
74             _get($prereqs, $phase, $type),
75             $type,
76             );
77 0 0       0 if ($tmp{$type}) {
78 0         0 $params{META_MERGE}{prereqs}{$phase} = \%tmp;
79 0         0 $requires_2_0 = 1;
80             }
81             }
82             }
83 0 0       0 if ($requires_2_0) { # for better recommends support
84 0   0     0 $params{META_MERGE}{"meta-spec"} ||= {version => 2};
85             }
86              
87             # XXX: better to use also META_MERGE when applicable?
88              
89             # As a small bonus, remove params that the installed version
90             # of EUMM doesn't know, so that we can always write them
91             # in Makefile.PL without caring about EUMM version.
92             # (EUMM warns if it finds unknown parameters.)
93             # As EUMM 6.17 is our prereq, we can safely ignore the keys
94             # defined before 6.17.
95             {
96 0 0       0 last if _eumm('6.66_03');
  0         0  
97 0 0       0 if (my $r = delete $params{TEST_REQUIRES}) {
98 0         0 _merge(\%params, $r, 'BUILD_REQUIRES');
99             }
100 0 0       0 last if _eumm('6.56');
101 0 0       0 if (my $r = delete $params{BUILD_REQUIRES}) {
102 0         0 _merge(\%params, $r, 'PREREQ_PM');
103             }
104              
105 0 0       0 last if _eumm('6.52');
106 0         0 delete $params{CONFIGURE_REQUIRES};
107              
108 0 0       0 last if _eumm('6.47_01');
109 0         0 delete $params{MIN_PERL_VERSION};
110              
111 0 0       0 last if _eumm('6.45_01');
112 0         0 delete $params{META_ADD};
113 0         0 delete $params{META_MERGE};
114              
115 0 0       0 last if _eumm('6.30_01');
116 0         0 delete $params{LICENSE};
117             }
118             } else {
119 0         0 print "cpanfile is not available: $@\n";
120 0         0 exit 0; # N/A
121             }
122              
123 0         0 $orig->(%params);
124 1         11 };
125             {
126 1     1   972 no warnings 'redefine';
  1         2  
  1         404  
  1         4  
127 1         29 *main::WriteMakefile =
128             *ExtUtils::MakeMaker::WriteMakefile = $writer;
129             }
130             }
131              
132             sub _eumm {
133 0     0     my $version = shift;
134 0 0         eval { ExtUtils::MakeMaker->VERSION($version) } ? 1 : 0;
  0            
135             }
136              
137             sub _get {
138 0     0     my $prereqs = shift;
139 0           eval { $prereqs->requirements_for(@_)->as_string_hash };
  0            
140             }
141              
142             sub _merge {
143 0     0     my ($params, $requires, $key) = @_;
144              
145 0 0         return unless $key;
146              
147 0 0         for (keys %{$requires || {}}) {
  0            
148 0           my $version = _normalize_version($requires->{$_});
149 0 0         next unless defined $version;
150              
151 0 0         if (not exists $params->{$key}{$_}) {
152 0           $params->{$key}{$_} = $version;
153             } else {
154 0           my $prev = $params->{$key}{$_};
155 0 0         if (version->parse($prev) < version->parse($version)) {
156 0           $params->{$key}{$_} = $version;
157             }
158             }
159             }
160             }
161              
162             sub _normalize_version {
163 0     0     my $version = shift;
164              
165             # shortcuts
166 0 0         return unless defined $version;
167 0 0         return $version unless $version =~ /\s/;
168              
169             # TODO: better range handling
170 0           $version =~ s/(?:>=|==)\s*//;
171 0           $version =~ s/,.+$//;
172              
173 0 0         return $version unless $version =~ /\s/;
174 0           return;
175             }
176              
177             1;
178              
179             __END__