line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Perl::Dist::Util::Toolchain; |
2
|
|
|
|
|
|
|
|
3
|
2
|
|
|
2
|
|
700926
|
use 5.005; |
|
2
|
|
|
|
|
8
|
|
|
2
|
|
|
|
|
81
|
|
4
|
2
|
|
|
2
|
|
12
|
use strict; |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
58
|
|
5
|
2
|
|
|
2
|
|
9
|
use Carp (); |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
38
|
|
6
|
2
|
|
|
2
|
|
919
|
use Params::Util qw{ _HASH _ARRAY }; |
|
2
|
|
|
|
|
3684
|
|
|
2
|
|
|
|
|
151
|
|
7
|
2
|
|
|
2
|
|
9513
|
use Module::CoreList (); |
|
2
|
|
|
|
|
259457
|
|
|
2
|
|
|
|
|
1184
|
|
8
|
2
|
|
|
2
|
|
2378
|
use IO::Capture::Stdout (); |
|
2
|
|
|
|
|
5414
|
|
|
2
|
|
|
|
|
52
|
|
9
|
2
|
|
|
2
|
|
60363
|
use IO::Capture::Stderr (); |
|
2
|
|
|
|
|
1602
|
|
|
2
|
|
|
|
|
51
|
|
10
|
2
|
|
|
2
|
|
1960
|
use Process::Delegatable (); |
|
2
|
|
|
|
|
52715
|
|
|
2
|
|
|
|
|
47
|
|
11
|
2
|
|
|
2
|
|
19
|
use Process::Storable (); |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
30
|
|
12
|
2
|
|
|
2
|
|
128434
|
use Process (); |
|
2
|
|
|
|
|
560
|
|
|
2
|
|
|
|
|
64
|
|
13
|
|
|
|
|
|
|
|
14
|
2
|
|
|
2
|
|
13
|
use vars qw{$VERSION @ISA @DELEGATE}; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
286
|
|
15
|
|
|
|
|
|
|
BEGIN { |
16
|
2
|
|
|
2
|
|
5
|
$VERSION = '1.16'; |
17
|
2
|
|
|
|
|
59
|
@ISA = qw{ |
18
|
|
|
|
|
|
|
Process::Delegatable |
19
|
|
|
|
|
|
|
Process::Storable |
20
|
|
|
|
|
|
|
Process |
21
|
|
|
|
|
|
|
}; |
22
|
2
|
|
|
|
|
4
|
@DELEGATE = (); |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
# Automatically handle delegation within the test suite |
25
|
2
|
50
|
|
|
|
16
|
if ( $ENV{HARNESS_ACTIVE} ) { |
26
|
2
|
|
|
|
|
12
|
require Probe::Perl; |
27
|
2
|
|
|
|
|
17
|
@DELEGATE = ( |
28
|
|
|
|
|
|
|
Probe::Perl->find_perl_interpreter, '-Mblib', |
29
|
|
|
|
|
|
|
); |
30
|
|
|
|
|
|
|
} |
31
|
|
|
|
|
|
|
} |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
my %MODULES = ( |
34
|
|
|
|
|
|
|
'5.008008' => [ qw{ |
35
|
|
|
|
|
|
|
ExtUtils::MakeMaker |
36
|
|
|
|
|
|
|
File::Path |
37
|
|
|
|
|
|
|
ExtUtils::Command |
38
|
|
|
|
|
|
|
Win32API::File |
39
|
|
|
|
|
|
|
ExtUtils::Install |
40
|
|
|
|
|
|
|
ExtUtils::Manifest |
41
|
|
|
|
|
|
|
Test::Harness |
42
|
|
|
|
|
|
|
Test::Simple |
43
|
|
|
|
|
|
|
ExtUtils::CBuilder |
44
|
|
|
|
|
|
|
ExtUtils::ParseXS |
45
|
|
|
|
|
|
|
version |
46
|
|
|
|
|
|
|
Scalar::Util |
47
|
|
|
|
|
|
|
Compress::Raw::Zlib |
48
|
|
|
|
|
|
|
Compress::Raw::Bzip2 |
49
|
|
|
|
|
|
|
IO::Compress::Base |
50
|
|
|
|
|
|
|
Compress::Bzip2 |
51
|
|
|
|
|
|
|
IO::Zlib |
52
|
|
|
|
|
|
|
File::Spec |
53
|
|
|
|
|
|
|
File::Temp |
54
|
|
|
|
|
|
|
Win32::WinError |
55
|
|
|
|
|
|
|
Win32API::Registry |
56
|
|
|
|
|
|
|
Win32::TieRegistry |
57
|
|
|
|
|
|
|
File::HomeDir |
58
|
|
|
|
|
|
|
File::Which |
59
|
|
|
|
|
|
|
Archive::Zip |
60
|
|
|
|
|
|
|
Package::Constants |
61
|
|
|
|
|
|
|
IO::String |
62
|
|
|
|
|
|
|
Archive::Tar |
63
|
|
|
|
|
|
|
Compress::unLZMA |
64
|
|
|
|
|
|
|
Parse::CPAN::Meta |
65
|
|
|
|
|
|
|
YAML |
66
|
|
|
|
|
|
|
Net::FTP |
67
|
|
|
|
|
|
|
Digest::MD5 |
68
|
|
|
|
|
|
|
Digest::SHA1 |
69
|
|
|
|
|
|
|
Digest::SHA |
70
|
|
|
|
|
|
|
Module::Build |
71
|
|
|
|
|
|
|
Term::Cap |
72
|
|
|
|
|
|
|
CPAN |
73
|
|
|
|
|
|
|
Term::ReadKey |
74
|
|
|
|
|
|
|
Term::ReadLine::Perl |
75
|
|
|
|
|
|
|
Text::Glob |
76
|
|
|
|
|
|
|
Data::Dumper |
77
|
|
|
|
|
|
|
URI |
78
|
|
|
|
|
|
|
HTML::Tagset |
79
|
|
|
|
|
|
|
HTML::Parser |
80
|
|
|
|
|
|
|
LWP::UserAgent |
81
|
|
|
|
|
|
|
} ], |
82
|
|
|
|
|
|
|
); |
83
|
|
|
|
|
|
|
$MODULES{'5.010000'} = $MODULES{'5.008008'}; |
84
|
|
|
|
|
|
|
$MODULES{'5.008009'} = $MODULES{'5.008008'}; |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
my %CORELIST = ( |
87
|
|
|
|
|
|
|
'5.008008' => '5.008008', |
88
|
|
|
|
|
|
|
'5.008009' => '5.008008', |
89
|
|
|
|
|
|
|
'5.010000' => '5.010000', |
90
|
|
|
|
|
|
|
); |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
##################################################################### |
97
|
|
|
|
|
|
|
# Constructor and Accessors |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
sub new { |
100
|
1
|
|
|
1
|
1
|
109
|
my $class = shift; |
101
|
1
|
|
|
|
|
6
|
my $self = bless { @_ }, $class; |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
# Check the Perl version |
104
|
1
|
50
|
|
|
|
6
|
unless ( defined $self->perl_version ) { |
105
|
0
|
|
|
|
|
0
|
Carp::croak("Did not provide a perl_version param"); |
106
|
|
|
|
|
|
|
} |
107
|
1
|
50
|
|
|
|
6
|
unless ( defined $self->{cpan} ) { |
108
|
0
|
|
|
|
|
0
|
Carp::croak("Did not provide a cpan param"); |
109
|
|
|
|
|
|
|
} |
110
|
1
|
50
|
|
|
|
3
|
unless ( $MODULES{$self->perl_version} ) { |
111
|
0
|
|
|
|
|
0
|
Carp::croak("Perl version '" . $self->perl_version . "' is not supported in $class"); |
112
|
|
|
|
|
|
|
} |
113
|
1
|
50
|
|
|
|
4
|
unless ( $CORELIST{$self->perl_version} ) { |
114
|
0
|
|
|
|
|
0
|
Carp::croak("Perl version '" . $self->perl_version . "' is not supported in $class"); |
115
|
|
|
|
|
|
|
} |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
# Populate the modules array if needed |
118
|
1
|
50
|
|
|
|
9
|
unless ( _ARRAY($self->{modules}) ) { |
119
|
0
|
|
|
|
|
0
|
$self->{modules} = $MODULES{$self->perl_version}; |
120
|
|
|
|
|
|
|
} |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
# Confirm we can find the corelist for the Perl version |
123
|
1
|
|
|
|
|
4
|
my $corelist_version = $CORELIST{$self->perl_version}; |
124
|
1
|
|
33
|
|
|
8
|
$self->{corelist} = $Module::CoreList::version{$corelist_version} |
125
|
|
|
|
|
|
|
|| $Module::CoreList::version{$corelist_version+0}; |
126
|
1
|
50
|
|
|
|
9
|
unless ( _HASH($self->{corelist}) ) { |
127
|
1
|
|
|
|
|
4
|
Carp::croak("Failed to find module core versions for Perl " . $self->perl_version); |
128
|
|
|
|
|
|
|
} |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
# Check forced dists, if applicable |
131
|
0
|
0
|
0
|
|
|
0
|
if ( $self->{force} and ! _HASH($self->{force}) ) { |
132
|
0
|
|
|
|
|
0
|
Carp::croak("The force param must be a HASH reference"); |
133
|
|
|
|
|
|
|
} |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
# Create the distribution array |
136
|
0
|
|
|
|
|
0
|
$self->{dists} = []; |
137
|
|
|
|
|
|
|
|
138
|
0
|
|
|
|
|
0
|
return $self; |
139
|
|
|
|
|
|
|
} |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
sub perl_version { |
142
|
5
|
|
|
5
|
0
|
658
|
$_[0]->{perl_version}; |
143
|
|
|
|
|
|
|
} |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
sub modules { |
146
|
0
|
|
|
0
|
0
|
|
@{$_[0]->{modules}}; |
|
0
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
} |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
sub dists { |
150
|
0
|
|
|
0
|
0
|
|
@{$_[0]->{dists}}; |
|
0
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
} |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
sub errstr { |
154
|
0
|
|
|
0
|
0
|
|
$_[0]->{errstr}; |
155
|
|
|
|
|
|
|
} |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
sub prepare { |
158
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
# Squash all output that CPAN might spew during this process |
161
|
0
|
|
|
|
|
|
my $stdout = IO::Capture::Stdout->new; |
162
|
0
|
|
|
|
|
|
my $stderr = IO::Capture::Stderr->new; |
163
|
0
|
|
|
|
|
|
$stdout->start; |
164
|
0
|
|
|
|
|
|
$stderr->start; |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
# Load the CPAN client |
167
|
0
|
|
|
|
|
|
require CPAN; |
168
|
0
|
|
|
|
|
|
CPAN->import(); |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
# Load the latest index |
171
|
0
|
|
|
|
|
|
eval { |
172
|
0
|
|
|
0
|
|
|
local $SIG{__WARN__} = sub { 1 }; |
|
0
|
|
|
|
|
|
|
173
|
0
|
0
|
|
|
|
|
CPAN::HandleConfig->load unless $CPAN::Config_loaded++; |
174
|
0
|
|
|
|
|
|
$CPAN::Config->{'urllist'} = [ $self->{cpan} ]; |
175
|
0
|
|
|
|
|
|
$CPAN::Config->{'use_sqlite'} = q[0]; |
176
|
0
|
|
|
|
|
|
CPAN::Index->reload; |
177
|
|
|
|
|
|
|
}; |
178
|
|
|
|
|
|
|
|
179
|
0
|
|
|
|
|
|
$stdout->stop; |
180
|
0
|
|
|
|
|
|
$stderr->stop; |
181
|
|
|
|
|
|
|
|
182
|
0
|
0
|
|
|
|
|
return $@ ? '' : 1; |
183
|
|
|
|
|
|
|
} |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
sub run { |
186
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
# Squash all output that CPAN might spew during this process |
189
|
0
|
|
|
|
|
|
my $stdout = IO::Capture::Stdout->new; |
190
|
0
|
|
|
|
|
|
my $stderr = IO::Capture::Stderr->new; |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
# Find the module |
193
|
0
|
|
|
|
|
|
my $core = delete $self->{corelist}; |
194
|
|
|
|
|
|
|
|
195
|
0
|
|
|
|
|
|
$stdout->start; $stderr->start; |
|
0
|
|
|
|
|
|
|
196
|
0
|
0
|
|
|
|
|
CPAN::HandleConfig->load unless $CPAN::Config_loaded++; |
197
|
0
|
|
|
|
|
|
$CPAN::Config->{'urllist'} = [ $self->{cpan} ]; |
198
|
0
|
|
|
|
|
|
$CPAN::Config->{'use_sqlite'} = q[0]; |
199
|
0
|
|
|
|
|
|
$stdout->stop; $stderr->stop; |
|
0
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
|
201
|
0
|
|
|
|
|
|
foreach my $name ( @{$self->{modules}} ) { |
|
0
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
# Shortcut if forced |
203
|
0
|
0
|
|
|
|
|
if ( $self->{force}->{$name} ) { |
204
|
0
|
|
|
|
|
|
push @{$self->{dists}}, $self->{force}->{$name}; |
|
0
|
|
|
|
|
|
|
205
|
0
|
|
|
|
|
|
next; |
206
|
|
|
|
|
|
|
} |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
# Get the CPAN object for the module, covering any output. |
209
|
0
|
|
|
|
|
|
$stdout->start; $stderr->start; |
|
0
|
|
|
|
|
|
|
210
|
0
|
|
|
|
|
|
my $module = CPAN::Shell->expand('Module', $name); |
211
|
0
|
|
|
|
|
|
$stdout->stop; $stderr->stop; |
|
0
|
|
|
|
|
|
|
212
|
0
|
0
|
|
|
|
|
unless ( $module ) { |
213
|
0
|
|
|
|
|
|
die "Failed to find '$name'"; |
214
|
|
|
|
|
|
|
} |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
# Ignore modules that don't need to be updated |
217
|
0
|
|
|
|
|
|
my $core_version = $core->{$name}; |
218
|
0
|
0
|
0
|
|
|
|
if ( defined $core_version and $core_version =~ /_/ ) { |
219
|
|
|
|
|
|
|
# Sometimes, the core contains a developer |
220
|
|
|
|
|
|
|
# version. For the purposes of this comparison |
221
|
|
|
|
|
|
|
# it should be safe to "round down". |
222
|
0
|
|
|
|
|
|
$core_version =~ s/_.+$//; |
223
|
|
|
|
|
|
|
} |
224
|
0
|
|
|
|
|
|
my $cpan_version = $module->cpan_version; |
225
|
0
|
0
|
|
|
|
|
unless ( defined $cpan_version ) { |
226
|
0
|
|
|
|
|
|
next; |
227
|
|
|
|
|
|
|
} |
228
|
0
|
0
|
0
|
|
|
|
if ( defined $core_version and $core_version >= $cpan_version ) { |
229
|
0
|
|
|
|
|
|
next; |
230
|
|
|
|
|
|
|
} |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
# Filter out already seen dists |
233
|
0
|
|
|
|
|
|
my $file = $module->cpan_file; |
234
|
0
|
|
|
|
|
|
$file =~ s/^[A-Z]\/[A-Z][A-Z]\///; |
235
|
0
|
|
|
|
|
|
push @{$self->{dists}}, $file; |
|
0
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
} |
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
# Remove duplicates |
239
|
0
|
|
|
|
|
|
my %seen = (); |
240
|
0
|
|
|
|
|
|
@{$self->{dists}} = grep { ! $seen{$_}++ } @{$self->{dists}}; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
|
242
|
0
|
|
|
|
|
|
return 1; |
243
|
|
|
|
|
|
|
} |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
sub delegate { |
246
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
247
|
0
|
0
|
|
|
|
|
unless ( $self->{delegated} ) { |
248
|
0
|
|
|
|
|
|
$self->SUPER::delegate( @DELEGATE ); |
249
|
0
|
|
|
|
|
|
$self->{delegated} = 1; |
250
|
|
|
|
|
|
|
} |
251
|
0
|
|
|
|
|
|
return 1; |
252
|
|
|
|
|
|
|
} |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
sub delegated { |
255
|
0
|
|
|
0
|
0
|
|
$_[0]->{delegated}; |
256
|
|
|
|
|
|
|
} |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
1; |
259
|
|
|
|
|
|
|
|