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
|
|
|
|
|
|
|
|