File Coverage

blib/lib/ExtUtils/MakeMaker/CPANfile.pm
Criterion Covered Total %
statement 26 110 23.6
branch 0 66 0.0
condition 0 3 0.0
subroutine 8 13 61.5
pod n/a
total 34 192 17.7


line stmt bran cond sub pod time code
1             package ExtUtils::MakeMaker::CPANfile;
2              
3 1     1   600 use strict;
  1         2  
  1         24  
4 1     1   5 use warnings;
  1         1  
  1         21  
5 1     1   645 use ExtUtils::MakeMaker ();
  1         94238  
  1         28  
6 1     1   353 use File::Spec::Functions qw/catfile rel2abs/;
  1         654  
  1         62  
7 1     1   397 use Module::CPANfile;
  1         12833  
  1         56  
8 1     1   8 use version;
  1         3  
  1         6  
9              
10             our $VERSION = "0.09";
11              
12             sub import {
13 1     1   24 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             # stash prereqs, which is already converted
85 0         0 my $tmp_prereqs = delete $params{META_MERGE}{prereqs};
86              
87 0         0 require CPAN::Meta::Converter;
88 0         0 for my $key (qw/META_ADD META_MERGE/) {
89 0 0       0 next unless %{$params{$key} || {}};
  0 0       0  
90 0         0 my $converter = CPAN::Meta::Converter->new($params{$key}, default_version => 1.4);
91 0         0 $params{$key} = $converter->upgrade_fragment;
92             }
93              
94 0 0       0 if ($params{META_MERGE}{prereqs}) {
95 0         0 require CPAN::Meta::Requirements;
96 0 0       0 for my $phase (keys %{$tmp_prereqs || {}}) {
  0         0  
97 0 0       0 for my $rel (keys %{$tmp_prereqs->{$phase} || {}}) {
  0         0  
98 0         0 my $req1 = CPAN::Meta::Requirements->from_string_hash($tmp_prereqs->{$phase}{$rel});
99 0         0 my $req2 = CPAN::Meta::Requirements->from_string_hash($params{META_MERGE}{prereqs}{$phase}{$rel});
100 0         0 $req1->add_requirements($req2);
101 0         0 $params{META_MERGE}{prereqs}{$phase} = $req1->as_string_hash;
102             }
103             }
104             } else {
105 0         0 $params{META_MERGE}{prereqs} = $tmp_prereqs;
106             }
107             }
108              
109             # XXX: better to use also META_MERGE when applicable?
110              
111             # As a small bonus, remove params that the installed version
112             # of EUMM doesn't know, so that we can always write them
113             # in Makefile.PL without caring about EUMM version.
114             # (EUMM warns if it finds unknown parameters.)
115             # As EUMM 6.17 is our prereq, we can safely ignore the keys
116             # defined before 6.17.
117             {
118 0 0       0 last if _eumm('6.66_03');
  0         0  
119 0 0       0 if (my $r = delete $params{TEST_REQUIRES}) {
120 0         0 _merge(\%params, $r, 'BUILD_REQUIRES');
121             }
122 0 0       0 last if _eumm('6.56');
123 0 0       0 if (my $r = delete $params{BUILD_REQUIRES}) {
124 0         0 _merge(\%params, $r, 'PREREQ_PM');
125             }
126              
127 0 0       0 last if _eumm('6.52');
128 0         0 delete $params{CONFIGURE_REQUIRES};
129              
130 0 0       0 last if _eumm('6.47_01');
131 0         0 delete $params{MIN_PERL_VERSION};
132              
133 0 0       0 last if _eumm('6.45_01');
134 0         0 delete $params{META_ADD};
135 0         0 delete $params{META_MERGE};
136              
137 0 0       0 last if _eumm('6.30_01');
138 0         0 delete $params{LICENSE};
139             }
140             } else {
141 0         0 print "cpanfile is not available: $@\n";
142 0         0 exit 0; # N/A
143             }
144              
145 0         0 $orig->(%params);
146 1         5 };
147             {
148 1     1   685 no warnings 'redefine';
  1         2  
  1         350  
  1         3  
149 1         20 *main::WriteMakefile =
150             *ExtUtils::MakeMaker::WriteMakefile = $writer;
151             }
152             }
153              
154             sub _eumm {
155 0     0     my $version = shift;
156 0 0         eval { ExtUtils::MakeMaker->VERSION($version) } ? 1 : 0;
  0            
157             }
158              
159             sub _get {
160 0     0     my $prereqs = shift;
161 0           eval { $prereqs->requirements_for(@_)->as_string_hash };
  0            
162             }
163              
164             sub _merge {
165 0     0     my ($params, $requires, $key) = @_;
166              
167 0 0         return unless $key;
168              
169 0 0         for (keys %{$requires || {}}) {
  0            
170 0           my $version = _normalize_version($requires->{$_});
171 0 0         next unless defined $version;
172              
173 0 0         if (not exists $params->{$key}{$_}) {
174 0           $params->{$key}{$_} = $version;
175             } else {
176 0           my $prev = $params->{$key}{$_};
177 0 0         if (version->parse($prev) < version->parse($version)) {
178 0           $params->{$key}{$_} = $version;
179             }
180             }
181             }
182             }
183              
184             sub _normalize_version {
185 0     0     my $version = shift;
186              
187             # shortcuts
188 0 0         return unless defined $version;
189 0 0         return $version unless $version =~ /\s/;
190              
191             # TODO: better range handling
192 0           $version =~ s/(?:>=|==)\s*//;
193 0           $version =~ s/,.+$//;
194              
195 0 0         return $version unless $version =~ /\s/;
196 0           return;
197             }
198              
199             1;
200              
201             __END__