| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Perl5::Dist::Backcompat; |
|
2
|
1
|
|
|
1
|
|
77905
|
use 5.14.0; |
|
|
1
|
|
|
|
|
3
|
|
|
3
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
50
|
|
|
4
|
|
|
|
|
|
|
our $VERSION = '0.10'; |
|
5
|
1
|
|
|
1
|
|
1277
|
use Archive::Tar; |
|
|
1
|
|
|
|
|
97775
|
|
|
|
1
|
|
|
|
|
78
|
|
|
6
|
1
|
|
|
1
|
|
12
|
use Carp qw( carp croak ); |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
45
|
|
|
7
|
1
|
|
|
1
|
|
5
|
use Cwd qw( cwd ); |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
35
|
|
|
8
|
1
|
|
|
1
|
|
540
|
use File::Copy qw( copy move ); |
|
|
1
|
|
|
|
|
4796
|
|
|
|
1
|
|
|
|
|
126
|
|
|
9
|
1
|
|
|
1
|
|
10
|
use File::Find qw( find ); |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
60
|
|
|
10
|
1
|
|
|
1
|
|
6
|
use File::Spec; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
30
|
|
|
11
|
1
|
|
|
1
|
|
1252
|
use File::Temp qw( tempdir ); |
|
|
1
|
|
|
|
|
10297
|
|
|
|
1
|
|
|
|
|
59
|
|
|
12
|
|
|
|
|
|
|
# From CPAN |
|
13
|
1
|
|
|
1
|
|
456
|
use CPAN::DistnameInfo; |
|
|
1
|
|
|
|
|
853
|
|
|
|
1
|
|
|
|
|
32
|
|
|
14
|
1
|
|
|
1
|
|
458
|
use Data::Dump qw( dd pp ); |
|
|
1
|
|
|
|
|
5249
|
|
|
|
1
|
|
|
|
|
90
|
|
|
15
|
1
|
|
|
1
|
|
597
|
use File::Copy::Recursive::Reduced qw( dircopy ); |
|
|
1
|
|
|
|
|
1674
|
|
|
|
1
|
|
|
|
|
3947
|
|
|
16
|
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
=head1 NAME |
|
18
|
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
Perl5::Dist::Backcompat - Analyze F distributions for CPAN release viability |
|
20
|
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
22
|
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
my $params = { |
|
24
|
|
|
|
|
|
|
perl_workdir => '/path/to/git/checkout/of/perl', |
|
25
|
|
|
|
|
|
|
verbose => 1, |
|
26
|
|
|
|
|
|
|
}; |
|
27
|
|
|
|
|
|
|
my $self = Perl5::Dist::Backcompat->new( $params ); |
|
28
|
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
30
|
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
This module serves as the backend for the program F which |
|
32
|
|
|
|
|
|
|
is also part of the F distribution. This document's |
|
33
|
|
|
|
|
|
|
focus is on documenting the methods used publicly in that program as well as |
|
34
|
|
|
|
|
|
|
internal methods and subroutines called by those public methods. For |
|
35
|
|
|
|
|
|
|
discussion on the problem which this distribution tries to solve, and how well |
|
36
|
|
|
|
|
|
|
it currently does that or not, please (i) read the plain-text F in the |
|
37
|
|
|
|
|
|
|
CPAN distribution or the F in the L
|
|
38
|
|
|
|
|
|
|
repository|https://github.com/jkeenan/p5-dist-backcompat>; and (ii) read the |
|
39
|
|
|
|
|
|
|
front-end program's documentation via F. |
|
40
|
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
=head1 PREREQUISITES |
|
42
|
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
F 5.14.0 or newer, with the following modules installed from CPAN: |
|
44
|
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
=over 4 |
|
46
|
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
=item * F |
|
48
|
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
=item * F |
|
50
|
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
=item * F |
|
52
|
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
=back |
|
54
|
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
=head1 PUBLIC METHODS |
|
56
|
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
=head2 C |
|
58
|
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
=over 4 |
|
60
|
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
=item * Purpose |
|
62
|
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
Perl5::Dist::Backcompat constructor. |
|
64
|
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
=item * Arguments |
|
66
|
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
my $self = Perl5::Dist::Backcompat->new( $params ); |
|
68
|
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
Single hash reference. Currently valid keys for this hashref are: |
|
70
|
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
=over 4 |
|
72
|
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
=item * C |
|
74
|
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
String holding absolute path to directory on disk where older F |
|
76
|
|
|
|
|
|
|
executables are stored. Defaults to C. |
|
77
|
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
=item * C |
|
79
|
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
String holding absolute path to directory holding a F checkout of Perl 5 |
|
81
|
|
|
|
|
|
|
core distribution and which has been built up through F. |
|
82
|
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
=item * C |
|
84
|
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
String holding absolute path to directory holding tarballs of the most recent |
|
86
|
|
|
|
|
|
|
CPAN releases of F distros. |
|
87
|
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
=item * C |
|
89
|
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
String holding path to file whose records list the versions of F against |
|
91
|
|
|
|
|
|
|
which we intend to test the tarballs of F distros found in |
|
92
|
|
|
|
|
|
|
C. In that file, these versions match this pattern: |
|
93
|
|
|
|
|
|
|
C<^perl5\.\d{1,2}\.\d1,2}$>, I C. (There is a default |
|
94
|
|
|
|
|
|
|
value which is only meaningful if you're starting in a F checkout of this |
|
95
|
|
|
|
|
|
|
F library.) |
|
96
|
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
=item * C |
|
98
|
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
String holding path to file whose records are pipe-delimited fields holding |
|
100
|
|
|
|
|
|
|
metadata about particular F distributions. |
|
101
|
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
# name|minimum_perl_version|needs_threaded_perl|needs_ppport_h|needs_threads_h|needs_shared_h |
|
103
|
|
|
|
|
|
|
threads|5.014000|1|1|1|0 |
|
104
|
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
(There is a default value which is only meaningful if you're starting in a |
|
106
|
|
|
|
|
|
|
F checkout of this F library.) |
|
107
|
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
=item * C |
|
109
|
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
String holding system's F. Defaults to C. |
|
111
|
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
=item * C |
|
113
|
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
Boolean. Extra output during operation. Defaults to off (C<0>), but |
|
115
|
|
|
|
|
|
|
recommended (C<1>). |
|
116
|
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
=back |
|
118
|
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
=item * Return Value |
|
120
|
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
Perl5::Dist::Backcompat object. |
|
122
|
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
=back |
|
124
|
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
=cut |
|
126
|
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
sub new { |
|
128
|
0
|
|
|
0
|
1
|
|
my ($class, $params) = @_; |
|
129
|
0
|
0
|
0
|
|
|
|
if (defined $params and ref($params) ne 'HASH') { |
|
130
|
0
|
|
|
|
|
|
croak "Argument supplied to constructor must be hashref"; |
|
131
|
|
|
|
|
|
|
} |
|
132
|
0
|
|
|
|
|
|
my %valid_params = map {$_ => 1} qw( |
|
|
0
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
verbose |
|
134
|
|
|
|
|
|
|
host |
|
135
|
|
|
|
|
|
|
path_to_perls |
|
136
|
|
|
|
|
|
|
perl_workdir |
|
137
|
|
|
|
|
|
|
tarball_dir |
|
138
|
|
|
|
|
|
|
older_perls_file |
|
139
|
|
|
|
|
|
|
distro_metadata_file |
|
140
|
|
|
|
|
|
|
); |
|
141
|
0
|
|
|
|
|
|
my @invalid_params = (); |
|
142
|
0
|
|
|
|
|
|
for my $p (keys %$params) { |
|
143
|
0
|
0
|
|
|
|
|
push @invalid_params, $p unless $valid_params{$p}; |
|
144
|
|
|
|
|
|
|
} |
|
145
|
0
|
0
|
|
|
|
|
if (@invalid_params) { |
|
146
|
0
|
|
|
|
|
|
my $msg = "Constructor parameter(s) @invalid_params not valid"; |
|
147
|
0
|
|
|
|
|
|
croak $msg; |
|
148
|
|
|
|
|
|
|
} |
|
149
|
|
|
|
|
|
|
croak "Must supply value for 'perl_workdir'" |
|
150
|
0
|
0
|
|
|
|
|
unless $params->{perl_workdir}; |
|
151
|
|
|
|
|
|
|
|
|
152
|
0
|
|
|
|
|
|
my $data = {}; |
|
153
|
0
|
|
|
|
|
|
for my $p (keys %valid_params) { |
|
154
|
0
|
0
|
|
|
|
|
$data->{$p} = (defined $params->{$p}) ? $params->{$p} : ''; |
|
155
|
|
|
|
|
|
|
} |
|
156
|
0
|
|
0
|
|
|
|
$data->{host} ||= 'dromedary.p5h.org'; |
|
157
|
0
|
|
0
|
|
|
|
$data->{path_to_perls} ||= '/media/Tux/perls-t/bin'; |
|
158
|
0
|
|
0
|
|
|
|
$data->{tarball_dir} ||= "$ENV{P5P_DIR}/dist-backcompat/tarballs"; |
|
159
|
0
|
|
0
|
|
|
|
$data->{older_perls_file} ||= File::Spec->catfile( |
|
160
|
|
|
|
|
|
|
'.', 'etc', 'dist-backcompat-older-perls.txt'); |
|
161
|
0
|
|
0
|
|
|
|
$data->{distro_metadata_file} ||= File::Spec->catfile( |
|
162
|
|
|
|
|
|
|
'.', 'etc', 'dist-backcompat-distro-metadata.txt'); |
|
163
|
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
croak "Could not locate directory $data->{path_to_perls} for perl executables" |
|
165
|
0
|
0
|
|
|
|
|
unless -d $data->{path_to_perls}; |
|
166
|
|
|
|
|
|
|
croak "Could not locate directory $data->{tarball_dir} for downloaded tarballs" |
|
167
|
0
|
0
|
|
|
|
|
unless -d $data->{tarball_dir}; |
|
168
|
|
|
|
|
|
|
|
|
169
|
0
|
|
|
|
|
|
return bless $data, $class; |
|
170
|
|
|
|
|
|
|
} |
|
171
|
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
=head2 C |
|
173
|
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
=over 4 |
|
175
|
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
=item * Purpose |
|
177
|
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
Guarantee that we can find the F executables we'll be using; the F |
|
179
|
|
|
|
|
|
|
checkout of the core distribution; metadata files and loading of data |
|
180
|
|
|
|
|
|
|
therefrom. |
|
181
|
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
=item * Arguments |
|
183
|
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
$self->init(); |
|
185
|
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
None; all data needed is found within the object. |
|
187
|
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
=item * Return Value |
|
189
|
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
Returns the object itself. |
|
191
|
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
=back |
|
193
|
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
=cut |
|
195
|
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
sub init { |
|
197
|
|
|
|
|
|
|
# From here on, we assume we're starting from the home directory of |
|
198
|
|
|
|
|
|
|
# someone with an account on Dromedary. |
|
199
|
|
|
|
|
|
|
|
|
200
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
|
201
|
|
|
|
|
|
|
|
|
202
|
0
|
|
|
|
|
|
my $currdir = cwd(); |
|
203
|
|
|
|
|
|
|
chdir $self->{perl_workdir} |
|
204
|
0
|
0
|
|
|
|
|
or croak "Unable to change to $self->{perl_workdir}"; |
|
205
|
|
|
|
|
|
|
|
|
206
|
0
|
|
|
|
|
|
my $describe = `git describe`; |
|
207
|
0
|
|
|
|
|
|
chomp($describe); |
|
208
|
0
|
0
|
|
|
|
|
croak "Unable to get value for 'git describe'" |
|
209
|
|
|
|
|
|
|
unless $describe; |
|
210
|
0
|
|
|
|
|
|
$self->{describe} = $describe; |
|
211
|
0
|
0
|
|
|
|
|
chdir $currdir or croak "Unable to change back to starting directory"; |
|
212
|
|
|
|
|
|
|
|
|
213
|
0
|
|
|
|
|
|
my $manifest = File::Spec->catfile($self->{perl_workdir}, 'MANIFEST'); |
|
214
|
0
|
0
|
|
|
|
|
croak "Could not locate $manifest" unless -f $manifest; |
|
215
|
0
|
|
|
|
|
|
$self->{manifest} = $manifest; |
|
216
|
|
|
|
|
|
|
|
|
217
|
0
|
|
|
|
|
|
my $maint_file = File::Spec->catfile($self->{perl_workdir}, 'Porting', 'Maintainers.pl'); |
|
218
|
0
|
|
|
|
|
|
require $maint_file; # to get %Modules in package Maintainers |
|
219
|
0
|
|
|
|
|
|
$self->{maint_file} = $maint_file; |
|
220
|
|
|
|
|
|
|
|
|
221
|
0
|
|
|
|
|
|
my $manilib_file = File::Spec->catfile($self->{perl_workdir}, 'Porting', 'manifest_lib.pl'); |
|
222
|
0
|
|
|
|
|
|
require $manilib_file; # to get function sort_manifest() |
|
223
|
0
|
|
|
|
|
|
$self->{manilib_file} = $manilib_file; |
|
224
|
|
|
|
|
|
|
|
|
225
|
0
|
|
|
|
|
|
my %distmodules = (); |
|
226
|
0
|
|
|
|
|
|
for my $m (keys %Maintainers::Modules) { |
|
227
|
0
|
0
|
|
|
|
|
if ($Maintainers::Modules{$m}{FILES} =~ m{dist/}) { |
|
228
|
0
|
|
|
|
|
|
$distmodules{$m} = $Maintainers::Modules{$m}; |
|
229
|
|
|
|
|
|
|
} |
|
230
|
|
|
|
|
|
|
} |
|
231
|
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
# Sanity checks; all modules under dist/ should be blead-upstream and have P5P |
|
233
|
|
|
|
|
|
|
# as maintainer. |
|
234
|
0
|
|
|
|
|
|
_sanity_check(\%distmodules, $self->{describe}, $self->{verbose}); |
|
235
|
0
|
|
|
|
|
|
$self->{distmodules} = \%distmodules; |
|
236
|
|
|
|
|
|
|
|
|
237
|
0
|
0
|
|
|
|
|
croak "Could not locate $self->{distro_metadata_file}" unless -f $self->{distro_metadata_file}; |
|
238
|
|
|
|
|
|
|
|
|
239
|
0
|
|
|
|
|
|
my %distro_metadata = (); |
|
240
|
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
open my $IN, '<', $self->{distro_metadata_file} |
|
242
|
0
|
0
|
|
|
|
|
or croak "Unable to open $self->{distro_metadata_file} for reading"; |
|
243
|
0
|
|
|
|
|
|
while (my $l = <$IN>) { |
|
244
|
0
|
|
|
|
|
|
chomp $l; |
|
245
|
0
|
0
|
|
|
|
|
next if $l =~ m{^(\#|\s*$)}; |
|
246
|
0
|
|
|
|
|
|
my @rowdata = split /\|/, $l; |
|
247
|
|
|
|
|
|
|
# Refine this later |
|
248
|
0
|
|
0
|
|
|
|
$distro_metadata{$rowdata[0]} = { |
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
249
|
|
|
|
|
|
|
minimum_perl_version => $rowdata[1] // '', |
|
250
|
|
|
|
|
|
|
needs_threaded_perl => $rowdata[2] // '', |
|
251
|
|
|
|
|
|
|
needs_ppport_h => $rowdata[3] // '', |
|
252
|
|
|
|
|
|
|
needs_threads_h => $rowdata[4] // '', |
|
253
|
|
|
|
|
|
|
needs_shared_h => $rowdata[5] // '', |
|
254
|
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
}; |
|
256
|
|
|
|
|
|
|
} |
|
257
|
0
|
0
|
|
|
|
|
close $IN or die "Unable to close $self->{distro_metadata_file} after reading: $!"; |
|
258
|
|
|
|
|
|
|
|
|
259
|
0
|
|
|
|
|
|
my $this = $self->identify_cpan_tarballs_with_makefile_pl(); |
|
260
|
0
|
|
|
|
|
|
for my $d (keys %{$this}) { |
|
|
0
|
|
|
|
|
|
|
|
261
|
0
|
|
|
|
|
|
$distro_metadata{$d}{tarball} = $this->{$d}->{tarball}; |
|
262
|
0
|
|
|
|
|
|
$distro_metadata{$d}{distvname} = $this->{$d}->{distvname}; |
|
263
|
|
|
|
|
|
|
} |
|
264
|
|
|
|
|
|
|
|
|
265
|
0
|
|
|
|
|
|
$self->{distro_metadata} = \%distro_metadata; |
|
266
|
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
croak "Could not locate $self->{older_perls_file}" |
|
268
|
0
|
0
|
|
|
|
|
unless -f $self->{older_perls_file}; |
|
269
|
|
|
|
|
|
|
|
|
270
|
0
|
|
|
|
|
|
return $self; |
|
271
|
|
|
|
|
|
|
} |
|
272
|
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
=head2 C |
|
274
|
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
=over 4 |
|
276
|
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
=item * Purpose |
|
278
|
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
Categorize each F distro in one of 4 categories based on the status and |
|
280
|
|
|
|
|
|
|
appropriateness of its F (if any). |
|
281
|
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
=item * Arguments |
|
283
|
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
$self->categorize_distros(); |
|
285
|
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
None; all data needed is already within the object. |
|
287
|
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
=item * Return Value |
|
289
|
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
Returns the object. |
|
291
|
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
=item * Comment |
|
293
|
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
Since our objective is to determine the CPAN release viability of code found |
|
295
|
|
|
|
|
|
|
within F distros in core, we need various ways to categorize those |
|
296
|
|
|
|
|
|
|
distros. This method will make a categorization based on the status of the |
|
297
|
|
|
|
|
|
|
distros's F. The categories will be mutually exclusive. By order |
|
298
|
|
|
|
|
|
|
of processing the categories will be: |
|
299
|
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
=item * |
|
301
|
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
B As based on an examination of C<%Maintainers::Modules> in |
|
303
|
|
|
|
|
|
|
F, at least one distro has no current CPAN release. |
|
304
|
|
|
|
|
|
|
Such modules will be categorized as C. |
|
305
|
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
=item * |
|
307
|
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
B Certain F distros have a CPAN release which contains a F. |
|
309
|
|
|
|
|
|
|
Such distros I also have a F in core; that F |
|
310
|
|
|
|
|
|
|
may or may not be functionally identical to that on CPAN. In either case, we |
|
311
|
|
|
|
|
|
|
shall make an assumption that the F found in the most recent CPAN |
|
312
|
|
|
|
|
|
|
release is the version to be preferred for the purpose of this program. Such |
|
313
|
|
|
|
|
|
|
distros will be categorized as C. |
|
314
|
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
B The following 3 categories should be considered I because, |
|
316
|
|
|
|
|
|
|
as the code in this methods is currently structured, all current F |
|
317
|
|
|
|
|
|
|
distros are categorized as either C or C. These categories |
|
318
|
|
|
|
|
|
|
may be removed in a future release. |
|
319
|
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
=over 4 |
|
321
|
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
=item * |
|
323
|
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
B Certain F distros have a F in core. Assuming that such a |
|
325
|
|
|
|
|
|
|
distro has not already been categorized as C, we will use that version |
|
326
|
|
|
|
|
|
|
in this program. Such distros will be categorized as C. |
|
327
|
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
=item * |
|
329
|
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
B If a F distro has no F either on CPAN or in core but, at |
|
331
|
|
|
|
|
|
|
the end of F in the Perl 5 build process does have a F |
|
332
|
|
|
|
|
|
|
generated by that process, we will categorize such a distro as C. |
|
333
|
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
=item * |
|
335
|
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
B The remaining F distros have a F neither on CPAN nor in |
|
337
|
|
|
|
|
|
|
core. For purpose of compilation in core they I have a F |
|
338
|
|
|
|
|
|
|
generated by core's F process, but this file, if created, does |
|
339
|
|
|
|
|
|
|
not appear to be retained on disk at the end of F. Such a distro might |
|
340
|
|
|
|
|
|
|
lack a F in its CPAN release because the CPAN releasor uses |
|
341
|
|
|
|
|
|
|
technology such as F to produce such a release and such |
|
342
|
|
|
|
|
|
|
technology does not require a F to be included in the CPAN |
|
343
|
|
|
|
|
|
|
tarball. At the present time we will categorize such distros as C and |
|
344
|
|
|
|
|
|
|
these will be skipped by subsequent methods. |
|
345
|
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
=back |
|
347
|
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
=back |
|
349
|
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
=cut |
|
351
|
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
sub categorize_distros { |
|
353
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
|
354
|
0
|
|
|
|
|
|
my %makefile_pl_status = (); |
|
355
|
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
# First, identify those dist/ distros which, on the basis of data in |
|
357
|
|
|
|
|
|
|
# Porting/Maintainers.PL, do not currently have CPAN releases. |
|
358
|
|
|
|
|
|
|
|
|
359
|
0
|
|
|
|
|
|
for my $m (keys %{$self->{distmodules}}) { |
|
|
0
|
|
|
|
|
|
|
|
360
|
0
|
0
|
|
|
|
|
if (! exists $self->{distmodules}->{$m}{DISTRIBUTION}) { |
|
361
|
0
|
|
|
|
|
|
my ($distname) = $self->{distmodules}->{$m}{FILES} =~ m{^dist/(.*)/?$}; |
|
362
|
0
|
|
|
|
|
|
$makefile_pl_status{$distname} = 'unreleased'; |
|
363
|
|
|
|
|
|
|
} |
|
364
|
|
|
|
|
|
|
} |
|
365
|
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
# Second, identify those dist/ distros which have their own hard-coded |
|
367
|
|
|
|
|
|
|
# Makefile.PLs in their CPAN releases. We'll call these 'cpan'. (We've |
|
368
|
|
|
|
|
|
|
# already done some of the work for this in |
|
369
|
|
|
|
|
|
|
# $self->identify_cpan_tarballs_with_makefile_pl() called from within |
|
370
|
|
|
|
|
|
|
# init(). The location of a distro's tarball is given by: |
|
371
|
|
|
|
|
|
|
# $self->{distro_metadata}->{$d}->{tarball}.) |
|
372
|
|
|
|
|
|
|
|
|
373
|
0
|
|
|
|
|
|
for my $d (keys %{$self->{distro_metadata}}) { |
|
|
0
|
|
|
|
|
|
|
|
374
|
0
|
0
|
|
|
|
|
if (! $makefile_pl_status{$d}) { |
|
375
|
0
|
|
|
|
|
|
my $tb = $self->{distro_metadata}->{$d}->{tarball}; |
|
376
|
0
|
|
|
|
|
|
my ($tar, $hasmpl); |
|
377
|
0
|
|
|
|
|
|
$tar = Archive::Tar->new($tb); |
|
378
|
0
|
0
|
|
|
|
|
croak "Unable to create Archive::Tar object for $d" unless defined $tar; |
|
379
|
0
|
|
|
|
|
|
$self->{distro_metadata}->{$d}->{tar} = $tar; |
|
380
|
|
|
|
|
|
|
$hasmpl = $self->{distro_metadata}->{$d}->{tar}->contains_file( |
|
381
|
0
|
|
|
|
|
|
File::Spec->catfile($self->{distro_metadata}->{$d}->{distvname},'Makefile.PL') |
|
382
|
|
|
|
|
|
|
); |
|
383
|
0
|
0
|
|
|
|
|
if ($hasmpl) { |
|
384
|
0
|
|
|
|
|
|
$makefile_pl_status{$d} = 'cpan'; |
|
385
|
|
|
|
|
|
|
} |
|
386
|
|
|
|
|
|
|
else { |
|
387
|
0
|
0
|
|
|
|
|
carp "$d Makefile.PL doubtful" unless $hasmpl; |
|
388
|
|
|
|
|
|
|
} |
|
389
|
|
|
|
|
|
|
} |
|
390
|
|
|
|
|
|
|
} |
|
391
|
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
# Third, identify those dist/ distros which have their own hard-coded |
|
393
|
|
|
|
|
|
|
# Makefile.PLs in the core distribution. We'll call these 'native'. |
|
394
|
|
|
|
|
|
|
|
|
395
|
0
|
|
|
|
|
|
my @sorted = read_manifest($self->{manifest}); |
|
396
|
|
|
|
|
|
|
|
|
397
|
0
|
|
|
|
|
|
for my $f (@sorted) { |
|
398
|
0
|
0
|
|
|
|
|
next unless $f =~ m{^dist/}; |
|
399
|
0
|
|
|
|
|
|
my $path = (split /\t+/, $f)[0]; |
|
400
|
0
|
0
|
|
|
|
|
if ($path =~ m{/(.*?)/Makefile\.PL$}) { |
|
401
|
0
|
|
|
|
|
|
my $distro = $1; |
|
402
|
|
|
|
|
|
|
$makefile_pl_status{$distro} = 'native' |
|
403
|
0
|
0
|
|
|
|
|
unless $makefile_pl_status{$distro}; |
|
404
|
|
|
|
|
|
|
} |
|
405
|
|
|
|
|
|
|
} |
|
406
|
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
# Fourth, identify those dist/ distros whose Makefile.PL is generated during |
|
408
|
|
|
|
|
|
|
# Perl's own 'make' process. |
|
409
|
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
my $get_generated_makefiles = sub { |
|
411
|
0
|
|
|
0
|
|
|
my $pattern = qr{dist/(.*?)/Makefile\.PL$}; |
|
412
|
0
|
0
|
|
|
|
|
if ( $File::Find::name =~ m{$pattern} ) { |
|
413
|
0
|
|
|
|
|
|
my $distro = $1; |
|
414
|
0
|
0
|
|
|
|
|
if (! $makefile_pl_status{$distro}) { |
|
415
|
0
|
|
|
|
|
|
$makefile_pl_status{$distro} = 'generated'; |
|
416
|
|
|
|
|
|
|
} |
|
417
|
|
|
|
|
|
|
} |
|
418
|
0
|
|
|
|
|
|
}; |
|
419
|
|
|
|
|
|
|
find( |
|
420
|
0
|
|
|
|
|
|
\&{$get_generated_makefiles}, |
|
421
|
0
|
|
|
|
|
|
File::Spec->catdir($self->{perl_workdir}, 'dist' ) |
|
422
|
|
|
|
|
|
|
); |
|
423
|
|
|
|
|
|
|
|
|
424
|
|
|
|
|
|
|
# Fifth, identify those dist/ distros whose Makefile.PLs are not yet |
|
425
|
|
|
|
|
|
|
# accounted for. |
|
426
|
|
|
|
|
|
|
|
|
427
|
0
|
|
|
|
|
|
for my $d (sort keys %{$self->{distmodules}}) { |
|
|
0
|
|
|
|
|
|
|
|
428
|
0
|
0
|
|
|
|
|
next unless exists $self->{distmodules}->{$d}{FILES}; |
|
429
|
0
|
|
|
|
|
|
my ($distname) = $self->{distmodules}->{$d}{FILES} =~ m{^dist/([^/]+)/?$}; |
|
430
|
0
|
0
|
|
|
|
|
if (! exists $makefile_pl_status{$distname}) { |
|
431
|
0
|
|
|
|
|
|
$makefile_pl_status{$distname} = 'tbd'; |
|
432
|
|
|
|
|
|
|
} |
|
433
|
|
|
|
|
|
|
} |
|
434
|
|
|
|
|
|
|
|
|
435
|
0
|
|
|
|
|
|
$self->{makefile_pl_status} = \%makefile_pl_status; |
|
436
|
0
|
|
|
|
|
|
return $self; |
|
437
|
|
|
|
|
|
|
} |
|
438
|
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
=head2 C |
|
440
|
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
=over 4 |
|
442
|
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
=item * Purpose |
|
444
|
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
Display a chart listing F distros in one column and the status of their |
|
446
|
|
|
|
|
|
|
respective Fs in the second column. |
|
447
|
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
=item * Arguments |
|
449
|
|
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
$self->show_makefile_pl_status(); |
|
451
|
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
None; this method simply displays data already present in the object. |
|
453
|
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
=item * Return Value |
|
455
|
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
Returns a true value when complete. |
|
457
|
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
=item * Comment |
|
459
|
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
Does nothing unless a true value for C was passed to C. |
|
461
|
|
|
|
|
|
|
|
|
462
|
|
|
|
|
|
|
=back |
|
463
|
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
=cut |
|
465
|
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
sub show_makefile_pl_status { |
|
467
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
|
468
|
0
|
|
|
|
|
|
my %counts; |
|
469
|
0
|
|
|
|
|
|
for my $module (sort keys %{$self->{makefile_pl_status}}) { |
|
|
0
|
|
|
|
|
|
|
|
470
|
0
|
|
|
|
|
|
$counts{$self->{makefile_pl_status}->{$module}}++; |
|
471
|
|
|
|
|
|
|
} |
|
472
|
0
|
0
|
|
|
|
|
if ($self->{verbose}) { |
|
473
|
0
|
|
|
|
|
|
for my $k (sort keys %counts) { |
|
474
|
0
|
|
|
|
|
|
printf " %-18s%4s\n" => ($k, $counts{$k}); |
|
475
|
|
|
|
|
|
|
} |
|
476
|
0
|
|
|
|
|
|
say ''; |
|
477
|
0
|
|
|
|
|
|
printf "%-24s%-12s\n" => ('Distribution', 'Status'); |
|
478
|
0
|
|
|
|
|
|
printf "%-24s%-12s\n" => ('------------', '------'); |
|
479
|
0
|
|
|
|
|
|
for my $module (sort keys %{$self->{makefile_pl_status}}) { |
|
|
0
|
|
|
|
|
|
|
|
480
|
0
|
|
|
|
|
|
printf "%-24s%-12s\n" => ($module, $self->{makefile_pl_status}->{$module}); |
|
481
|
|
|
|
|
|
|
} |
|
482
|
|
|
|
|
|
|
} |
|
483
|
0
|
|
|
|
|
|
return 1; |
|
484
|
|
|
|
|
|
|
} |
|
485
|
|
|
|
|
|
|
|
|
486
|
|
|
|
|
|
|
=head2 C |
|
487
|
|
|
|
|
|
|
|
|
488
|
|
|
|
|
|
|
=over 4 |
|
489
|
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
=item * Purpose |
|
491
|
|
|
|
|
|
|
|
|
492
|
|
|
|
|
|
|
Assemble the list of F distros which the program will actually test |
|
493
|
|
|
|
|
|
|
against older Fs. |
|
494
|
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
=item * Arguments |
|
496
|
|
|
|
|
|
|
|
|
497
|
|
|
|
|
|
|
my @distros_for_testing = $self->get_distros_for_testing( [ @distros_requested ] ); |
|
498
|
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
Single arrayref, optional (though recommended). If no arrayref is provided, |
|
500
|
|
|
|
|
|
|
then the program will test I F distros I those whose |
|
501
|
|
|
|
|
|
|
"Makefile.PL status" is C. |
|
502
|
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
=item * Return Value |
|
504
|
|
|
|
|
|
|
|
|
505
|
|
|
|
|
|
|
List holding distros to be tested. (This is provided for readability of the |
|
506
|
|
|
|
|
|
|
code, but the list will be stored within the object and subsequently |
|
507
|
|
|
|
|
|
|
referenced therefrom. |
|
508
|
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
=item * Comment |
|
510
|
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
In a production program, the list of distros selected for testing may be |
|
512
|
|
|
|
|
|
|
provided on the command-line and processed by C |
|
513
|
|
|
|
|
|
|
within that program. But it's only at this point that we need to add such a |
|
514
|
|
|
|
|
|
|
list to the object. |
|
515
|
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
=back |
|
517
|
|
|
|
|
|
|
|
|
518
|
|
|
|
|
|
|
=cut |
|
519
|
|
|
|
|
|
|
|
|
520
|
|
|
|
|
|
|
sub get_distros_for_testing { |
|
521
|
0
|
|
|
0
|
1
|
|
my ($self, $distros) = @_; |
|
522
|
0
|
0
|
|
|
|
|
if (defined $distros) { |
|
523
|
0
|
0
|
|
|
|
|
croak "Argument passed to get_distros_for_testing() must be arrayref" |
|
524
|
|
|
|
|
|
|
unless ref($distros) eq 'ARRAY'; |
|
525
|
|
|
|
|
|
|
} |
|
526
|
|
|
|
|
|
|
else { |
|
527
|
0
|
|
|
|
|
|
$distros = []; |
|
528
|
|
|
|
|
|
|
} |
|
529
|
0
|
|
|
|
|
|
my @distros_for_testing = (scalar @{$distros}) |
|
530
|
0
|
|
|
|
|
|
? @{$distros} |
|
531
|
0
|
|
|
|
|
|
: sort grep { $self->{makefile_pl_status}->{$_} ne 'unreleased' } |
|
532
|
0
|
0
|
|
|
|
|
keys %{$self->{makefile_pl_status}}; |
|
|
0
|
|
|
|
|
|
|
|
533
|
0
|
0
|
|
|
|
|
if ($self->{verbose}) { |
|
534
|
0
|
|
|
|
|
|
say "\nWill test ", scalar @distros_for_testing, |
|
535
|
|
|
|
|
|
|
" distros which have been presumably released to CPAN:"; |
|
536
|
0
|
|
|
|
|
|
say " $_" for @distros_for_testing; |
|
537
|
|
|
|
|
|
|
} |
|
538
|
0
|
|
|
|
|
|
$self->{distros_for_testing} = [ @distros_for_testing ]; |
|
539
|
0
|
|
|
|
|
|
return @distros_for_testing; |
|
540
|
|
|
|
|
|
|
} |
|
541
|
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
=head2 C |
|
543
|
|
|
|
|
|
|
|
|
544
|
|
|
|
|
|
|
=over 4 |
|
545
|
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
=item * Purpose |
|
547
|
|
|
|
|
|
|
|
|
548
|
|
|
|
|
|
|
Validate the paths and executability of the older perl versions against which |
|
549
|
|
|
|
|
|
|
we're going to test F distros. |
|
550
|
|
|
|
|
|
|
|
|
551
|
|
|
|
|
|
|
=item * Arguments |
|
552
|
|
|
|
|
|
|
|
|
553
|
|
|
|
|
|
|
my @perls = $self->validate_older_perls(); |
|
554
|
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
None; all necessary information is found within the object. |
|
556
|
|
|
|
|
|
|
|
|
557
|
|
|
|
|
|
|
=item * Return Value |
|
558
|
|
|
|
|
|
|
|
|
559
|
|
|
|
|
|
|
List holding older F executables against which distros will be tested. |
|
560
|
|
|
|
|
|
|
(This is provided for readability of the code, but the list will be stored |
|
561
|
|
|
|
|
|
|
within the object and subsequently referenced therefrom. |
|
562
|
|
|
|
|
|
|
|
|
563
|
|
|
|
|
|
|
=back |
|
564
|
|
|
|
|
|
|
|
|
565
|
|
|
|
|
|
|
=cut |
|
566
|
|
|
|
|
|
|
|
|
567
|
|
|
|
|
|
|
sub validate_older_perls { |
|
568
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
|
569
|
0
|
|
|
|
|
|
my @perllist = (); |
|
570
|
|
|
|
|
|
|
open my $IN1, '<', $self->{older_perls_file} |
|
571
|
0
|
0
|
|
|
|
|
or croak "Unable to open $self->{older_perls_file} for reading"; |
|
572
|
0
|
|
|
|
|
|
while (my $l = <$IN1>) { |
|
573
|
0
|
|
|
|
|
|
chomp $l; |
|
574
|
0
|
0
|
|
|
|
|
next if $l =~ m{^(\#|\s*$)}; |
|
575
|
0
|
|
|
|
|
|
push @perllist, $l; |
|
576
|
|
|
|
|
|
|
} |
|
577
|
0
|
0
|
|
|
|
|
close $IN1 |
|
578
|
|
|
|
|
|
|
or croak "Unable to close $self->{older_perls_file} after reading"; |
|
579
|
|
|
|
|
|
|
|
|
580
|
0
|
|
|
|
|
|
my @perls = (); |
|
581
|
|
|
|
|
|
|
|
|
582
|
0
|
|
|
|
|
|
for my $p (@perllist) { |
|
583
|
0
|
0
|
|
|
|
|
say "Locating $p executable ..." if $self->{verbose}; |
|
584
|
0
|
|
|
|
|
|
my $rv; |
|
585
|
0
|
|
|
|
|
|
my $path_to_perl = File::Spec->catfile($self->{path_to_perls}, $p); |
|
586
|
0
|
0
|
|
|
|
|
warn "Could not locate $path_to_perl" unless -e $path_to_perl; |
|
587
|
0
|
|
|
|
|
|
$rv = system(qq| $path_to_perl -v 1>/dev/null 2>&1 |); |
|
588
|
0
|
0
|
|
|
|
|
warn "Could not execute perl -v with $path_to_perl" if $rv; |
|
589
|
|
|
|
|
|
|
|
|
590
|
0
|
|
|
|
|
|
my ($major, $minor, $patch) = $p =~ m{^perl(5)\.(\d+)\.(\d+)$}; |
|
591
|
0
|
|
|
|
|
|
my $canon = sprintf "%s.%03d%03d" => ($major, $minor, $patch); |
|
592
|
|
|
|
|
|
|
|
|
593
|
0
|
|
|
|
|
|
push @perls, { |
|
594
|
|
|
|
|
|
|
version => $p, |
|
595
|
|
|
|
|
|
|
path => $path_to_perl, |
|
596
|
|
|
|
|
|
|
canon => $canon, |
|
597
|
|
|
|
|
|
|
}; |
|
598
|
|
|
|
|
|
|
} |
|
599
|
0
|
|
|
|
|
|
$self->{perls} = [ @perls ]; |
|
600
|
0
|
|
|
|
|
|
return @perls; |
|
601
|
|
|
|
|
|
|
} |
|
602
|
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
=head2 C |
|
604
|
|
|
|
|
|
|
|
|
605
|
|
|
|
|
|
|
=over 4 |
|
606
|
|
|
|
|
|
|
|
|
607
|
|
|
|
|
|
|
=item * Purpose |
|
608
|
|
|
|
|
|
|
|
|
609
|
|
|
|
|
|
|
Test a given F distro against each of the older Fs against which |
|
610
|
|
|
|
|
|
|
it is eligible to be tested. |
|
611
|
|
|
|
|
|
|
|
|
612
|
|
|
|
|
|
|
=item * Arguments |
|
613
|
|
|
|
|
|
|
|
|
614
|
|
|
|
|
|
|
$self->test_distros_against_older_perls('/path/to/debugging/directory'); |
|
615
|
|
|
|
|
|
|
|
|
616
|
|
|
|
|
|
|
String holding absolute path to an already created directory to which files |
|
617
|
|
|
|
|
|
|
can be written for later study and debugging. That directory I be |
|
618
|
|
|
|
|
|
|
created by C, but it should I be created with C<( |
|
619
|
|
|
|
|
|
|
CLEANUP => 1)>; the user should manually remove this directory after analysis |
|
620
|
|
|
|
|
|
|
is complete. |
|
621
|
|
|
|
|
|
|
|
|
622
|
|
|
|
|
|
|
=item * Return Value |
|
623
|
|
|
|
|
|
|
|
|
624
|
|
|
|
|
|
|
Returns the object itself. |
|
625
|
|
|
|
|
|
|
|
|
626
|
|
|
|
|
|
|
=item * Comment |
|
627
|
|
|
|
|
|
|
|
|
628
|
|
|
|
|
|
|
The method will loop over the selected distros, calling |
|
629
|
|
|
|
|
|
|
C against each. |
|
630
|
|
|
|
|
|
|
|
|
631
|
|
|
|
|
|
|
=back |
|
632
|
|
|
|
|
|
|
|
|
633
|
|
|
|
|
|
|
=cut |
|
634
|
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
sub test_distros_against_older_perls { |
|
636
|
0
|
|
|
0
|
1
|
|
my ($self, $results_dir) = @_; |
|
637
|
|
|
|
|
|
|
# $results_dir will be explicitly user-created to hold the results of |
|
638
|
|
|
|
|
|
|
# testing. |
|
639
|
|
|
|
|
|
|
|
|
640
|
|
|
|
|
|
|
# A program using Perl5::Dist::Backcompat won't need it until now. So even |
|
641
|
|
|
|
|
|
|
# if we feed that directory to the program via GetOptions, it doesn't need |
|
642
|
|
|
|
|
|
|
# to go into the constructor. It may be a tempdir but should almost |
|
643
|
|
|
|
|
|
|
# certainly NOT be set to get automatically cleaned up at program |
|
644
|
|
|
|
|
|
|
# conclusion (otherwise, where would you look for the results?). |
|
645
|
|
|
|
|
|
|
|
|
646
|
0
|
0
|
|
|
|
|
croak "Unable to locate $results_dir" unless -d $results_dir; |
|
647
|
0
|
|
|
|
|
|
$self->{results_dir} = $results_dir; |
|
648
|
|
|
|
|
|
|
|
|
649
|
|
|
|
|
|
|
# Calculations WILL, however, be done in a true tempdir. We'll create |
|
650
|
|
|
|
|
|
|
# subdirs and files underneath that tempdir. We'll cd to that tempdir but |
|
651
|
|
|
|
|
|
|
# come back to where we started before this method exits. |
|
652
|
|
|
|
|
|
|
# $self->{temp_top_dir} will be the conceptual equivalent of the top-level |
|
653
|
|
|
|
|
|
|
# directory in the Perl 5 distribution. Hence, underneath it we'll create |
|
654
|
|
|
|
|
|
|
# the equivalents of the F, F, etc., and |
|
655
|
|
|
|
|
|
|
# F directories. |
|
656
|
0
|
|
|
|
|
|
$self->{currdir} = cwd(); |
|
657
|
0
|
|
|
|
|
|
$self->{temp_top_dir} = tempdir( CLEANUP => 1 ); |
|
658
|
0
|
|
|
|
|
|
my %results = (); |
|
659
|
|
|
|
|
|
|
|
|
660
|
0
|
0
|
|
|
|
|
chdir $self->{temp_top_dir} or croak "Unable to change to tempdir $self->{temp_top_dir}"; |
|
661
|
|
|
|
|
|
|
|
|
662
|
|
|
|
|
|
|
# Create a 't/' directory underneath the temp_top_dir |
|
663
|
0
|
|
|
|
|
|
my $temp_t_dir = File::Spec->catdir($self->{temp_top_dir}, 't'); |
|
664
|
0
|
0
|
|
|
|
|
mkdir $temp_t_dir or croak "Unable to mkdir $temp_t_dir"; |
|
665
|
0
|
|
|
|
|
|
$self->{temp_t_dir} = $temp_t_dir; |
|
666
|
|
|
|
|
|
|
|
|
667
|
|
|
|
|
|
|
# Several of the F distros need F for their tests; copy |
|
668
|
|
|
|
|
|
|
# it into position once only. |
|
669
|
0
|
|
|
|
|
|
my $testpl = File::Spec->catfile($self->{perl_workdir}, 't', 'test.pl'); |
|
670
|
0
|
0
|
|
|
|
|
croak "Could not locate $testpl" unless -f $testpl; |
|
671
|
0
|
0
|
|
|
|
|
copy $testpl => $self->{temp_t_dir} or croak "Unable to copy $testpl"; |
|
672
|
|
|
|
|
|
|
|
|
673
|
|
|
|
|
|
|
# Create a 'dist/' directory underneath the temp_top_dir |
|
674
|
0
|
|
|
|
|
|
my $temp_dist_dir = File::Spec->catdir($self->{temp_top_dir}, 'dist'); |
|
675
|
0
|
0
|
|
|
|
|
mkdir $temp_dist_dir or croak "Unable to mkdir $temp_dist_dir"; |
|
676
|
0
|
|
|
|
|
|
$self->{temp_dist_dir} = $temp_dist_dir; |
|
677
|
|
|
|
|
|
|
|
|
678
|
0
|
|
|
|
|
|
for my $d (@{$self->{distros_for_testing}}) { |
|
|
0
|
|
|
|
|
|
|
|
679
|
0
|
|
|
|
|
|
my $this_result = $self->test_one_distro_against_older_perls($d); |
|
680
|
0
|
|
|
|
|
|
$results{$d} = $this_result; |
|
681
|
|
|
|
|
|
|
} |
|
682
|
|
|
|
|
|
|
|
|
683
|
|
|
|
|
|
|
chdir $self->{currdir} |
|
684
|
0
|
0
|
|
|
|
|
or croak "Unable to change back to starting directory $self->{currdir}"; |
|
685
|
|
|
|
|
|
|
|
|
686
|
0
|
|
|
|
|
|
$self->{results} = { %results }; |
|
687
|
0
|
|
|
|
|
|
return $self; |
|
688
|
|
|
|
|
|
|
|
|
689
|
|
|
|
|
|
|
# temp_top_dir should go out of scope here (though its path and those of |
|
690
|
|
|
|
|
|
|
# temp_t_dir and temp_dist_dir will still be in the object) |
|
691
|
|
|
|
|
|
|
} |
|
692
|
|
|
|
|
|
|
|
|
693
|
|
|
|
|
|
|
=head2 C |
|
694
|
|
|
|
|
|
|
|
|
695
|
|
|
|
|
|
|
=over 4 |
|
696
|
|
|
|
|
|
|
|
|
697
|
|
|
|
|
|
|
=item * Purpose |
|
698
|
|
|
|
|
|
|
|
|
699
|
|
|
|
|
|
|
Print on F: |
|
700
|
|
|
|
|
|
|
|
|
701
|
|
|
|
|
|
|
=over 4 |
|
702
|
|
|
|
|
|
|
|
|
703
|
|
|
|
|
|
|
=item 1 |
|
704
|
|
|
|
|
|
|
|
|
705
|
|
|
|
|
|
|
A list of the F files created for each |
|
706
|
|
|
|
|
|
|
tested distro (each file containing a summary of the results for that distro |
|
707
|
|
|
|
|
|
|
against each designated F executable. Example: |
|
708
|
|
|
|
|
|
|
|
|
709
|
|
|
|
|
|
|
Summaries |
|
710
|
|
|
|
|
|
|
--------- |
|
711
|
|
|
|
|
|
|
Attribute-Handlers /tmp/29LsgNfjVb/Attribute-Handlers.summary.txt |
|
712
|
|
|
|
|
|
|
Carp /tmp/29LsgNfjVb/Carp.summary.txt |
|
713
|
|
|
|
|
|
|
Data-Dumper /tmp/29LsgNfjVb/Data-Dumper.summary.txt |
|
714
|
|
|
|
|
|
|
... |
|
715
|
|
|
|
|
|
|
threads /tmp/29LsgNfjVb/threads.summary.txt |
|
716
|
|
|
|
|
|
|
threads-shared /tmp/29LsgNfjVb/threads-shared.summary.txt |
|
717
|
|
|
|
|
|
|
|
|
718
|
|
|
|
|
|
|
=item 2 |
|
719
|
|
|
|
|
|
|
|
|
720
|
|
|
|
|
|
|
A concatenation of all those files. |
|
721
|
|
|
|
|
|
|
|
|
722
|
|
|
|
|
|
|
=back |
|
723
|
|
|
|
|
|
|
|
|
724
|
|
|
|
|
|
|
=item * Arguments |
|
725
|
|
|
|
|
|
|
|
|
726
|
|
|
|
|
|
|
To simply list the summary files: |
|
727
|
|
|
|
|
|
|
|
|
728
|
|
|
|
|
|
|
$self->print_distro_summaries(); |
|
729
|
|
|
|
|
|
|
|
|
730
|
|
|
|
|
|
|
To list the summary files and concatenate their content: |
|
731
|
|
|
|
|
|
|
|
|
732
|
|
|
|
|
|
|
$self->print_distro_summaries( {cat_summaries => 1} ); |
|
733
|
|
|
|
|
|
|
|
|
734
|
|
|
|
|
|
|
=item * Return Value |
|
735
|
|
|
|
|
|
|
|
|
736
|
|
|
|
|
|
|
Returns true value upon success. |
|
737
|
|
|
|
|
|
|
|
|
738
|
|
|
|
|
|
|
=item * Comment |
|
739
|
|
|
|
|
|
|
|
|
740
|
|
|
|
|
|
|
You'll probably want to redirect or F F to a file for further |
|
741
|
|
|
|
|
|
|
study. |
|
742
|
|
|
|
|
|
|
|
|
743
|
|
|
|
|
|
|
=back |
|
744
|
|
|
|
|
|
|
|
|
745
|
|
|
|
|
|
|
=cut |
|
746
|
|
|
|
|
|
|
|
|
747
|
|
|
|
|
|
|
sub print_distro_summaries { |
|
748
|
0
|
|
|
0
|
1
|
|
my ($self, $args) = @_; |
|
749
|
0
|
0
|
|
|
|
|
if (! defined $args) { $args = {}; } |
|
|
0
|
|
|
|
|
|
|
|
750
|
|
|
|
|
|
|
else { |
|
751
|
0
|
0
|
|
|
|
|
croak "Argument to print_distro_summaries must be hashref" |
|
752
|
|
|
|
|
|
|
unless ref($args) eq 'HASH'; |
|
753
|
|
|
|
|
|
|
} |
|
754
|
|
|
|
|
|
|
|
|
755
|
0
|
|
|
|
|
|
say "\nSummaries"; |
|
756
|
0
|
|
|
|
|
|
say '-' x 9; |
|
757
|
0
|
|
|
|
|
|
for my $d (sort keys %{$self->{results}}) { |
|
|
0
|
|
|
|
|
|
|
|
758
|
0
|
|
|
|
|
|
$self->print_distro_summary($d); |
|
759
|
|
|
|
|
|
|
} |
|
760
|
|
|
|
|
|
|
|
|
761
|
0
|
0
|
|
|
|
|
if ($args->{cat_summaries}) { |
|
762
|
0
|
|
|
|
|
|
say "\nOverall (at $self->{describe}):"; |
|
763
|
0
|
|
|
|
|
|
for my $d (sort keys %{$self->{results}}) { |
|
|
0
|
|
|
|
|
|
|
|
764
|
0
|
|
|
|
|
|
say "\n$d"; |
|
765
|
0
|
|
|
|
|
|
dd $self->{results}->{$d}; |
|
766
|
|
|
|
|
|
|
} |
|
767
|
|
|
|
|
|
|
} |
|
768
|
0
|
|
|
|
|
|
return 1; |
|
769
|
|
|
|
|
|
|
} |
|
770
|
|
|
|
|
|
|
|
|
771
|
|
|
|
|
|
|
=head2 C |
|
772
|
|
|
|
|
|
|
|
|
773
|
|
|
|
|
|
|
=over 4 |
|
774
|
|
|
|
|
|
|
|
|
775
|
|
|
|
|
|
|
=item * Purpose |
|
776
|
|
|
|
|
|
|
|
|
777
|
|
|
|
|
|
|
Provide an overall summary of PASSes and FAILs in the distro/perl-version matrix. |
|
778
|
|
|
|
|
|
|
|
|
779
|
|
|
|
|
|
|
=item * Arguments |
|
780
|
|
|
|
|
|
|
|
|
781
|
|
|
|
|
|
|
None, all data needed is stored within object. |
|
782
|
|
|
|
|
|
|
|
|
783
|
|
|
|
|
|
|
=item * Return Value |
|
784
|
|
|
|
|
|
|
|
|
785
|
|
|
|
|
|
|
Array ref with 4 elements: overall attempts, overall passes, overall failures, |
|
786
|
|
|
|
|
|
|
overall skipped. |
|
787
|
|
|
|
|
|
|
|
|
788
|
|
|
|
|
|
|
=item * Comment |
|
789
|
|
|
|
|
|
|
|
|
790
|
|
|
|
|
|
|
An entry in the distro/perl-version matrix is skipped if there is a failure |
|
791
|
|
|
|
|
|
|
running F, which causes the C, C and C |
|
792
|
|
|
|
|
|
|
values to be all undefined. |
|
793
|
|
|
|
|
|
|
|
|
794
|
|
|
|
|
|
|
=back |
|
795
|
|
|
|
|
|
|
|
|
796
|
|
|
|
|
|
|
=cut |
|
797
|
|
|
|
|
|
|
|
|
798
|
|
|
|
|
|
|
sub tally_results { |
|
799
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
|
800
|
0
|
|
|
|
|
|
my $overall_attempts = 0; |
|
801
|
0
|
|
|
|
|
|
my $overall_successes = 0; |
|
802
|
0
|
|
|
|
|
|
my $overall_skipped = 0; |
|
803
|
0
|
|
|
|
|
|
for my $d (keys %{$self->{results}}) { |
|
|
0
|
|
|
|
|
|
|
|
804
|
0
|
|
|
|
|
|
for my $p (keys %{$self->{results}->{$d}}) { |
|
|
0
|
|
|
|
|
|
|
|
805
|
0
|
|
|
|
|
|
$overall_attempts++; |
|
806
|
0
|
|
|
|
|
|
my %thisrun = %{$self->{results}->{$d}->{$p}}; |
|
|
0
|
|
|
|
|
|
|
|
807
|
0
|
0
|
0
|
|
|
|
if ( |
|
|
|
0
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
808
|
|
|
|
|
|
|
! defined $thisrun{configure} and |
|
809
|
|
|
|
|
|
|
! defined $thisrun{make} and |
|
810
|
|
|
|
|
|
|
! defined $thisrun{test} |
|
811
|
|
|
|
|
|
|
) { |
|
812
|
0
|
|
|
|
|
|
$overall_skipped++; |
|
813
|
|
|
|
|
|
|
} |
|
814
|
|
|
|
|
|
|
elsif ( |
|
815
|
|
|
|
|
|
|
$thisrun{configure} and |
|
816
|
|
|
|
|
|
|
$thisrun{make} and |
|
817
|
|
|
|
|
|
|
$thisrun{test} |
|
818
|
|
|
|
|
|
|
) { |
|
819
|
0
|
|
|
|
|
|
$overall_successes++; |
|
820
|
|
|
|
|
|
|
} |
|
821
|
|
|
|
|
|
|
} |
|
822
|
|
|
|
|
|
|
} |
|
823
|
0
|
|
|
|
|
|
my $overall_failures = $overall_attempts - ($overall_successes + $overall_skipped); |
|
824
|
0
|
|
|
|
|
|
return [$overall_attempts, $overall_successes, $overall_failures, $overall_skipped]; |
|
825
|
|
|
|
|
|
|
} |
|
826
|
|
|
|
|
|
|
|
|
827
|
|
|
|
|
|
|
=head1 INTERNAL METHODS |
|
828
|
|
|
|
|
|
|
|
|
829
|
|
|
|
|
|
|
The following methods use the Perl5::Dist::Backcompat object but are called |
|
830
|
|
|
|
|
|
|
from within the public methods. Other than this library's author, you |
|
831
|
|
|
|
|
|
|
shouldn't need to explicitly call these methods (or the internal subroutines |
|
832
|
|
|
|
|
|
|
documented below) in a production program. The documentation here is mainly |
|
833
|
|
|
|
|
|
|
for people working on this distribution itself. |
|
834
|
|
|
|
|
|
|
|
|
835
|
|
|
|
|
|
|
=cut |
|
836
|
|
|
|
|
|
|
|
|
837
|
|
|
|
|
|
|
=head2 C |
|
838
|
|
|
|
|
|
|
|
|
839
|
|
|
|
|
|
|
=over 4 |
|
840
|
|
|
|
|
|
|
|
|
841
|
|
|
|
|
|
|
=item * Purpose |
|
842
|
|
|
|
|
|
|
|
|
843
|
|
|
|
|
|
|
Test one selected F distribution against the list of older Fs. |
|
844
|
|
|
|
|
|
|
|
|
845
|
|
|
|
|
|
|
=item * Arguments |
|
846
|
|
|
|
|
|
|
|
|
847
|
|
|
|
|
|
|
Single string holding the name of the distro in C format. |
|
848
|
|
|
|
|
|
|
|
|
849
|
|
|
|
|
|
|
=item * Return Value |
|
850
|
|
|
|
|
|
|
|
|
851
|
|
|
|
|
|
|
Hash reference with one element for each F executable selected: |
|
852
|
|
|
|
|
|
|
|
|
853
|
|
|
|
|
|
|
{ |
|
854
|
|
|
|
|
|
|
"5.006002" => { a => "perl5.6.2", configure => 1, make => 0, test => undef }, |
|
855
|
|
|
|
|
|
|
"5.008009" => { a => "perl5.8.9", configure => 1, make => 0, test => undef }, |
|
856
|
|
|
|
|
|
|
"5.010001" => { a => "perl5.10.1", configure => 1, make => 0, test => undef }, |
|
857
|
|
|
|
|
|
|
... |
|
858
|
|
|
|
|
|
|
"5.034000" => { a => "perl5.34.0", configure => 1, make => 1, test => 1 }, |
|
859
|
|
|
|
|
|
|
} |
|
860
|
|
|
|
|
|
|
|
|
861
|
|
|
|
|
|
|
The value of each element is a hashref with elements keyed as follows: |
|
862
|
|
|
|
|
|
|
|
|
863
|
|
|
|
|
|
|
=over 4 |
|
864
|
|
|
|
|
|
|
|
|
865
|
|
|
|
|
|
|
=item * C |
|
866
|
|
|
|
|
|
|
|
|
867
|
|
|
|
|
|
|
Perl version in the spelling used in the default value for C. |
|
868
|
|
|
|
|
|
|
|
|
869
|
|
|
|
|
|
|
=item * C |
|
870
|
|
|
|
|
|
|
|
|
871
|
|
|
|
|
|
|
The result of calling F: C<1> for success; C<0> for failure; |
|
872
|
|
|
|
|
|
|
C for not attempted. |
|
873
|
|
|
|
|
|
|
|
|
874
|
|
|
|
|
|
|
=item * C |
|
875
|
|
|
|
|
|
|
|
|
876
|
|
|
|
|
|
|
The result of calling F: same meaning as above. |
|
877
|
|
|
|
|
|
|
|
|
878
|
|
|
|
|
|
|
=item * C |
|
879
|
|
|
|
|
|
|
|
|
880
|
|
|
|
|
|
|
The result of calling F: same meaning as above. |
|
881
|
|
|
|
|
|
|
|
|
882
|
|
|
|
|
|
|
=back |
|
883
|
|
|
|
|
|
|
|
|
884
|
|
|
|
|
|
|
=back |
|
885
|
|
|
|
|
|
|
|
|
886
|
|
|
|
|
|
|
=cut |
|
887
|
|
|
|
|
|
|
|
|
888
|
|
|
|
|
|
|
sub test_one_distro_against_older_perls { |
|
889
|
0
|
|
|
0
|
1
|
|
my ($self, $d) = @_; |
|
890
|
0
|
0
|
|
|
|
|
say "Testing $d ..." if $self->{verbose}; |
|
891
|
0
|
|
|
|
|
|
my $this_result = {}; |
|
892
|
|
|
|
|
|
|
|
|
893
|
0
|
|
|
|
|
|
my $source_dir = File::Spec->catdir($self->{perl_workdir}, 'dist', $d); |
|
894
|
0
|
|
|
|
|
|
my $this_tempdir = File::Spec->catdir($self->{temp_dist_dir}, $d); |
|
895
|
0
|
0
|
|
|
|
|
mkdir $this_tempdir or croak "Unable to mkdir $this_tempdir"; |
|
896
|
0
|
0
|
|
|
|
|
dircopy($source_dir, $this_tempdir) |
|
897
|
|
|
|
|
|
|
or croak "Unable to copy $source_dir to $this_tempdir"; |
|
898
|
|
|
|
|
|
|
|
|
899
|
0
|
0
|
|
|
|
|
chdir $this_tempdir or croak "Unable to chdir to tempdir for dist/$d"; |
|
900
|
0
|
0
|
|
|
|
|
say " Now in $this_tempdir ..." if $self->{verbose}; |
|
901
|
|
|
|
|
|
|
|
|
902
|
0
|
|
|
|
|
|
THIS_PERL: for my $p (@{$self->{perls}}) { |
|
|
0
|
|
|
|
|
|
|
|
903
|
0
|
|
|
|
|
|
$this_result->{$p->{canon}}{a} = $p->{version}; |
|
904
|
|
|
|
|
|
|
# Skip this perl version if (a) distro has a specified |
|
905
|
|
|
|
|
|
|
# 'minimum_perl_version' and (b) that minimum version is greater than |
|
906
|
|
|
|
|
|
|
# the current perl we're running. |
|
907
|
0
|
0
|
0
|
|
|
|
if ( |
|
908
|
|
|
|
|
|
|
( |
|
909
|
|
|
|
|
|
|
$self->{distro_metadata}->{$d}{minimum_perl_version} |
|
910
|
|
|
|
|
|
|
and |
|
911
|
|
|
|
|
|
|
$self->{distro_metadata}->{$d}{minimum_perl_version} >= $p->{canon} |
|
912
|
|
|
|
|
|
|
) |
|
913
|
|
|
|
|
|
|
# Since we're currently using threaded perls for this |
|
914
|
|
|
|
|
|
|
# process, the following condition is not pertinent. But we'll |
|
915
|
|
|
|
|
|
|
# retain it here commented out for possible future use. |
|
916
|
|
|
|
|
|
|
# |
|
917
|
|
|
|
|
|
|
# or |
|
918
|
|
|
|
|
|
|
# ( |
|
919
|
|
|
|
|
|
|
# $self->{distro_metadata}->{$d}{needs_threaded_perl} |
|
920
|
|
|
|
|
|
|
# ) |
|
921
|
|
|
|
|
|
|
) { |
|
922
|
0
|
|
|
|
|
|
$this_result->{$p->{canon}}{configure} = undef; |
|
923
|
0
|
|
|
|
|
|
$this_result->{$p->{canon}}{make} = undef; |
|
924
|
0
|
|
|
|
|
|
$this_result->{$p->{canon}}{test} = undef; |
|
925
|
0
|
|
|
|
|
|
next THIS_PERL; |
|
926
|
|
|
|
|
|
|
} |
|
927
|
0
|
|
|
|
|
|
my $f = join '.' => ($d, $p->{version}, 'txt'); |
|
928
|
0
|
|
|
|
|
|
my $debugfile = File::Spec->catfile($self->{results_dir}, $f); |
|
929
|
0
|
0
|
|
|
|
|
if ($self->{verbose}) { |
|
930
|
0
|
|
|
|
|
|
say "Testing $d with $p->{canon} ($p->{version}); see $debugfile"; |
|
931
|
|
|
|
|
|
|
} |
|
932
|
|
|
|
|
|
|
|
|
933
|
|
|
|
|
|
|
# Here, assuming the distro ($d) is classified as 'cpan', we should |
|
934
|
|
|
|
|
|
|
# extract the Makefile.PL from the tar and swap that into the |
|
935
|
|
|
|
|
|
|
# following 'perl Makefile.PL' command. |
|
936
|
|
|
|
|
|
|
|
|
937
|
0
|
|
|
|
|
|
my ($rv, $cmd); |
|
938
|
0
|
|
|
|
|
|
my $this_makefile_pl = 'Makefile.PL'; |
|
939
|
0
|
0
|
|
|
|
|
if ($self->{makefile_pl_status}->{$d} eq 'cpan') { |
|
940
|
|
|
|
|
|
|
# We currently expect this branch to prevail 40 times |
|
941
|
0
|
0
|
|
|
|
|
if (-f $this_makefile_pl) { |
|
942
|
0
|
|
|
|
|
|
move $this_makefile_pl => "$this_makefile_pl.noncpan"; |
|
943
|
|
|
|
|
|
|
} |
|
944
|
0
|
|
|
|
|
|
my $source = File::Spec->catfile($self->{distro_metadata}->{$d}->{distvname},'Makefile.PL'); |
|
945
|
0
|
|
|
|
|
|
my $destination = File::Spec->catfile('.', $this_makefile_pl); |
|
946
|
|
|
|
|
|
|
my $extract = $self->{distro_metadata}->{$d}->{tar}->extract_file( |
|
947
|
0
|
|
|
|
|
|
$source, |
|
948
|
|
|
|
|
|
|
$destination, |
|
949
|
|
|
|
|
|
|
); |
|
950
|
0
|
0
|
|
|
|
|
croak "Unable to extract Makefile.PL from tarball" unless $extract; |
|
951
|
0
|
0
|
|
|
|
|
croak "Unable to locate extracted Makefile.PL" unless -f $destination; |
|
952
|
|
|
|
|
|
|
} |
|
953
|
0
|
0
|
|
|
|
|
croak "Could not locate $this_makefile_pl for configuring" unless -f $this_makefile_pl; |
|
954
|
|
|
|
|
|
|
|
|
955
|
0
|
0
|
|
|
|
|
if ($self->{distro_metadata}->{$d}->{needs_ppport_h}) { |
|
956
|
0
|
|
|
|
|
|
my $source = File::Spec->catfile($self->{distro_metadata}->{$d}->{distvname},'ppport.h'); |
|
957
|
0
|
|
|
|
|
|
my $destination = File::Spec->catfile('.', 'ppport.h'); |
|
958
|
|
|
|
|
|
|
my $extract = $self->{distro_metadata}->{$d}->{tar}->extract_file( |
|
959
|
0
|
|
|
|
|
|
$source, |
|
960
|
|
|
|
|
|
|
$destination, |
|
961
|
|
|
|
|
|
|
); |
|
962
|
0
|
0
|
|
|
|
|
croak "Unable to extract ppport.h from tarball" unless $extract; |
|
963
|
0
|
0
|
|
|
|
|
croak "Unable to locate extracted ppport.h" unless -f $destination; |
|
964
|
|
|
|
|
|
|
} |
|
965
|
|
|
|
|
|
|
|
|
966
|
0
|
0
|
|
|
|
|
if ($self->{distro_metadata}->{$d}->{needs_threads_h}) { |
|
967
|
0
|
|
|
|
|
|
my $source = File::Spec->catfile($self->{distro_metadata}->{$d}->{distvname},'threads.h'); |
|
968
|
0
|
|
|
|
|
|
my $destination = File::Spec->catfile('.', 'threads.h'); |
|
969
|
|
|
|
|
|
|
my $extract = $self->{distro_metadata}->{$d}->{tar}->extract_file( |
|
970
|
0
|
|
|
|
|
|
$source, |
|
971
|
|
|
|
|
|
|
$destination, |
|
972
|
|
|
|
|
|
|
); |
|
973
|
0
|
0
|
|
|
|
|
croak "Unable to extract threads.h from tarball" unless $extract; |
|
974
|
0
|
0
|
|
|
|
|
croak "Unable to locate extracted threads.h" unless -f $destination; |
|
975
|
|
|
|
|
|
|
} |
|
976
|
|
|
|
|
|
|
|
|
977
|
0
|
0
|
|
|
|
|
if ($self->{distro_metadata}->{$d}->{needs_shared_h}) { |
|
978
|
0
|
|
|
|
|
|
my $source = File::Spec->catfile($self->{distro_metadata}->{$d}->{distvname},'shared.h'); |
|
979
|
0
|
|
|
|
|
|
my $destination = File::Spec->catfile('.', 'shared.h'); |
|
980
|
|
|
|
|
|
|
my $extract = $self->{distro_metadata}->{$d}->{tar}->extract_file( |
|
981
|
0
|
|
|
|
|
|
$source, |
|
982
|
|
|
|
|
|
|
$destination, |
|
983
|
|
|
|
|
|
|
); |
|
984
|
0
|
0
|
|
|
|
|
croak "Unable to extract shared.h from tarball" unless $extract; |
|
985
|
0
|
0
|
|
|
|
|
croak "Unable to locate extracted shared.h" unless -f $destination; |
|
986
|
|
|
|
|
|
|
} |
|
987
|
|
|
|
|
|
|
|
|
988
|
0
|
|
|
|
|
|
$cmd = qq| $p->{path} $this_makefile_pl > $debugfile 2>&1 |; |
|
989
|
0
|
0
|
|
|
|
|
$rv = system($cmd) and say STDERR " FAIL: $d: $p->{canon}: Makefile.PL"; |
|
990
|
0
|
0
|
|
|
|
|
$this_result->{$p->{canon}}{configure} = $rv ? 0 : 1; undef $rv; |
|
|
0
|
|
|
|
|
|
|
|
991
|
0
|
0
|
|
|
|
|
unless ($this_result->{$p->{canon}}{configure}) { |
|
992
|
0
|
|
|
|
|
|
undef $this_result->{$p->{canon}}{make}; |
|
993
|
0
|
|
|
|
|
|
undef $this_result->{$p->{canon}}{test}; |
|
994
|
0
|
|
|
|
|
|
next THIS_PERL; |
|
995
|
|
|
|
|
|
|
} |
|
996
|
|
|
|
|
|
|
|
|
997
|
0
|
0
|
|
|
|
|
$rv = system(qq| make >> $debugfile 2>&1 |) |
|
998
|
|
|
|
|
|
|
and say STDERR " FAIL: $d: $p->{canon}: make"; |
|
999
|
0
|
0
|
|
|
|
|
$this_result->{$p->{canon}}{make} = $rv ? 0 : 1; undef $rv; |
|
|
0
|
|
|
|
|
|
|
|
1000
|
0
|
0
|
|
|
|
|
unless ($this_result->{$p->{canon}}{make}) { |
|
1001
|
0
|
|
|
|
|
|
undef $this_result->{$p->{canon}}{test}; |
|
1002
|
0
|
|
|
|
|
|
next THIS_PERL; |
|
1003
|
|
|
|
|
|
|
} |
|
1004
|
|
|
|
|
|
|
|
|
1005
|
0
|
0
|
|
|
|
|
$rv = system(qq| make test >> $debugfile 2>&1 |) |
|
1006
|
|
|
|
|
|
|
and say STDERR " FAIL: $d: $p->{canon}: make test"; |
|
1007
|
0
|
0
|
|
|
|
|
$this_result->{$p->{canon}}{test} = $rv ? 0 : 1; undef $rv; |
|
|
0
|
|
|
|
|
|
|
|
1008
|
|
|
|
|
|
|
|
|
1009
|
0
|
0
|
|
|
|
|
system(qq| make clean 2>&1 1>/dev/null |) |
|
1010
|
|
|
|
|
|
|
and carp "Unable to 'make clean' for $d"; |
|
1011
|
|
|
|
|
|
|
} |
|
1012
|
|
|
|
|
|
|
chdir $self->{temp_top_dir} |
|
1013
|
0
|
0
|
|
|
|
|
or croak "Unable to change to tempdir $self->{temp_top_dir}"; |
|
1014
|
0
|
|
|
|
|
|
return $this_result; |
|
1015
|
|
|
|
|
|
|
} |
|
1016
|
|
|
|
|
|
|
|
|
1017
|
|
|
|
|
|
|
=head2 C |
|
1018
|
|
|
|
|
|
|
|
|
1019
|
|
|
|
|
|
|
=over 4 |
|
1020
|
|
|
|
|
|
|
|
|
1021
|
|
|
|
|
|
|
=item * Purpose |
|
1022
|
|
|
|
|
|
|
|
|
1023
|
|
|
|
|
|
|
Create a file holding a summary of the results for running one distro against |
|
1024
|
|
|
|
|
|
|
each of the selected Fs. |
|
1025
|
|
|
|
|
|
|
|
|
1026
|
|
|
|
|
|
|
=item * Arguments |
|
1027
|
|
|
|
|
|
|
|
|
1028
|
|
|
|
|
|
|
$self->print_distro_summary('Some-Distro'); |
|
1029
|
|
|
|
|
|
|
|
|
1030
|
|
|
|
|
|
|
String holding name of distro. |
|
1031
|
|
|
|
|
|
|
|
|
1032
|
|
|
|
|
|
|
=item * Return Value |
|
1033
|
|
|
|
|
|
|
|
|
1034
|
|
|
|
|
|
|
Returns true value on success. |
|
1035
|
|
|
|
|
|
|
|
|
1036
|
|
|
|
|
|
|
=item * Comment |
|
1037
|
|
|
|
|
|
|
|
|
1038
|
|
|
|
|
|
|
File created will be named like F. |
|
1039
|
|
|
|
|
|
|
|
|
1040
|
|
|
|
|
|
|
File's content will look like this: |
|
1041
|
|
|
|
|
|
|
|
|
1042
|
|
|
|
|
|
|
Attribute-Handlers v5.35.7-48-g34e3587 |
|
1043
|
|
|
|
|
|
|
{ |
|
1044
|
|
|
|
|
|
|
"5.006002" => { a => "perl5.6.2", configure => 1, make => 0, test => undef }, |
|
1045
|
|
|
|
|
|
|
"5.008009" => { a => "perl5.8.9", configure => 1, make => 0, test => undef }, |
|
1046
|
|
|
|
|
|
|
"5.010001" => { a => "perl5.10.1", configure => 1, make => 0, test => undef }, |
|
1047
|
|
|
|
|
|
|
... |
|
1048
|
|
|
|
|
|
|
"5.034000" => { a => "perl5.34.0", configure => 1, make => 1, test => 1 }, |
|
1049
|
|
|
|
|
|
|
} |
|
1050
|
|
|
|
|
|
|
|
|
1051
|
|
|
|
|
|
|
=back |
|
1052
|
|
|
|
|
|
|
|
|
1053
|
|
|
|
|
|
|
=cut |
|
1054
|
|
|
|
|
|
|
|
|
1055
|
|
|
|
|
|
|
sub print_distro_summary { |
|
1056
|
0
|
|
|
0
|
1
|
|
my ($self, $d) = @_; |
|
1057
|
0
|
|
|
|
|
|
my $output = File::Spec->catfile($self->{results_dir}, "$d.summary.txt"); |
|
1058
|
0
|
0
|
|
|
|
|
open my $OUT, '>', $output or die "Unable to open $output for writing: $!"; |
|
1059
|
0
|
|
|
|
|
|
say $OUT sprintf "%-52s%20s" => ($d, $self->{describe}); |
|
1060
|
0
|
|
|
|
|
|
my $oldfh = select($OUT); |
|
1061
|
0
|
|
|
|
|
|
dd $self->{results}->{$d}; |
|
1062
|
0
|
0
|
|
|
|
|
close $OUT or die "Unable to close $output after writing: $!"; |
|
1063
|
0
|
|
|
|
|
|
select $oldfh; |
|
1064
|
|
|
|
|
|
|
say sprintf "%-24s%-48s" => ($d, $output) |
|
1065
|
0
|
0
|
|
|
|
|
if $self->{verbose}; |
|
1066
|
|
|
|
|
|
|
} |
|
1067
|
|
|
|
|
|
|
|
|
1068
|
|
|
|
|
|
|
# Check tarballs we have on disk to see whether they contain a |
|
1069
|
|
|
|
|
|
|
# Makefile.PL. |
|
1070
|
|
|
|
|
|
|
# $ pwd |
|
1071
|
|
|
|
|
|
|
# /home/jkeenan/learn/perl/p5p/dist-backcompat/tarballs/authors/id |
|
1072
|
|
|
|
|
|
|
# $ ls . | head -n 5 |
|
1073
|
|
|
|
|
|
|
# Attribute-Handlers-0.99.tar.gz |
|
1074
|
|
|
|
|
|
|
# autouse-1.11.tar.gz |
|
1075
|
|
|
|
|
|
|
# base-2.23.tar.gz |
|
1076
|
|
|
|
|
|
|
# Carp-1.50.tar.gz |
|
1077
|
|
|
|
|
|
|
# constant-1.33.tar.gz |
|
1078
|
|
|
|
|
|
|
|
|
1079
|
|
|
|
|
|
|
sub identify_cpan_tarballs_with_makefile_pl { |
|
1080
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
|
1081
|
0
|
|
|
|
|
|
my $id_dir = File::Spec->catdir($self->{tarball_dir}, 'authors', 'id'); |
|
1082
|
0
|
0
|
|
|
|
|
opendir my $DIR, $id_dir |
|
1083
|
|
|
|
|
|
|
or croak "Unable to open directory $id_dir for reading"; |
|
1084
|
0
|
|
|
|
|
|
my @available = map { File::Spec->catfile('authors', 'id', $_) } |
|
1085
|
0
|
|
|
|
|
|
grep { m/\.tar\.gz$/ } readdir $DIR; |
|
|
0
|
|
|
|
|
|
|
|
1086
|
0
|
0
|
|
|
|
|
closedir $DIR or croak "Unable to close directory $id_dir after reading"; |
|
1087
|
0
|
|
|
|
|
|
my %this = (); |
|
1088
|
0
|
|
|
|
|
|
for my $tb (@available) { |
|
1089
|
0
|
|
|
|
|
|
my $d = CPAN::DistnameInfo->new($tb); |
|
1090
|
0
|
|
|
|
|
|
my $dist = $d->dist; |
|
1091
|
0
|
|
|
|
|
|
my $distvname = $d->distvname; |
|
1092
|
0
|
|
|
|
|
|
$this{$dist}{tarball} = File::Spec->catfile($self->{tarball_dir}, $tb); |
|
1093
|
0
|
|
|
|
|
|
$this{$dist}{distvname} = $distvname; |
|
1094
|
|
|
|
|
|
|
} |
|
1095
|
0
|
|
|
|
|
|
return \%this; |
|
1096
|
|
|
|
|
|
|
} |
|
1097
|
|
|
|
|
|
|
|
|
1098
|
|
|
|
|
|
|
=head1 INTERNAL SUBROUTINES |
|
1099
|
|
|
|
|
|
|
|
|
1100
|
|
|
|
|
|
|
=head2 C |
|
1101
|
|
|
|
|
|
|
|
|
1102
|
|
|
|
|
|
|
=over 4 |
|
1103
|
|
|
|
|
|
|
|
|
1104
|
|
|
|
|
|
|
=item * Purpose |
|
1105
|
|
|
|
|
|
|
|
|
1106
|
|
|
|
|
|
|
Assure us that our environment is adequate to the task. |
|
1107
|
|
|
|
|
|
|
|
|
1108
|
|
|
|
|
|
|
=item * Arguments |
|
1109
|
|
|
|
|
|
|
|
|
1110
|
|
|
|
|
|
|
sanity_check(\%distmodules, $verbose); |
|
1111
|
|
|
|
|
|
|
|
|
1112
|
|
|
|
|
|
|
List of two scalars: (i) reference to the hash which is storing list of |
|
1113
|
|
|
|
|
|
|
F distros; (ii) verbosity selection. |
|
1114
|
|
|
|
|
|
|
|
|
1115
|
|
|
|
|
|
|
=item * Return Value |
|
1116
|
|
|
|
|
|
|
|
|
1117
|
|
|
|
|
|
|
Implicitly returns true on success, but does not otherwise return any |
|
1118
|
|
|
|
|
|
|
meaningful value. |
|
1119
|
|
|
|
|
|
|
|
|
1120
|
|
|
|
|
|
|
=item * Comment |
|
1121
|
|
|
|
|
|
|
|
|
1122
|
|
|
|
|
|
|
If verbosity is selected, displays the current git commit and other useful |
|
1123
|
|
|
|
|
|
|
information on F. |
|
1124
|
|
|
|
|
|
|
|
|
1125
|
|
|
|
|
|
|
=back |
|
1126
|
|
|
|
|
|
|
|
|
1127
|
|
|
|
|
|
|
=cut |
|
1128
|
|
|
|
|
|
|
|
|
1129
|
|
|
|
|
|
|
sub _sanity_check { |
|
1130
|
0
|
|
|
0
|
|
|
my ($distmodules, $describe, $verbose) = @_; |
|
1131
|
0
|
|
|
|
|
|
for my $m (keys %{$distmodules}) { |
|
|
0
|
|
|
|
|
|
|
|
1132
|
0
|
0
|
|
|
|
|
if ($distmodules->{$m}{UPSTREAM} ne 'blead') { |
|
1133
|
0
|
|
|
|
|
|
warn "Distro $m has UPSTREAM other than 'blead'"; |
|
1134
|
|
|
|
|
|
|
} |
|
1135
|
0
|
0
|
|
|
|
|
if ($distmodules->{$m}{MAINTAINER} ne 'P5P') { |
|
1136
|
0
|
|
|
|
|
|
warn "Distro $m has MAINTAINER other than 'P5P'"; |
|
1137
|
|
|
|
|
|
|
} |
|
1138
|
|
|
|
|
|
|
} |
|
1139
|
|
|
|
|
|
|
|
|
1140
|
0
|
0
|
|
|
|
|
if ($verbose) { |
|
1141
|
0
|
|
|
|
|
|
say "p5-dist-backcompat"; |
|
1142
|
0
|
|
|
|
|
|
my $ldescribe = length $describe; |
|
1143
|
|
|
|
|
|
|
my $message = q|Found | . |
|
1144
|
0
|
|
|
|
|
|
(scalar keys %{$distmodules}) . |
|
|
0
|
|
|
|
|
|
|
|
1145
|
|
|
|
|
|
|
q| 'dist/' entries in %Maintainers::Modules|; |
|
1146
|
0
|
|
|
|
|
|
my $lmessage = length $message; |
|
1147
|
0
|
|
|
|
|
|
my $ldiff = $lmessage - $ldescribe; |
|
1148
|
0
|
|
|
|
|
|
say sprintf "%-${ldiff}s%s" => ('Results at commit:', $describe); |
|
1149
|
0
|
|
|
|
|
|
say "\n$message"; |
|
1150
|
|
|
|
|
|
|
} |
|
1151
|
0
|
|
|
|
|
|
return 1; |
|
1152
|
|
|
|
|
|
|
} |
|
1153
|
|
|
|
|
|
|
|
|
1154
|
|
|
|
|
|
|
=head2 C |
|
1155
|
|
|
|
|
|
|
|
|
1156
|
|
|
|
|
|
|
=over 4 |
|
1157
|
|
|
|
|
|
|
|
|
1158
|
|
|
|
|
|
|
=item * Purpose |
|
1159
|
|
|
|
|
|
|
|
|
1160
|
|
|
|
|
|
|
Get a sorted list of all files in F (without their descriptions). |
|
1161
|
|
|
|
|
|
|
|
|
1162
|
|
|
|
|
|
|
=item * Arguments |
|
1163
|
|
|
|
|
|
|
|
|
1164
|
|
|
|
|
|
|
read_manifest('/path/to/MANIFEST'); |
|
1165
|
|
|
|
|
|
|
|
|
1166
|
|
|
|
|
|
|
One scalar: the path to F in a git checkout of the Perl 5 core distribution. |
|
1167
|
|
|
|
|
|
|
|
|
1168
|
|
|
|
|
|
|
=item * Return Value |
|
1169
|
|
|
|
|
|
|
|
|
1170
|
|
|
|
|
|
|
List (sorted) of all files in F. |
|
1171
|
|
|
|
|
|
|
|
|
1172
|
|
|
|
|
|
|
=item * Comment |
|
1173
|
|
|
|
|
|
|
|
|
1174
|
|
|
|
|
|
|
Depends on C from F. |
|
1175
|
|
|
|
|
|
|
|
|
1176
|
|
|
|
|
|
|
(This is so elementary and useful that it should probably be in F!) |
|
1177
|
|
|
|
|
|
|
|
|
1178
|
|
|
|
|
|
|
=back |
|
1179
|
|
|
|
|
|
|
|
|
1180
|
|
|
|
|
|
|
=cut |
|
1181
|
|
|
|
|
|
|
|
|
1182
|
|
|
|
|
|
|
sub read_manifest { |
|
1183
|
0
|
|
|
0
|
1
|
|
my $manifest = shift; |
|
1184
|
0
|
0
|
|
|
|
|
open(my $IN, '<', $manifest) or die("Can't read '$manifest': $!"); |
|
1185
|
0
|
|
|
|
|
|
my @manifest = <$IN>; |
|
1186
|
0
|
0
|
|
|
|
|
close($IN) or die($!); |
|
1187
|
0
|
|
|
|
|
|
chomp(@manifest); |
|
1188
|
|
|
|
|
|
|
|
|
1189
|
0
|
|
|
|
|
|
my %seen= ( '' => 1 ); # filter out blank lines |
|
1190
|
0
|
|
|
|
|
|
return grep { !$seen{$_}++ } sort_manifest(@manifest); |
|
|
0
|
|
|
|
|
|
|
|
1191
|
|
|
|
|
|
|
} |
|
1192
|
|
|
|
|
|
|
|
|
1193
|
|
|
|
|
|
|
1; |
|
1194
|
|
|
|
|
|
|
|