line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
33
|
|
|
33
|
|
80505
|
use strict; |
|
33
|
|
|
|
|
35
|
|
|
33
|
|
|
|
|
1375
|
|
2
|
|
|
|
|
|
|
package CPAN::Reporter; |
3
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
our $VERSION = '1.2017'; |
5
|
|
|
|
|
|
|
|
6
|
33
|
|
|
33
|
|
106
|
use Config; |
|
33
|
|
|
|
|
32
|
|
|
33
|
|
|
|
|
1067
|
|
7
|
33
|
|
|
33
|
|
13819
|
use Capture::Tiny qw/ capture tee_merged /; |
|
33
|
|
|
|
|
134974
|
|
|
33
|
|
|
|
|
1858
|
|
8
|
33
|
|
|
33
|
|
143
|
use CPAN 1.94 (); |
|
33
|
|
|
|
|
492
|
|
|
33
|
|
|
|
|
509
|
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
|
11
|
33
|
|
|
33
|
|
12975
|
use CPAN::Version (); |
|
33
|
|
|
|
|
40078
|
|
|
33
|
|
|
|
|
695
|
|
12
|
33
|
|
|
33
|
|
152
|
use File::Basename qw/basename dirname/; |
|
33
|
|
|
|
|
42
|
|
|
33
|
|
|
|
|
1561
|
|
13
|
33
|
|
|
33
|
|
121
|
use File::Find (); |
|
33
|
|
|
|
|
36
|
|
|
33
|
|
|
|
|
332
|
|
14
|
33
|
|
|
33
|
|
108
|
use File::HomeDir (); |
|
33
|
|
|
|
|
35
|
|
|
33
|
|
|
|
|
508
|
|
15
|
33
|
|
|
33
|
|
93
|
use File::Path qw/mkpath rmtree/; |
|
33
|
|
|
|
|
31
|
|
|
33
|
|
|
|
|
1415
|
|
16
|
33
|
|
|
33
|
|
109
|
use File::Spec 3.19 (); |
|
33
|
|
|
|
|
597
|
|
|
33
|
|
|
|
|
640
|
|
17
|
33
|
|
|
33
|
|
98
|
use File::Temp 0.16 qw/tempdir/; |
|
33
|
|
|
|
|
519
|
|
|
33
|
|
|
|
|
1043
|
|
18
|
33
|
|
|
33
|
|
1354
|
use IO::File (); |
|
33
|
|
|
|
|
1960
|
|
|
33
|
|
|
|
|
387
|
|
19
|
33
|
|
|
33
|
|
13402
|
use Parse::CPAN::Meta (); |
|
33
|
|
|
|
|
24540
|
|
|
33
|
|
|
|
|
509
|
|
20
|
33
|
|
|
33
|
|
824
|
use Probe::Perl (); |
|
33
|
|
|
|
|
1830
|
|
|
33
|
|
|
|
|
471
|
|
21
|
33
|
|
|
33
|
|
4679
|
use Test::Reporter 1.54 (); |
|
33
|
|
|
|
|
23881
|
|
|
33
|
|
|
|
|
442
|
|
22
|
33
|
|
|
33
|
|
13470
|
use CPAN::Reporter::Config (); |
|
33
|
|
|
|
|
72
|
|
|
33
|
|
|
|
|
687
|
|
23
|
33
|
|
|
33
|
|
13306
|
use CPAN::Reporter::History (); |
|
33
|
|
|
|
|
74
|
|
|
33
|
|
|
|
|
647
|
|
24
|
33
|
|
|
33
|
|
11553
|
use CPAN::Reporter::PrereqCheck (); |
|
33
|
|
|
|
|
67
|
|
|
33
|
|
|
|
|
623
|
|
25
|
|
|
|
|
|
|
|
26
|
33
|
|
|
33
|
|
132
|
use constant MAX_OUTPUT_LENGTH => 1_000_000; |
|
33
|
|
|
|
|
33
|
|
|
33
|
|
|
|
|
1868
|
|
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
|
33
|
33
|
|
|
33
|
|
13393
|
use Devel::Autoflush 0.04 (); |
|
33
|
|
|
|
|
1074
|
|
|
33
|
|
|
|
|
176851
|
|
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
my $Autoflush_Lib = tempdir( |
36
|
|
|
|
|
|
|
"CPAN-Reporter-lib-XXXX", TMPDIR => 1, CLEANUP => 1 |
37
|
|
|
|
|
|
|
); |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
_file_copy_quiet( |
40
|
|
|
|
|
|
|
$INC{'Devel/Autoflush.pm'}, |
41
|
|
|
|
|
|
|
File::Spec->catfile( $Autoflush_Lib, qw/Devel Autoflush.pm/ ) |
42
|
|
|
|
|
|
|
) or undef $Autoflush_Lib; |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
sub configure { |
49
|
2
|
|
|
2
|
0
|
7825
|
goto &CPAN::Reporter::Config::_configure; |
50
|
|
|
|
|
|
|
} |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
sub grade_make { |
53
|
16
|
|
|
16
|
0
|
1108
|
my @args = @_; |
54
|
16
|
100
|
|
|
|
111
|
my $result = _init_result( 'make', @args ) or return; |
55
|
15
|
|
|
|
|
72
|
_compute_make_grade($result); |
56
|
15
|
100
|
|
|
|
57
|
if ( $result->{grade} eq 'discard' ) { |
57
|
|
|
|
|
|
|
$CPAN::Frontend->myprint( |
58
|
|
|
|
|
|
|
"\nCPAN::Reporter: test results were not valid, $result->{grade_msg}.\n\n", |
59
|
4
|
|
|
|
|
92
|
$result->{prereq_pm}, "\n", |
60
|
|
|
|
|
|
|
"Test report will not be sent" |
61
|
|
|
|
|
|
|
); |
62
|
4
|
100
|
|
|
|
211
|
CPAN::Reporter::History::_record_history( $result ) |
63
|
|
|
|
|
|
|
if not CPAN::Reporter::History::_is_duplicate( $result ); |
64
|
|
|
|
|
|
|
} |
65
|
|
|
|
|
|
|
else { |
66
|
11
|
|
|
|
|
75
|
_print_grade_msg($result->{make_cmd}, $result); |
67
|
11
|
100
|
|
|
|
56
|
if ( $result->{grade} ne 'pass' ) { _dispatch_report( $result ) } |
|
9
|
|
|
|
|
37
|
|
68
|
|
|
|
|
|
|
} |
69
|
15
|
|
|
|
|
555
|
return $result->{success}; |
70
|
|
|
|
|
|
|
} |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
sub grade_PL { |
73
|
34
|
|
|
34
|
0
|
5376
|
my @args = @_; |
74
|
34
|
100
|
|
|
|
213
|
my $result = _init_result( 'PL', @args ) or return; |
75
|
33
|
|
|
|
|
94
|
_compute_PL_grade($result); |
76
|
33
|
100
|
|
|
|
109
|
if ( $result->{grade} eq 'discard' ) { |
77
|
|
|
|
|
|
|
$CPAN::Frontend->myprint( |
78
|
|
|
|
|
|
|
"\nCPAN::Reporter: test results were not valid, $result->{grade_msg}.\n\n", |
79
|
9
|
|
|
|
|
168
|
$result->{prereq_pm}, "\n", |
80
|
|
|
|
|
|
|
"Test report will not be sent" |
81
|
|
|
|
|
|
|
); |
82
|
9
|
100
|
|
|
|
246
|
CPAN::Reporter::History::_record_history( $result ) |
83
|
|
|
|
|
|
|
if not CPAN::Reporter::History::_is_duplicate( $result ); |
84
|
|
|
|
|
|
|
} |
85
|
|
|
|
|
|
|
else { |
86
|
24
|
|
|
|
|
145
|
_print_grade_msg($result->{PL_file} , $result); |
87
|
24
|
100
|
|
|
|
73
|
if ( $result->{grade} ne 'pass' ) { _dispatch_report( $result ) } |
|
18
|
|
|
|
|
75
|
|
88
|
|
|
|
|
|
|
} |
89
|
33
|
|
|
|
|
1187
|
return $result->{success}; |
90
|
|
|
|
|
|
|
} |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
sub grade_test { |
93
|
119
|
|
|
119
|
0
|
1926
|
my @args = @_; |
94
|
119
|
100
|
|
|
|
766
|
my $result = _init_result( 'test', @args ) or return; |
95
|
118
|
|
|
|
|
485
|
_compute_test_grade($result); |
96
|
118
|
100
|
|
|
|
386
|
if ( $result->{grade} eq 'discard' ) { |
97
|
|
|
|
|
|
|
$CPAN::Frontend->myprint( |
98
|
|
|
|
|
|
|
"\nCPAN::Reporter: test results were not valid, $result->{grade_msg}.\n\n", |
99
|
15
|
|
|
|
|
246
|
$result->{prereq_pm}, "\n", |
100
|
|
|
|
|
|
|
"Test report will not be sent" |
101
|
|
|
|
|
|
|
); |
102
|
15
|
100
|
|
|
|
386
|
CPAN::Reporter::History::_record_history( $result ) |
103
|
|
|
|
|
|
|
if not CPAN::Reporter::History::_is_duplicate( $result ); |
104
|
|
|
|
|
|
|
} |
105
|
|
|
|
|
|
|
else { |
106
|
103
|
|
|
|
|
553
|
_print_grade_msg( "Test", $result ); |
107
|
103
|
|
|
|
|
381
|
_dispatch_report( $result ); |
108
|
|
|
|
|
|
|
} |
109
|
118
|
|
|
|
|
4512
|
return $result->{success}; |
110
|
|
|
|
|
|
|
} |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
sub record_command { |
113
|
186
|
|
|
186
|
0
|
35281168
|
my ($command, $timeout) = @_; |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
|
117
|
186
|
100
|
|
|
|
1469
|
if ( -r CPAN::Reporter::Config::_get_config_file() ) { |
118
|
170
|
|
|
|
|
1024
|
my $config_obj = CPAN::Reporter::Config::_open_config_file(); |
119
|
170
|
|
|
|
|
256
|
my $config; |
120
|
170
|
50
|
|
|
|
839
|
$config = CPAN::Reporter::Config::_get_config_options( $config_obj ) |
121
|
|
|
|
|
|
|
if $config_obj; |
122
|
|
|
|
|
|
|
|
123
|
170
|
|
100
|
|
|
1413
|
$timeout ||= $config->{command_timeout}; |
124
|
|
|
|
|
|
|
} |
125
|
|
|
|
|
|
|
|
126
|
186
|
|
|
|
|
993
|
my ($cmd, $redirect) = _split_redirect($command); |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
|
130
|
186
|
|
|
|
|
230
|
my $wrap_code; |
131
|
186
|
100
|
|
|
|
433
|
if ( $timeout ) { |
132
|
15
|
50
|
|
|
|
80
|
$wrap_code = $^O eq 'MSWin32' |
133
|
|
|
|
|
|
|
? _timeout_wrapper_win32($cmd, $timeout) |
134
|
|
|
|
|
|
|
: _timeout_wrapper($cmd, $timeout); |
135
|
|
|
|
|
|
|
} |
136
|
|
|
|
|
|
|
|
137
|
186
|
100
|
|
|
|
403
|
if ( ! $wrap_code ) { |
138
|
171
|
|
|
|
|
387
|
my $safecmd = quotemeta($cmd); |
139
|
171
|
|
|
|
|
610
|
$wrap_code = << "HERE"; |
140
|
|
|
|
|
|
|
my \$rc = system("$safecmd"); |
141
|
|
|
|
|
|
|
my \$ec = \$rc == -1 ? -1 : \$?; |
142
|
|
|
|
|
|
|
print "($safecmd exited with \$ec)\\n"; |
143
|
|
|
|
|
|
|
HERE |
144
|
|
|
|
|
|
|
} |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
|
147
|
186
|
|
|
|
|
628
|
my $wrapper_name = _temp_filename( 'CPAN-Reporter-CW-' ); |
148
|
186
|
50
|
|
|
|
2213
|
my $wrapper_fh = IO::File->new( $wrapper_name, 'w' ) |
149
|
|
|
|
|
|
|
or die "Could not create a wrapper for $cmd\: $!"; |
150
|
|
|
|
|
|
|
|
151
|
186
|
|
|
|
|
30997
|
$wrapper_fh->print( $wrap_code ); |
152
|
186
|
|
|
|
|
2237
|
$wrapper_fh->close; |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
|
155
|
186
|
|
|
|
|
7786
|
my @tee_input = ( Probe::Perl->find_perl_interpreter, $wrapper_name ); |
156
|
186
|
100
|
|
|
|
2810
|
push @tee_input, $redirect if defined $redirect; |
157
|
186
|
|
|
|
|
242
|
my $tee_out; |
158
|
|
|
|
|
|
|
{ |
159
|
|
|
|
|
|
|
|
160
|
186
|
100
|
|
|
|
233
|
local $ENV{PERL5OPT} = _get_perl5opt() if _is_PL($command); |
|
186
|
|
|
|
|
701
|
|
161
|
186
|
|
|
186
|
|
5903
|
$tee_out = tee_merged { system( @tee_input ) }; |
|
186
|
|
|
|
|
101918146
|
|
162
|
|
|
|
|
|
|
} |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
|
165
|
186
|
50
|
|
|
|
498645
|
unlink $wrapper_name unless $ENV{PERL_CR_NO_CLEANUP}; |
166
|
|
|
|
|
|
|
|
167
|
186
|
|
|
|
|
19531
|
my @cmd_output = split qr{(?<=$/)}, $tee_out; |
168
|
186
|
50
|
|
|
|
892
|
if ( ! @cmd_output ) { |
169
|
0
|
|
|
|
|
0
|
$CPAN::Frontend->mywarn( |
170
|
|
|
|
|
|
|
"CPAN::Reporter: didn't capture command results for '$cmd'\n" |
171
|
|
|
|
|
|
|
); |
172
|
0
|
|
|
|
|
0
|
return; |
173
|
|
|
|
|
|
|
} |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
|
176
|
186
|
|
|
|
|
341
|
my $exit_value; |
177
|
186
|
50
|
|
|
|
1465
|
if ( $cmd_output[-1] =~ m{exited with} ) { |
178
|
186
|
|
|
|
|
1423
|
($exit_value) = $cmd_output[-1] =~ m{exited with ([-0-9]+)}; |
179
|
186
|
|
|
|
|
402
|
pop @cmd_output; |
180
|
|
|
|
|
|
|
} |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
|
183
|
186
|
50
|
|
|
|
1196
|
if ( ! defined $exit_value ) { |
|
|
50
|
|
|
|
|
|
184
|
0
|
|
|
|
|
0
|
$CPAN::Frontend->mywarn( |
185
|
|
|
|
|
|
|
"CPAN::Reporter: couldn't determine exit value for '$cmd'\n" |
186
|
|
|
|
|
|
|
); |
187
|
0
|
|
|
|
|
0
|
return; |
188
|
|
|
|
|
|
|
} |
189
|
|
|
|
|
|
|
elsif ( $exit_value == -1 ) { |
190
|
0
|
|
|
|
|
0
|
$CPAN::Frontend->mywarn( |
191
|
|
|
|
|
|
|
"CPAN::Reporter: couldn't execute '$cmd'\n" |
192
|
|
|
|
|
|
|
); |
193
|
0
|
|
|
|
|
0
|
return; |
194
|
|
|
|
|
|
|
} |
195
|
|
|
|
|
|
|
|
196
|
186
|
|
|
|
|
2689
|
return \@cmd_output, $exit_value; |
197
|
|
|
|
|
|
|
} |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
sub test { |
200
|
76
|
|
|
76
|
0
|
12868083
|
my ($dist, $system_command) = @_; |
201
|
76
|
|
|
|
|
340
|
my ($output, $exit_value) = record_command( $system_command ); |
202
|
76
|
|
|
|
|
409
|
return grade_test( $dist, $system_command, $output, $exit_value ); |
203
|
|
|
|
|
|
|
} |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
sub _compute_make_grade { |
214
|
15
|
|
|
15
|
|
30
|
my $result = shift; |
215
|
15
|
|
|
|
|
27
|
my ($grade,$msg); |
216
|
15
|
100
|
|
|
|
51
|
if ( $result->{exit_value} ) { |
217
|
13
|
|
|
|
|
55
|
$result->{grade} = "unknown"; |
218
|
13
|
|
|
|
|
38
|
$result->{grade_msg} = "Stopped with an error" |
219
|
|
|
|
|
|
|
} |
220
|
|
|
|
|
|
|
else { |
221
|
2
|
|
|
|
|
10
|
$result->{grade} = "pass"; |
222
|
2
|
|
|
|
|
8
|
$result->{grade_msg} = "No errors" |
223
|
|
|
|
|
|
|
} |
224
|
|
|
|
|
|
|
|
225
|
15
|
|
|
|
|
72
|
_downgrade_known_causes( $result ); |
226
|
|
|
|
|
|
|
|
227
|
15
|
|
|
|
|
60
|
$result->{success} = $result->{grade} eq 'pass'; |
228
|
15
|
|
|
|
|
41
|
return; |
229
|
|
|
|
|
|
|
} |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
sub _compute_PL_grade { |
236
|
33
|
|
|
33
|
|
41
|
my $result = shift; |
237
|
33
|
|
|
|
|
55
|
my ($grade,$msg); |
238
|
33
|
100
|
|
|
|
87
|
if ( $result->{exit_value} ) { |
239
|
23
|
|
|
|
|
90
|
$result->{grade} = "unknown"; |
240
|
23
|
|
|
|
|
69
|
$result->{grade_msg} = "Stopped with an error" |
241
|
|
|
|
|
|
|
} |
242
|
|
|
|
|
|
|
else { |
243
|
10
|
|
|
|
|
41
|
$result->{grade} = "pass"; |
244
|
10
|
|
|
|
|
29
|
$result->{grade_msg} = "No errors" |
245
|
|
|
|
|
|
|
} |
246
|
|
|
|
|
|
|
|
247
|
33
|
|
|
|
|
152
|
_downgrade_known_causes( $result ); |
248
|
|
|
|
|
|
|
|
249
|
33
|
|
|
|
|
126
|
$result->{success} = $result->{grade} eq 'pass'; |
250
|
33
|
|
|
|
|
94
|
return; |
251
|
|
|
|
|
|
|
} |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
sub _compute_test_grade { |
274
|
118
|
|
|
118
|
|
175
|
my $result = shift; |
275
|
118
|
|
|
|
|
174
|
my ($grade,$msg); |
276
|
118
|
|
|
|
|
215
|
my $output = $result->{output}; |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
|
279
|
118
|
100
|
100
|
|
|
1476
|
if ( $result->{is_make} && ( -f "test.pl" || _has_recursive_make() ) ) { |
|
|
|
66
|
|
|
|
|
280
|
16
|
100
|
|
|
|
75
|
if ( $result->{exit_value} ) { |
281
|
10
|
|
|
|
|
35
|
$grade = "fail"; |
282
|
10
|
|
|
|
|
28
|
$msg = "'make test' error detected"; |
283
|
|
|
|
|
|
|
} |
284
|
|
|
|
|
|
|
else { |
285
|
6
|
|
|
|
|
15
|
$grade = "pass"; |
286
|
6
|
|
|
|
|
18
|
$msg = "'make test' no errors"; |
287
|
|
|
|
|
|
|
} |
288
|
|
|
|
|
|
|
} |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
else { |
291
|
|
|
|
|
|
|
|
292
|
102
|
|
|
|
|
493
|
_expand_result( $result ); |
293
|
102
|
|
|
|
|
369
|
my $harness_version = $result->{toolchain}{'Test::Harness'}{have}; |
294
|
102
|
50
|
|
|
|
1416
|
my $harness_parser = CPAN::Version->vgt($harness_version, '2.99_01') |
295
|
|
|
|
|
|
|
? \&_parse_tap_harness |
296
|
|
|
|
|
|
|
: \&_parse_test_harness; |
297
|
|
|
|
|
|
|
|
298
|
102
|
|
|
|
|
5920
|
for my $i ( reverse 0 .. $#{$output} ) { |
|
102
|
|
|
|
|
445
|
|
299
|
276
|
100
|
|
|
|
1693
|
if ( $output->[$i] =~ m{No support for OS|OS unsupported}ims ) { |
|
|
100
|
|
|
|
|
|
300
|
6
|
|
|
|
|
18
|
$grade = 'na'; |
301
|
6
|
|
|
|
|
14
|
$msg = 'This platform is not supported'; |
302
|
|
|
|
|
|
|
} |
303
|
|
|
|
|
|
|
elsif ( $output->[$i] =~ m{^.?No tests defined}ms ) { |
304
|
8
|
|
|
|
|
24
|
$grade = 'unknown'; |
305
|
8
|
|
|
|
|
16
|
$msg = 'No tests provided'; |
306
|
|
|
|
|
|
|
} |
307
|
|
|
|
|
|
|
else { |
308
|
262
|
|
|
|
|
460
|
($grade, $msg) = $harness_parser->( $output->[$i] ); |
309
|
|
|
|
|
|
|
} |
310
|
276
|
100
|
|
|
|
591
|
last if $grade; |
311
|
|
|
|
|
|
|
} |
312
|
|
|
|
|
|
|
|
313
|
102
|
100
|
|
|
|
473
|
if ( ! $grade ) { |
314
|
12
|
100
|
|
|
|
76
|
$grade = $result->{exit_value} ? "fail" : "pass"; |
315
|
|
|
|
|
|
|
$msg = ( $result->{is_make} ? "'make test' " : "'Build test' " ) |
316
|
12
|
100
|
|
|
|
75
|
. ( $result->{exit_value} ? "error detected" : "no errors"); |
|
|
100
|
|
|
|
|
|
317
|
|
|
|
|
|
|
} |
318
|
|
|
|
|
|
|
} |
319
|
|
|
|
|
|
|
|
320
|
118
|
|
|
|
|
453
|
$result->{grade} = $grade; |
321
|
118
|
|
|
|
|
327
|
$result->{grade_msg} = $msg; |
322
|
|
|
|
|
|
|
|
323
|
118
|
|
|
|
|
589
|
_downgrade_known_causes( $result ); |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
$result->{success} = $result->{grade} eq 'pass' |
326
|
118
|
|
100
|
|
|
774
|
|| $result->{grade} eq 'unknown'; |
327
|
118
|
|
|
|
|
293
|
return; |
328
|
|
|
|
|
|
|
} |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
sub _dispatch_report { |
337
|
131
|
|
|
131
|
|
5868
|
my $result = shift; |
338
|
131
|
|
|
|
|
373
|
my $phase = $result->{phase}; |
339
|
|
|
|
|
|
|
|
340
|
131
|
|
|
|
|
575
|
$CPAN::Frontend->myprint( |
341
|
|
|
|
|
|
|
"CPAN::Reporter: preparing a CPAN Testers report for $result->{dist_name}\n" |
342
|
|
|
|
|
|
|
); |
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
|
345
|
131
|
|
|
|
|
1804
|
my $config_obj = CPAN::Reporter::Config::_open_config_file(); |
346
|
131
|
|
|
|
|
211
|
my $config; |
347
|
131
|
100
|
|
|
|
713
|
$config = CPAN::Reporter::Config::_get_config_options( $config_obj ) |
348
|
|
|
|
|
|
|
if $config_obj; |
349
|
131
|
100
|
|
|
|
464
|
if ( ! $config->{email_from} ) { |
350
|
5
|
|
|
|
|
12
|
$CPAN::Frontend->mywarn( << "EMAIL_REQUIRED"); |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
CPAN::Reporter: required 'email_from' option missing an email address, so |
353
|
|
|
|
|
|
|
test report will not be sent. See documentation for configuration details. |
354
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
Even though CPAN Testers no longer uses email, this email address will |
356
|
|
|
|
|
|
|
show up in the report and help identify the tester. This is required |
357
|
|
|
|
|
|
|
for compatibility with tools that process legacy reports for analysis. |
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
EMAIL_REQUIRED |
360
|
5
|
|
|
|
|
37
|
return; |
361
|
|
|
|
|
|
|
} |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
|
364
|
126
|
|
|
|
|
554
|
my $is_duplicate = CPAN::Reporter::History::_is_duplicate( $result ); |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
my @format_checks = $result->{dist_basename} =~ |
371
|
126
|
|
|
|
|
1772
|
m{(.+)([\-\_])(v?\d.*)(\.(?:tar\.(?:gz|bz2)|tgz|zip))$}i; |
372
|
|
|
|
|
|
|
; |
373
|
126
|
100
|
|
|
|
284
|
if ( ! grep { length } @format_checks ) { |
|
492
|
|
|
|
|
727
|
|
374
|
3
|
|
|
|
|
30
|
$CPAN::Frontend->mywarn( << "END_BAD_DISTNAME"); |
375
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
CPAN::Reporter: the distribution name '$result->{dist_basename}' does not |
377
|
|
|
|
|
|
|
appear to be packaged according to CPAN tester guidelines. Perhaps it is |
378
|
|
|
|
|
|
|
not a normal CPAN distribution. |
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
Test report will not be sent. |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
END_BAD_DISTNAME |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
|
385
|
3
|
|
|
|
|
40
|
$result->{grade} = 'discard'; |
386
|
3
|
50
|
|
|
|
20
|
CPAN::Reporter::History::_record_history( $result ) |
387
|
|
|
|
|
|
|
if not $is_duplicate; |
388
|
3
|
|
|
|
|
13
|
return; |
389
|
|
|
|
|
|
|
} |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
|
392
|
123
|
|
|
|
|
329
|
_expand_result( $result); |
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
|
395
|
123
|
100
|
66
|
|
|
438
|
if ( $config->{send_skipfile} && -r $config->{send_skipfile} ) { |
396
|
4
|
|
|
|
|
31
|
my $send_skipfile = IO::File->new( $config->{send_skipfile}, "r" ); |
397
|
4
|
|
|
|
|
316
|
my $dist_id = $result->{dist}->pretty_id; |
398
|
4
|
|
|
|
|
62
|
while ( my $pattern = <$send_skipfile> ) { |
399
|
11
|
|
|
|
|
15
|
chomp($pattern); |
400
|
|
|
|
|
|
|
|
401
|
11
|
100
|
|
|
|
29
|
next if substr($pattern,0,1) eq '#'; |
402
|
|
|
|
|
|
|
|
403
|
7
|
100
|
|
|
|
100
|
next if $dist_id !~ /$pattern/i; |
404
|
|
|
|
|
|
|
|
405
|
3
|
|
|
|
|
23
|
$CPAN::Frontend->myprint( << "END_SKIP_DIST" ); |
406
|
|
|
|
|
|
|
CPAN::Reporter: '$dist_id' matched against the send_skipfile. |
407
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
Test report will not be sent. |
409
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
END_SKIP_DIST |
411
|
|
|
|
|
|
|
|
412
|
3
|
|
|
|
|
67
|
return; |
413
|
|
|
|
|
|
|
} |
414
|
|
|
|
|
|
|
} |
415
|
|
|
|
|
|
|
|
416
|
|
|
|
|
|
|
|
417
|
120
|
|
|
|
|
1670
|
my $tr = Test::Reporter->new; |
418
|
120
|
|
|
|
|
1909
|
$tr->grade( $result->{grade} ); |
419
|
120
|
|
|
|
|
1182
|
$tr->distribution( $result->{dist_name} ); |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
$tr->distfile( $result->{dist}->pretty_id ) |
423
|
120
|
50
|
|
|
|
1671
|
if $Test::Reporter::VERSION >= 1.54; |
424
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
|
426
|
120
|
100
|
|
|
|
1272
|
if ( $is_duplicate ) { |
427
|
74
|
100
|
|
|
|
269
|
if ( _prompt( $config, "send_duplicates", $tr->grade) =~ /^n/ ) { |
428
|
2
|
|
|
|
|
6
|
$CPAN::Frontend->myprint(<< "DUPLICATE_REPORT"); |
429
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
CPAN::Reporter: this appears to be a duplicate report for the $phase phase: |
431
|
2
|
|
|
|
|
8
|
@{[$tr->subject]} |
432
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
Test report will not be sent. |
434
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
DUPLICATE_REPORT |
436
|
|
|
|
|
|
|
|
437
|
2
|
|
|
|
|
83
|
return; |
438
|
|
|
|
|
|
|
} |
439
|
|
|
|
|
|
|
} |
440
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
|
442
|
118
|
50
|
|
|
|
401
|
$tr->debug( $config->{debug} ) if defined $config->{debug}; |
443
|
118
|
|
|
|
|
227
|
my $transport = $config->{transport}; |
444
|
118
|
50
|
33
|
|
|
707
|
unless ( defined $transport && length $transport ) { |
445
|
0
|
|
|
|
|
0
|
$CPAN::Frontend->mywarn( << "TRANSPORT_REQUIRED"); |
446
|
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
CPAN::Reporter: required 'transport' option missing so the test report |
448
|
|
|
|
|
|
|
will not be sent. See documentation for configuration details. |
449
|
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
TRANSPORT_REQUIRED |
451
|
0
|
|
|
|
|
0
|
return; |
452
|
|
|
|
|
|
|
} |
453
|
118
|
|
|
|
|
485
|
my @transport_args = split " ", $transport; |
454
|
|
|
|
|
|
|
|
455
|
|
|
|
|
|
|
|
456
|
118
|
100
|
|
|
|
343
|
if ($transport_args[0] eq 'Metabase') { |
457
|
116
|
|
|
|
|
330
|
@transport_args = _validate_metabase_args(@transport_args); |
458
|
116
|
50
|
|
|
|
358
|
unless (@transport_args) { |
459
|
0
|
|
|
|
|
0
|
$CPAN::Frontend->mywarn( "Test report will not be sent.\n\n" ); |
460
|
0
|
|
|
|
|
0
|
return; |
461
|
|
|
|
|
|
|
} |
462
|
|
|
|
|
|
|
} |
463
|
|
|
|
|
|
|
|
464
|
118
|
|
|
|
|
178
|
eval { $tr->transport( @transport_args ) }; |
|
118
|
|
|
|
|
407
|
|
465
|
118
|
100
|
|
|
|
1759
|
if ($@) { |
466
|
1
|
|
|
|
|
10
|
$CPAN::Frontend->mywarn( |
467
|
|
|
|
|
|
|
"CPAN::Reporter: problem with Test::Reporter transport: \n" . |
468
|
|
|
|
|
|
|
"$@\n" . |
469
|
|
|
|
|
|
|
"Test report will not be sent\n" |
470
|
|
|
|
|
|
|
); |
471
|
1
|
|
|
|
|
19
|
return; |
472
|
|
|
|
|
|
|
} |
473
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
|
475
|
117
|
|
|
|
|
591
|
$tr->from( $config->{email_from} ); |
476
|
|
|
|
|
|
|
|
477
|
|
|
|
|
|
|
|
478
|
117
|
|
|
|
|
920
|
$tr->comments( _report_text( $result ) ); |
479
|
117
|
|
|
|
|
1018
|
$tr->via( 'CPAN::Reporter ' . $CPAN::Reporter::VERSION ); |
480
|
|
|
|
|
|
|
|
481
|
|
|
|
|
|
|
|
482
|
117
|
50
|
|
|
|
775
|
if ( _prompt( $config, "edit_report", $tr->grade ) =~ /^y/ ) { |
483
|
0
|
|
|
|
|
0
|
my $editor = $config->{editor}; |
484
|
0
|
0
|
|
|
|
0
|
local $ENV{VISUAL} = $editor if $editor; |
485
|
0
|
|
|
|
|
0
|
$tr->edit_comments; |
486
|
|
|
|
|
|
|
} |
487
|
|
|
|
|
|
|
|
488
|
|
|
|
|
|
|
|
489
|
117
|
100
|
|
|
|
608
|
my $send_config = defined $config->{"send_$phase\_report"} |
490
|
|
|
|
|
|
|
? "send_$phase\_report" |
491
|
|
|
|
|
|
|
: "send_report" ; |
492
|
117
|
100
|
|
|
|
546
|
if ( _prompt( $config, $send_config, $tr->grade ) =~ /^y/ ) { |
493
|
114
|
|
|
|
|
523
|
$CPAN::Frontend->myprint( "CPAN::Reporter: sending test report with '" . $tr->grade . |
494
|
|
|
|
|
|
|
"' via " . $transport_args[0] . "\n"); |
495
|
114
|
50
|
|
|
|
2546
|
if ( $tr->send() ) { |
496
|
114
|
100
|
|
|
|
882
|
CPAN::Reporter::History::_record_history( $result ) |
497
|
|
|
|
|
|
|
if not $is_duplicate; |
498
|
|
|
|
|
|
|
} |
499
|
|
|
|
|
|
|
else { |
500
|
0
|
|
|
|
|
0
|
$CPAN::Frontend->mywarn( "CPAN::Reporter: " . $tr->errstr . "\n"); |
501
|
|
|
|
|
|
|
|
502
|
0
|
0
|
|
|
|
0
|
if ( $config->{retry_submission} ) { |
503
|
0
|
|
|
|
|
0
|
sleep(3); |
504
|
|
|
|
|
|
|
|
505
|
0
|
|
|
|
|
0
|
$CPAN::Frontend->mywarn( "CPAN::Reporter: second attempt\n"); |
506
|
0
|
|
|
|
|
0
|
$tr->errstr(''); |
507
|
|
|
|
|
|
|
|
508
|
0
|
0
|
|
|
|
0
|
if ( $tr->send() ) { |
509
|
0
|
0
|
|
|
|
0
|
CPAN::Reporter::History::_record_history( $result ) |
510
|
|
|
|
|
|
|
if not $is_duplicate; |
511
|
|
|
|
|
|
|
} |
512
|
|
|
|
|
|
|
else { |
513
|
0
|
|
|
|
|
0
|
$CPAN::Frontend->mywarn( "CPAN::Reporter: " . $tr->errstr . "\n"); |
514
|
|
|
|
|
|
|
} |
515
|
|
|
|
|
|
|
} |
516
|
|
|
|
|
|
|
|
517
|
|
|
|
|
|
|
} |
518
|
|
|
|
|
|
|
} |
519
|
|
|
|
|
|
|
else { |
520
|
3
|
|
|
|
|
11
|
$CPAN::Frontend->myprint("CPAN::Reporter: test report will not be sent\n"); |
521
|
|
|
|
|
|
|
} |
522
|
|
|
|
|
|
|
|
523
|
117
|
|
|
|
|
853
|
return; |
524
|
|
|
|
|
|
|
} |
525
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
sub _report_timeout { |
527
|
129
|
|
|
129
|
|
215
|
my $result = shift; |
528
|
129
|
100
|
|
|
|
464
|
if ($result->{exit_value} == 9) { |
529
|
2
|
|
|
|
|
18
|
my $config_obj = CPAN::Reporter::Config::_open_config_file(); |
530
|
2
|
|
|
|
|
5
|
my $config; |
531
|
2
|
50
|
|
|
|
11
|
$config = CPAN::Reporter::Config::_get_config_options( $config_obj ) |
532
|
|
|
|
|
|
|
if $config_obj; |
533
|
|
|
|
|
|
|
|
534
|
2
|
50
|
|
|
|
10
|
if ($config->{'_store_problems_in_dir'}) { |
535
|
0
|
|
|
|
|
0
|
my $distribution = $result->{dist}->base_id; |
536
|
0
|
|
|
|
|
0
|
my $file = "e9.$distribution.${\(time)}.$$.log"; |
|
0
|
|
|
|
|
0
|
|
537
|
0
|
0
|
|
|
|
0
|
if (open my $to_log_fh, '>>', $config->{'_store_problems_in_dir'}.'/'.$file) { |
538
|
0
|
|
|
|
|
0
|
print $to_log_fh $distribution,"\n"; |
539
|
0
|
|
|
|
|
0
|
print $to_log_fh "stage: ",$result->{phase},"\n"; |
540
|
0
|
|
|
|
|
0
|
print $to_log_fh $Config{archname},"\n"; |
541
|
0
|
|
|
|
|
0
|
print $to_log_fh _report_text( $result ); |
542
|
|
|
|
|
|
|
} else { |
543
|
|
|
|
|
|
|
$CPAN::Frontend->mywarn( "CPAN::Reporter: writing ". |
544
|
0
|
|
|
|
|
0
|
$config->{'_store_problems_in_dir'}.'/'.$file. " failed\n"); |
545
|
|
|
|
|
|
|
} |
546
|
|
|
|
|
|
|
} |
547
|
2
|
50
|
|
|
|
11
|
if ($config->{'_problem_log'}) { |
548
|
0
|
|
|
|
|
0
|
my $distribution = $result->{dist}->base_id; |
549
|
0
|
0
|
|
|
|
0
|
if (open my $to_log_fh, '>>', $config->{'_problem_log'}) { |
550
|
0
|
|
|
|
|
0
|
print $to_log_fh "$result->{phase} $distribution $Config{archname}\n"; |
551
|
|
|
|
|
|
|
} else { |
552
|
|
|
|
|
|
|
$CPAN::Frontend->mywarn( "CPAN::Reporter: writing ". |
553
|
0
|
|
|
|
|
0
|
$config->{'_store_problems_in_dir'}. " failed\n"); |
554
|
|
|
|
|
|
|
} |
555
|
|
|
|
|
|
|
} |
556
|
|
|
|
|
|
|
} |
557
|
|
|
|
|
|
|
} |
558
|
|
|
|
|
|
|
|
559
|
|
|
|
|
|
|
|
560
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
|
562
|
|
|
|
|
|
|
|
563
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
|
565
|
|
|
|
|
|
|
|
566
|
|
|
|
|
|
|
|
567
|
|
|
|
|
|
|
sub _downgrade_known_causes { |
568
|
169
|
|
|
169
|
|
284
|
my ($result) = @_; |
569
|
169
|
|
|
|
|
759
|
my ($grade, $output) = ( $result->{grade}, $result->{output} ); |
570
|
169
|
|
50
|
|
|
1314
|
my $msg = $result->{grade_msg} || q{}; |
571
|
|
|
|
|
|
|
|
572
|
|
|
|
|
|
|
|
573
|
|
|
|
|
|
|
|
574
|
|
|
|
|
|
|
|
575
|
169
|
100
|
|
|
|
490
|
return if $grade eq 'na'; |
576
|
163
|
100
|
100
|
|
|
759
|
return if $grade eq 'pass' && $result->{phase} ne 'PL'; |
577
|
|
|
|
|
|
|
|
578
|
|
|
|
|
|
|
|
579
|
129
|
|
|
|
|
360
|
_expand_result( $result ); |
580
|
|
|
|
|
|
|
|
581
|
129
|
|
|
|
|
641
|
_report_timeout( $result ); |
582
|
|
|
|
|
|
|
|
583
|
|
|
|
|
|
|
|
584
|
129
|
100
|
|
|
|
409
|
if ( $result->{exit_value} & 127 ) { |
585
|
2
|
|
|
|
|
5
|
$result->{grade} = 'discard'; |
586
|
2
|
|
|
|
|
7
|
$result->{grade_msg} = 'Command interrupted'; |
587
|
2
|
|
|
|
|
5
|
return; |
588
|
|
|
|
|
|
|
} |
589
|
|
|
|
|
|
|
|
590
|
|
|
|
|
|
|
|
591
|
|
|
|
|
|
|
|
592
|
|
|
|
|
|
|
|
593
|
127
|
|
|
|
|
178
|
my ($harness_error, $version_error, $unsupported) ; |
594
|
127
|
|
|
|
|
427
|
for my $line ( @$output ) { |
595
|
3614
|
100
|
100
|
|
|
9411
|
if ( $result->{phase} eq 'test' |
596
|
|
|
|
|
|
|
&& $line =~ m{open3: IO::Pipe: Can't spawn.*?TAP/Parser/Iterator/Process.pm} |
597
|
|
|
|
|
|
|
) { |
598
|
2
|
|
|
|
|
3
|
$harness_error++; |
599
|
2
|
|
|
|
|
5
|
last; |
600
|
|
|
|
|
|
|
} |
601
|
3612
|
50
|
66
|
|
|
30838
|
if( $line =~ /(?<!skipped: )Perl .*? required.*?--this is only/ims || |
|
|
|
100
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
33
|
|
|
|
|
602
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
$line =~ /Perl version .*? or higher required\. We run/ims || |
604
|
|
|
|
|
|
|
$line =~ /ERROR: perl: Version .*? is installed, but we need version/ims || |
605
|
|
|
|
|
|
|
$line =~ /ERROR: perl \(.*?\) is installed, but we need version/ims || |
606
|
|
|
|
|
|
|
$line =~ /Error evaling version line 'BEGIN/ims || |
607
|
|
|
|
|
|
|
$line =~ /Could not eval '/ims |
608
|
|
|
|
|
|
|
) { |
609
|
8
|
|
|
|
|
26
|
$version_error++; |
610
|
8
|
|
|
|
|
19
|
last; |
611
|
|
|
|
|
|
|
} |
612
|
3604
|
100
|
|
|
|
10181
|
if ( $line =~ /No support for OS|OS unsupported/ims ) { |
613
|
6
|
|
|
|
|
20
|
$unsupported++; |
614
|
6
|
|
|
|
|
19
|
last; |
615
|
|
|
|
|
|
|
} |
616
|
|
|
|
|
|
|
} |
617
|
|
|
|
|
|
|
|
618
|
|
|
|
|
|
|
|
619
|
127
|
100
|
100
|
|
|
3344
|
if ( $harness_error ) { |
|
|
100
|
100
|
|
|
|
|
|
|
100
|
100
|
|
|
|
|
|
|
100
|
100
|
|
|
|
|
|
|
100
|
100
|
|
|
|
|
|
|
100
|
100
|
|
|
|
|
|
|
100
|
100
|
|
|
|
|
|
|
100
|
100
|
|
|
|
|
|
|
100
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
620
|
2
|
|
|
|
|
5
|
$grade = 'discard'; |
621
|
2
|
|
|
|
|
6
|
$msg = 'Test harness failure'; |
622
|
|
|
|
|
|
|
} |
623
|
|
|
|
|
|
|
|
624
|
|
|
|
|
|
|
elsif ( $version_error || $result->{prereq_pm} =~ m{^\s+!\s+perl\s}ims ) { |
625
|
12
|
|
|
|
|
41
|
$grade = 'na'; |
626
|
12
|
|
|
|
|
30
|
$msg = 'Perl version too low'; |
627
|
|
|
|
|
|
|
} |
628
|
|
|
|
|
|
|
|
629
|
|
|
|
|
|
|
elsif ( $unsupported ) { |
630
|
6
|
|
|
|
|
22
|
$grade = 'na'; |
631
|
6
|
|
|
|
|
19
|
$msg = 'This platform is not supported'; |
632
|
|
|
|
|
|
|
} |
633
|
|
|
|
|
|
|
|
634
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
|
636
|
|
|
|
|
|
|
elsif ( |
637
|
|
|
|
|
|
|
$result->{is_make} && $result->{phase} eq 'test' && ! _has_test_target() |
638
|
|
|
|
|
|
|
) { |
639
|
1
|
|
|
|
|
2
|
$grade = 'unknown'; |
640
|
1
|
|
|
|
|
3
|
$msg = 'No make test target'; |
641
|
|
|
|
|
|
|
} |
642
|
|
|
|
|
|
|
|
643
|
|
|
|
|
|
|
elsif ( $grade ne 'pass' && $result->{prereq_pm} =~ m{n/a}ims ) { |
644
|
14
|
|
|
|
|
42
|
$grade = 'discard'; |
645
|
14
|
|
|
|
|
127
|
$msg = "Prerequisite missing:\n$result->{prereq_pm}"; |
646
|
|
|
|
|
|
|
} |
647
|
|
|
|
|
|
|
elsif ( $grade ne 'pass' && $result->{prereq_pm} =~ m{^\s+!}ims ) { |
648
|
8
|
|
|
|
|
28
|
$grade = 'discard'; |
649
|
8
|
|
|
|
|
36
|
$msg = "Prerequisite version too low:\n$result->{prereq_pm}"; |
650
|
|
|
|
|
|
|
} |
651
|
|
|
|
|
|
|
|
652
|
|
|
|
|
|
|
|
653
|
|
|
|
|
|
|
elsif ( $result->{phase} eq 'PL' && $grade eq 'pass' |
654
|
|
|
|
|
|
|
&& ! -f 'Makefile' && ! -f 'Build' |
655
|
|
|
|
|
|
|
) { |
656
|
2
|
|
|
|
|
13
|
$grade = 'discard'; |
657
|
2
|
|
|
|
|
5
|
$msg = 'No Makefile or Build file found'; |
658
|
|
|
|
|
|
|
} |
659
|
|
|
|
|
|
|
elsif ( $result->{command} =~ /Build.*?-j/ ) { |
660
|
2
|
|
|
|
|
5
|
$grade = 'discard'; |
661
|
2
|
|
|
|
|
5
|
$msg = '-j is not a valid option for Module::Build (upgrade your CPAN.pm)'; |
662
|
|
|
|
|
|
|
} |
663
|
|
|
|
|
|
|
elsif ( |
664
|
|
|
|
|
|
|
$result->{is_make} && $result->{phase} eq 'make' && |
665
|
39
|
|
|
|
|
77
|
grep { /Makefile out-of-date with respect to Makefile.PL/ } @$output |
666
|
|
|
|
|
|
|
) { |
667
|
1
|
|
|
|
|
5
|
$grade = 'discard'; |
668
|
1
|
|
|
|
|
3
|
$msg = 'Makefile out-of-date'; |
669
|
|
|
|
|
|
|
} |
670
|
|
|
|
|
|
|
|
671
|
|
|
|
|
|
|
|
672
|
127
|
|
|
|
|
1787
|
$result->{grade} = $grade; |
673
|
127
|
|
|
|
|
424
|
$result->{grade_msg} = $msg; |
674
|
|
|
|
|
|
|
|
675
|
127
|
|
|
|
|
252
|
return; |
676
|
|
|
|
|
|
|
} |
677
|
|
|
|
|
|
|
|
678
|
|
|
|
|
|
|
|
679
|
|
|
|
|
|
|
|
680
|
|
|
|
|
|
|
|
681
|
|
|
|
|
|
|
|
682
|
|
|
|
|
|
|
|
683
|
|
|
|
|
|
|
|
684
|
|
|
|
|
|
|
sub _expand_result { |
685
|
354
|
|
|
354
|
|
564
|
my $result = shift; |
686
|
354
|
100
|
|
|
|
1314
|
return if $result->{expanded}++; |
687
|
167
|
|
|
|
|
812
|
$result->{prereq_pm} = _prereq_report( $result->{dist} ); |
688
|
|
|
|
|
|
|
{ |
689
|
|
|
|
|
|
|
|
690
|
167
|
100
|
|
|
|
272
|
local $ENV{PERL5OPT} = _get_perl5opt() if _is_PL($result->{command}); |
|
167
|
|
|
|
|
818
|
|
691
|
167
|
|
|
|
|
646
|
$result->{env_vars} = _env_report(); |
692
|
|
|
|
|
|
|
} |
693
|
167
|
|
|
|
|
690
|
$result->{special_vars} = _special_vars_report(); |
694
|
167
|
|
|
|
|
634
|
$result->{toolchain_versions} = _toolchain_report( $result ); |
695
|
167
|
|
|
|
|
1309
|
$result->{perl_version} = CPAN::Reporter::History::_format_perl_version(); |
696
|
167
|
|
|
|
|
607
|
return; |
697
|
|
|
|
|
|
|
} |
698
|
|
|
|
|
|
|
|
699
|
|
|
|
|
|
|
|
700
|
|
|
|
|
|
|
|
701
|
|
|
|
|
|
|
|
702
|
|
|
|
|
|
|
|
703
|
|
|
|
|
|
|
|
704
|
|
|
|
|
|
|
my @env_vars= qw( |
705
|
|
|
|
|
|
|
/HARNESS/ |
706
|
|
|
|
|
|
|
/LC_/ |
707
|
|
|
|
|
|
|
/PERL/ |
708
|
|
|
|
|
|
|
/_TEST/ |
709
|
|
|
|
|
|
|
COMSPEC |
710
|
|
|
|
|
|
|
INCLUDE |
711
|
|
|
|
|
|
|
LANG |
712
|
|
|
|
|
|
|
LANGUAGE |
713
|
|
|
|
|
|
|
LD_LIBRARY_PATH |
714
|
|
|
|
|
|
|
LIB |
715
|
|
|
|
|
|
|
NUMBER_OF_PROCESSORS |
716
|
|
|
|
|
|
|
PATH |
717
|
|
|
|
|
|
|
PROCESSOR_IDENTIFIER |
718
|
|
|
|
|
|
|
SHELL |
719
|
|
|
|
|
|
|
TEMP |
720
|
|
|
|
|
|
|
TERM |
721
|
|
|
|
|
|
|
TMPDIR |
722
|
|
|
|
|
|
|
); |
723
|
|
|
|
|
|
|
|
724
|
|
|
|
|
|
|
sub _env_report { |
725
|
176
|
|
|
176
|
|
14293
|
my @vars_found; |
726
|
176
|
|
|
|
|
719
|
for my $var ( @env_vars ) { |
727
|
2992
|
100
|
|
|
|
5643
|
if ( $var =~ m{^/(.+)/$} ) { |
728
|
704
|
|
|
|
|
3020
|
push @vars_found, grep { /$1/ } keys %ENV; |
|
16324
|
|
|
|
|
27785
|
|
729
|
|
|
|
|
|
|
} |
730
|
|
|
|
|
|
|
else { |
731
|
2288
|
100
|
|
|
|
4100
|
push @vars_found, $var if exists $ENV{$var}; |
732
|
|
|
|
|
|
|
} |
733
|
|
|
|
|
|
|
} |
734
|
|
|
|
|
|
|
|
735
|
176
|
|
|
|
|
325
|
my $report = ""; |
736
|
176
|
|
|
|
|
1224
|
for my $var ( sort @vars_found ) { |
737
|
2145
|
|
|
|
|
2184
|
my $value = $ENV{$var}; |
738
|
2145
|
50
|
|
|
|
2526
|
$value = '[undef]' if ! defined $value; |
739
|
2145
|
|
|
|
|
2989
|
$report .= " $var = $value\n"; |
740
|
|
|
|
|
|
|
} |
741
|
176
|
|
|
|
|
880
|
return $report; |
742
|
|
|
|
|
|
|
} |
743
|
|
|
|
|
|
|
|
744
|
|
|
|
|
|
|
|
745
|
|
|
|
|
|
|
|
746
|
|
|
|
|
|
|
|
747
|
|
|
|
|
|
|
|
748
|
|
|
|
|
|
|
|
749
|
|
|
|
|
|
|
|
750
|
|
|
|
|
|
|
sub _file_copy_quiet { |
751
|
33
|
|
|
33
|
|
66
|
my ($source, $target) = @_; |
752
|
|
|
|
|
|
|
|
753
|
33
|
50
|
|
|
|
5103
|
mkpath( dirname($target) ) or return; |
754
|
|
|
|
|
|
|
|
755
|
33
|
|
|
|
|
104
|
local *FH; |
756
|
33
|
50
|
|
|
|
1199
|
open FH, "<$source" or return; |
757
|
33
|
|
|
|
|
52
|
my $pm_guts = do { local $/; <FH> }; |
|
33
|
|
|
|
|
120
|
|
|
33
|
|
|
|
|
477
|
|
758
|
33
|
|
|
|
|
172
|
close FH; |
759
|
|
|
|
|
|
|
|
760
|
33
|
50
|
|
|
|
1566
|
open FH, ">$target" or return; |
761
|
33
|
|
|
|
|
135
|
print FH $pm_guts; |
762
|
33
|
|
|
|
|
967
|
close FH; |
763
|
33
|
|
|
|
|
169
|
return 1; |
764
|
|
|
|
|
|
|
} |
765
|
|
|
|
|
|
|
|
766
|
|
|
|
|
|
|
|
767
|
|
|
|
|
|
|
|
768
|
|
|
|
|
|
|
|
769
|
|
|
|
|
|
|
|
770
|
|
|
|
|
|
|
sub _get_perl5opt { |
771
|
76
|
|
50
|
76
|
|
469
|
my $perl5opt = $ENV{PERL5OPT} || q{}; |
772
|
76
|
50
|
|
|
|
189
|
if ( $Autoflush_Lib ) { |
773
|
76
|
50
|
|
|
|
162
|
$perl5opt .= q{ } if length $perl5opt; |
774
|
76
|
50
|
|
|
|
315
|
$perl5opt .= "-I$Autoflush_Lib " if $] >= 5.008; |
775
|
76
|
|
|
|
|
129
|
$perl5opt .= "-MDevel::Autoflush"; |
776
|
|
|
|
|
|
|
} |
777
|
76
|
|
|
|
|
659
|
return $perl5opt; |
778
|
|
|
|
|
|
|
} |
779
|
|
|
|
|
|
|
|
780
|
|
|
|
|
|
|
|
781
|
|
|
|
|
|
|
|
782
|
|
|
|
|
|
|
|
783
|
|
|
|
|
|
|
|
784
|
|
|
|
|
|
|
|
785
|
|
|
|
|
|
|
|
786
|
|
|
|
|
|
|
sub _has_recursive_make { |
787
|
67
|
|
|
67
|
|
106
|
my $PL_count = 0; |
788
|
|
|
|
|
|
|
File::Find::find( |
789
|
|
|
|
|
|
|
sub { |
790
|
2318
|
100
|
|
2318
|
|
64787
|
if ( $_ eq 't' ) { |
|
|
100
|
|
|
|
|
|
791
|
63
|
|
|
|
|
396
|
$File::Find::prune = 1; |
792
|
|
|
|
|
|
|
} |
793
|
|
|
|
|
|
|
elsif ( $_ eq 'Makefile.PL' ) { |
794
|
73
|
|
|
|
|
871
|
$PL_count++; |
795
|
|
|
|
|
|
|
} |
796
|
|
|
|
|
|
|
}, |
797
|
67
|
|
|
|
|
6246
|
File::Spec->curdir() |
798
|
|
|
|
|
|
|
); |
799
|
67
|
|
|
|
|
580
|
return $PL_count > 1; |
800
|
|
|
|
|
|
|
} |
801
|
|
|
|
|
|
|
|
802
|
|
|
|
|
|
|
|
803
|
|
|
|
|
|
|
|
804
|
|
|
|
|
|
|
|
805
|
|
|
|
|
|
|
|
806
|
|
|
|
|
|
|
sub _has_test_target { |
807
|
47
|
50
|
|
47
|
|
680
|
my $fh = IO::File->new("Makefile") or return; |
808
|
47
|
|
|
|
|
19042
|
return scalar grep { /^test[ ]*:/ } <$fh>; |
|
40793
|
|
|
|
|
34154
|
|
809
|
|
|
|
|
|
|
} |
810
|
|
|
|
|
|
|
|
811
|
|
|
|
|
|
|
|
812
|
|
|
|
|
|
|
|
813
|
|
|
|
|
|
|
|
814
|
|
|
|
|
|
|
|
815
|
|
|
|
|
|
|
|
816
|
|
|
|
|
|
|
|
817
|
|
|
|
|
|
|
|
818
|
|
|
|
|
|
|
sub _init_result { |
819
|
173
|
|
|
173
|
|
6338
|
my ($phase, $dist, $system_command, $output, $exit_value) = @_; |
820
|
|
|
|
|
|
|
|
821
|
173
|
50
|
33
|
|
|
1473
|
unless ( defined $output && defined $exit_value ) { |
822
|
0
|
|
|
|
|
0
|
my $missing; |
823
|
0
|
0
|
0
|
|
|
0
|
if ( ! defined $output && ! defined $exit_value ) { |
|
|
0
|
0
|
|
|
|
|
824
|
0
|
|
|
|
|
0
|
$missing = "exit value and output" |
825
|
|
|
|
|
|
|
} |
826
|
|
|
|
|
|
|
elsif ( defined $output && !defined $exit_value ) { |
827
|
0
|
|
|
|
|
0
|
$missing = "exit value" |
828
|
|
|
|
|
|
|
} |
829
|
|
|
|
|
|
|
else { |
830
|
0
|
|
|
|
|
0
|
$missing = "output"; |
831
|
|
|
|
|
|
|
} |
832
|
0
|
|
|
|
|
0
|
$CPAN::Frontend->mywarn( |
833
|
|
|
|
|
|
|
"CPAN::Reporter: had errors capturing $missing. Tests abandoned" |
834
|
|
|
|
|
|
|
); |
835
|
0
|
|
|
|
|
0
|
return; |
836
|
|
|
|
|
|
|
} |
837
|
|
|
|
|
|
|
|
838
|
173
|
100
|
|
|
|
1443
|
if ( $dist->pretty_id =~ m{\w+/Perl6/} ) { |
839
|
3
|
|
|
|
|
31
|
$CPAN::Frontend->mywarn( |
840
|
|
|
|
|
|
|
"CPAN::Reporter: Won't report a Perl6 distribution." |
841
|
|
|
|
|
|
|
); |
842
|
3
|
|
|
|
|
120
|
return; |
843
|
|
|
|
|
|
|
} |
844
|
|
|
|
|
|
|
|
845
|
170
|
100
|
|
|
|
1858
|
my $result = { |
846
|
|
|
|
|
|
|
phase => $phase, |
847
|
|
|
|
|
|
|
dist => $dist, |
848
|
|
|
|
|
|
|
command => $system_command, |
849
|
|
|
|
|
|
|
is_make => _is_make( $system_command ), |
850
|
|
|
|
|
|
|
output => ref $output eq 'ARRAY' ? $output : [ split /\n/, $output ], |
851
|
|
|
|
|
|
|
exit_value => $exit_value, |
852
|
|
|
|
|
|
|
|
853
|
|
|
|
|
|
|
dist_basename => basename($dist->pretty_id), |
854
|
|
|
|
|
|
|
dist_name => $dist->base_id, |
855
|
|
|
|
|
|
|
}; |
856
|
|
|
|
|
|
|
|
857
|
|
|
|
|
|
|
|
858
|
170
|
100
|
|
|
|
18872
|
$result->{PL_file} = $result->{is_make} ? "Makefile.PL" : "Build.PL"; |
859
|
170
|
100
|
|
|
|
2478
|
$result->{make_cmd} = $result->{is_make} ? $Config{make} : "Build"; |
860
|
|
|
|
|
|
|
|
861
|
|
|
|
|
|
|
|
862
|
170
|
|
|
|
|
752
|
my $author = $dist->author; |
863
|
170
|
50
|
|
|
|
1161
|
$result->{author} = defined $author ? $author->fullname : "Author"; |
864
|
170
|
50
|
|
|
|
1382
|
$result->{author_id} = defined $author ? $author->id : "" ; |
865
|
|
|
|
|
|
|
|
866
|
170
|
|
|
|
|
1340
|
return $result; |
867
|
|
|
|
|
|
|
} |
868
|
|
|
|
|
|
|
|
869
|
|
|
|
|
|
|
|
870
|
|
|
|
|
|
|
|
871
|
|
|
|
|
|
|
|
872
|
|
|
|
|
|
|
|
873
|
|
|
|
|
|
|
sub _is_make { |
874
|
190
|
|
|
190
|
|
8617
|
my $command = shift; |
875
|
190
|
100
|
|
|
|
2440
|
return $command =~ m{\b(?:\S*make|Makefile.PL)\b}ims ? 1 : 0; |
876
|
|
|
|
|
|
|
} |
877
|
|
|
|
|
|
|
|
878
|
|
|
|
|
|
|
|
879
|
|
|
|
|
|
|
|
880
|
|
|
|
|
|
|
|
881
|
|
|
|
|
|
|
|
882
|
|
|
|
|
|
|
sub _is_PL { |
883
|
353
|
|
|
353
|
|
660
|
my $command = shift; |
884
|
353
|
100
|
|
|
|
3681
|
return $command =~ m{\b(?:Makefile|Build)\.PL\b}ims ? 1 : 0; |
885
|
|
|
|
|
|
|
} |
886
|
|
|
|
|
|
|
|
887
|
|
|
|
|
|
|
|
888
|
|
|
|
|
|
|
|
889
|
|
|
|
|
|
|
|
890
|
|
|
|
|
|
|
|
891
|
|
|
|
|
|
|
sub _max_length { |
892
|
352
|
|
|
352
|
|
1288
|
my ($first, @rest) = @_; |
893
|
352
|
|
|
|
|
475
|
my $max = length $first; |
894
|
352
|
|
|
|
|
641
|
for my $term ( @rest ) { |
895
|
6688
|
100
|
|
|
|
8151
|
$max = length $term if length $term > $max; |
896
|
|
|
|
|
|
|
} |
897
|
352
|
|
|
|
|
807
|
return $max; |
898
|
|
|
|
|
|
|
} |
899
|
|
|
|
|
|
|
|
900
|
|
|
|
|
|
|
|
901
|
|
|
|
|
|
|
|
902
|
|
|
|
|
|
|
|
903
|
|
|
|
|
|
|
|
904
|
|
|
|
|
|
|
|
905
|
|
|
|
|
|
|
|
906
|
|
|
|
|
|
|
|
907
|
|
|
|
|
|
|
|
908
|
|
|
|
|
|
|
|
909
|
|
|
|
|
|
|
sub _parse_tap_harness { |
910
|
262
|
|
|
262
|
|
330
|
my ($line) = @_; |
911
|
262
|
100
|
|
|
|
1051
|
if ( $line =~ m{^Result:\s+([A-Z]+)} ) { |
|
|
100
|
|
|
|
|
|
912
|
74
|
100
|
|
|
|
363
|
if ( $1 eq 'PASS' ) { |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
913
|
20
|
|
|
|
|
79
|
return ('pass', 'All tests successful'); |
914
|
|
|
|
|
|
|
} |
915
|
|
|
|
|
|
|
elsif ( $1 eq 'FAIL' ) { |
916
|
51
|
|
|
|
|
179
|
return ('fail', 'One or more tests failed'); |
917
|
|
|
|
|
|
|
} |
918
|
|
|
|
|
|
|
elsif ( $1 eq 'NOTESTS' ) { |
919
|
3
|
|
|
|
|
15
|
return ('unknown', 'No tests were run'); |
920
|
|
|
|
|
|
|
} |
921
|
|
|
|
|
|
|
} |
922
|
|
|
|
|
|
|
elsif ( $line =~ m{Bailout called\.\s+Further testing stopped}ms ) { |
923
|
2
|
|
|
|
|
7
|
return ( 'fail', 'Bailed out of tests'); |
924
|
|
|
|
|
|
|
} |
925
|
186
|
|
|
|
|
333
|
return; |
926
|
|
|
|
|
|
|
} |
927
|
|
|
|
|
|
|
|
928
|
|
|
|
|
|
|
|
929
|
|
|
|
|
|
|
|
930
|
|
|
|
|
|
|
|
931
|
|
|
|
|
|
|
|
932
|
|
|
|
|
|
|
|
933
|
|
|
|
|
|
|
|
934
|
|
|
|
|
|
|
|
935
|
|
|
|
|
|
|
|
936
|
|
|
|
|
|
|
sub _parse_test_harness { |
937
|
0
|
|
|
0
|
|
0
|
my ($line) = @_; |
938
|
0
|
0
|
|
|
|
0
|
if ( $line =~ m{^All tests successful}ms ) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
939
|
0
|
|
|
|
|
0
|
return ( 'pass', 'All tests successful' ); |
940
|
|
|
|
|
|
|
} |
941
|
|
|
|
|
|
|
elsif ( $line =~ m{^FAILED--no tests were run}ms ) { |
942
|
0
|
|
|
|
|
0
|
return ( 'unknown', 'No tests were run' ); |
943
|
|
|
|
|
|
|
} |
944
|
|
|
|
|
|
|
elsif ( $line =~ m{^FAILED--.*--no output}ms ) { |
945
|
0
|
|
|
|
|
0
|
return ( 'unknown', 'No tests were run'); |
946
|
|
|
|
|
|
|
} |
947
|
|
|
|
|
|
|
elsif ( $line =~ m{FAILED--Further testing stopped}ms ) { |
948
|
0
|
|
|
|
|
0
|
return ( 'fail', 'Bailed out of tests'); |
949
|
|
|
|
|
|
|
} |
950
|
|
|
|
|
|
|
elsif ( $line =~ m{^Failed }ms ) { |
951
|
0
|
|
|
|
|
0
|
return ( 'fail', 'One or more tests failed'); |
952
|
|
|
|
|
|
|
} |
953
|
|
|
|
|
|
|
else { |
954
|
0
|
|
|
|
|
0
|
return; |
955
|
|
|
|
|
|
|
} |
956
|
|
|
|
|
|
|
} |
957
|
|
|
|
|
|
|
|
958
|
|
|
|
|
|
|
|
959
|
|
|
|
|
|
|
|
960
|
|
|
|
|
|
|
|
961
|
|
|
|
|
|
|
|
962
|
|
|
|
|
|
|
my @prereq_sections = qw( |
963
|
|
|
|
|
|
|
requires build_requires configure_requires opt_requires opt_build_requires |
964
|
|
|
|
|
|
|
); |
965
|
|
|
|
|
|
|
|
966
|
|
|
|
|
|
|
sub _prereq_report { |
967
|
179
|
|
|
179
|
|
93701
|
my $dist = shift; |
968
|
179
|
|
|
|
|
258
|
my (%need, %have, %prereq_met, $report); |
969
|
|
|
|
|
|
|
|
970
|
|
|
|
|
|
|
|
971
|
179
|
|
|
|
|
604
|
my $prereq_pm = $dist->prereq_pm; |
972
|
|
|
|
|
|
|
|
973
|
179
|
50
|
|
|
|
1164
|
if ( ref $prereq_pm eq 'HASH' ) { |
974
|
|
|
|
|
|
|
|
975
|
179
|
|
|
|
|
776
|
foreach (values %$prereq_pm) { |
976
|
711
|
50
|
66
|
|
|
2723
|
if (defined && ref ne 'HASH') { |
977
|
0
|
|
|
|
|
0
|
require Data::Dumper; |
978
|
0
|
|
|
|
|
0
|
warn "Data error detecting prerequisites. Please report it to CPAN::Reporter bug tracker:"; |
979
|
0
|
|
|
|
|
0
|
warn Data::Dumper::Dumper($prereq_pm); |
980
|
0
|
|
|
|
|
0
|
die "Stopping"; |
981
|
|
|
|
|
|
|
} |
982
|
|
|
|
|
|
|
} |
983
|
|
|
|
|
|
|
|
984
|
179
|
|
|
|
|
639
|
for my $sec ( @prereq_sections ) { |
985
|
895
|
100
|
|
|
|
643
|
$need{$sec} = $prereq_pm->{$sec} if keys %{ $prereq_pm->{$sec} }; |
|
895
|
|
|
|
|
3887
|
|
986
|
|
|
|
|
|
|
} |
987
|
|
|
|
|
|
|
} |
988
|
|
|
|
|
|
|
|
989
|
|
|
|
|
|
|
|
990
|
179
|
100
|
66
|
|
|
1670
|
if ( $dist->{build_dir} && -d $dist->{build_dir} ) { |
991
|
72
|
|
|
|
|
1232
|
my $meta_yml = File::Spec->catfile($dist->{build_dir}, 'META.yml'); |
992
|
72
|
100
|
|
|
|
901
|
if ( -f $meta_yml ) { |
993
|
4
|
|
|
|
|
18
|
my @yaml = eval { Parse::CPAN::Meta::LoadFile($meta_yml) }; |
|
4
|
|
|
|
|
35
|
|
994
|
4
|
100
|
|
|
|
7895
|
if ( $@ ) { |
995
|
2
|
|
|
|
|
28
|
$CPAN::Frontend->mywarn( |
996
|
|
|
|
|
|
|
"CPAN::Reporter: error parsing META.yml\n" |
997
|
|
|
|
|
|
|
); |
998
|
|
|
|
|
|
|
} |
999
|
4
|
100
|
66
|
|
|
60
|
if ( ref $yaml[0] eq 'HASH' && |
1000
|
|
|
|
|
|
|
ref $yaml[0]{configure_requires} eq 'HASH' |
1001
|
|
|
|
|
|
|
) { |
1002
|
2
|
|
|
|
|
15
|
$need{configure_requires} = $yaml[0]{configure_requires}; |
1003
|
|
|
|
|
|
|
} |
1004
|
|
|
|
|
|
|
} |
1005
|
|
|
|
|
|
|
} |
1006
|
|
|
|
|
|
|
|
1007
|
|
|
|
|
|
|
|
1008
|
179
|
|
|
|
|
391
|
for my $section ( @prereq_sections ) { |
1009
|
895
|
100
|
|
|
|
2233
|
next unless ref $need{$section} eq 'HASH'; |
1010
|
137
|
|
|
|
|
193
|
my @prereq_list = %{ $need{$section} }; |
|
137
|
|
|
|
|
636
|
|
1011
|
137
|
50
|
|
|
|
348
|
next unless @prereq_list; |
1012
|
137
|
|
|
|
|
604
|
my $prereq_results = _version_finder( @prereq_list ); |
1013
|
137
|
|
|
|
|
270
|
for my $mod ( keys %{$prereq_results} ) { |
|
137
|
|
|
|
|
618
|
|
1014
|
185
|
|
|
|
|
854
|
$have{$section}{$mod} = $prereq_results->{$mod}{have}; |
1015
|
185
|
|
|
|
|
990
|
$prereq_met{$section}{$mod} = $prereq_results->{$mod}{met}; |
1016
|
|
|
|
|
|
|
} |
1017
|
|
|
|
|
|
|
} |
1018
|
|
|
|
|
|
|
|
1019
|
|
|
|
|
|
|
|
1020
|
179
|
|
|
|
|
431
|
my ($name_width, $need_width, $have_width) = (6, 4, 4); |
1021
|
179
|
|
|
|
|
402
|
for my $section ( @prereq_sections ) { |
1022
|
895
|
|
|
|
|
671
|
for my $module ( keys %{ $need{$section} } ) { |
|
895
|
|
|
|
|
2488
|
|
1023
|
185
|
|
|
|
|
305
|
my $name_length = length $module; |
1024
|
185
|
|
|
|
|
478
|
my $need_length = length $need{$section}{$module}; |
1025
|
185
|
|
|
|
|
258
|
my $have_length = length $have{$section}{$module}; |
1026
|
185
|
100
|
|
|
|
476
|
$name_width = $name_length if $name_length > $name_width; |
1027
|
185
|
100
|
|
|
|
407
|
$need_width = $need_length if $need_length > $need_width; |
1028
|
185
|
100
|
|
|
|
473
|
$have_width = $have_length if $have_length > $have_width; |
1029
|
|
|
|
|
|
|
} |
1030
|
|
|
|
|
|
|
} |
1031
|
|
|
|
|
|
|
|
1032
|
179
|
|
|
|
|
725
|
my $format_str = |
1033
|
|
|
|
|
|
|
" \%1s \%-${name_width}s \%-${need_width}s \%-${have_width}s\n"; |
1034
|
|
|
|
|
|
|
|
1035
|
|
|
|
|
|
|
|
1036
|
179
|
|
|
|
|
351
|
for my $section ( @prereq_sections ) { |
1037
|
895
|
100
|
|
|
|
634
|
if ( keys %{ $need{$section} } ) { |
|
895
|
|
|
|
|
1709
|
|
1038
|
137
|
|
|
|
|
420
|
$report .= "$section:\n\n"; |
1039
|
137
|
|
|
|
|
829
|
$report .= sprintf( $format_str, " ", qw/Module Need Have/ ); |
1040
|
137
|
|
|
|
|
696
|
$report .= sprintf( $format_str, " ", |
1041
|
|
|
|
|
|
|
"-" x $name_width, |
1042
|
|
|
|
|
|
|
"-" x $need_width, |
1043
|
|
|
|
|
|
|
"-" x $have_width ); |
1044
|
137
|
|
|
|
|
207
|
for my $module (sort {lc $a cmp lc $b} keys %{ $need{$section} } ) { |
|
138
|
|
|
|
|
109
|
|
|
137
|
|
|
|
|
575
|
|
1045
|
185
|
|
|
|
|
346
|
my $need = $need{$section}{$module}; |
1046
|
185
|
|
|
|
|
261
|
my $have = $have{$section}{$module}; |
1047
|
185
|
100
|
|
|
|
648
|
my $bad = $prereq_met{$section}{$module} ? " " : "!"; |
1048
|
185
|
|
|
|
|
612
|
$report .= |
1049
|
|
|
|
|
|
|
sprintf( $format_str, $bad, $module, $need, $have); |
1050
|
|
|
|
|
|
|
} |
1051
|
137
|
|
|
|
|
246
|
$report .= "\n"; |
1052
|
|
|
|
|
|
|
} |
1053
|
|
|
|
|
|
|
} |
1054
|
|
|
|
|
|
|
|
1055
|
179
|
|
100
|
|
|
2168
|
return $report || " No requirements found\n"; |
1056
|
|
|
|
|
|
|
} |
1057
|
|
|
|
|
|
|
|
1058
|
|
|
|
|
|
|
|
1059
|
|
|
|
|
|
|
|
1060
|
|
|
|
|
|
|
|
1061
|
|
|
|
|
|
|
|
1062
|
|
|
|
|
|
|
sub _print_grade_msg { |
1063
|
138
|
|
|
138
|
|
642
|
my ($phase, $result) = @_; |
1064
|
138
|
|
|
|
|
428
|
my ($grade, $msg) = ($result->{grade}, $result->{grade_msg}); |
1065
|
138
|
|
|
|
|
2461
|
$CPAN::Frontend->myprint( "CPAN::Reporter: $phase result is '$grade'"); |
1066
|
138
|
50
|
33
|
|
|
4147
|
$CPAN::Frontend->myprint(", $msg") if defined $msg && length $msg; |
1067
|
138
|
|
|
|
|
1234
|
$CPAN::Frontend->myprint(".\n"); |
1068
|
138
|
|
|
|
|
887
|
return; |
1069
|
|
|
|
|
|
|
} |
1070
|
|
|
|
|
|
|
|
1071
|
|
|
|
|
|
|
|
1072
|
|
|
|
|
|
|
|
1073
|
|
|
|
|
|
|
|
1074
|
|
|
|
|
|
|
|
1075
|
|
|
|
|
|
|
|
1076
|
|
|
|
|
|
|
|
1077
|
|
|
|
|
|
|
sub _prompt { |
1078
|
328
|
|
|
328
|
|
14577
|
my ($config, $option, $grade, $extra) = @_; |
1079
|
328
|
|
50
|
|
|
1348
|
$extra ||= q{}; |
1080
|
|
|
|
|
|
|
|
1081
|
328
|
|
|
|
|
732
|
my %spec = CPAN::Reporter::Config::_config_spec(); |
1082
|
|
|
|
|
|
|
|
1083
|
|
|
|
|
|
|
my $dispatch = CPAN::Reporter::Config::_validate_grade_action_pair( |
1084
|
328
|
|
50
|
|
|
1778
|
$option, join(q{ }, "default:no", $config->{$option} || '') |
1085
|
|
|
|
|
|
|
); |
1086
|
328
|
|
66
|
|
|
1102
|
my $action = $dispatch->{$grade} || $dispatch->{default}; |
1087
|
328
|
|
|
|
|
757
|
my $intro = $spec{$option}{prompt} . $extra . " (yes/no)"; |
1088
|
328
|
|
|
|
|
267
|
my $prompt; |
1089
|
328
|
100
|
|
|
|
1109
|
if ( $action =~ m{^ask/yes}i ) { |
|
|
100
|
|
|
|
|
|
1090
|
10
|
|
|
|
|
25
|
$prompt = CPAN::Shell::colorable_makemaker_prompt( $intro, "yes" ); |
1091
|
|
|
|
|
|
|
} |
1092
|
|
|
|
|
|
|
elsif ( $action =~ m{^ask(/no)?}i ) { |
1093
|
72
|
|
|
|
|
309
|
$prompt = CPAN::Shell::colorable_makemaker_prompt( $intro, "no" ); |
1094
|
|
|
|
|
|
|
} |
1095
|
|
|
|
|
|
|
else { |
1096
|
246
|
|
|
|
|
342
|
$prompt = $action; |
1097
|
|
|
|
|
|
|
} |
1098
|
328
|
|
|
|
|
6405
|
return lc $prompt; |
1099
|
|
|
|
|
|
|
} |
1100
|
|
|
|
|
|
|
|
1101
|
|
|
|
|
|
|
|
1102
|
|
|
|
|
|
|
|
1103
|
|
|
|
|
|
|
|
1104
|
|
|
|
|
|
|
|
1105
|
|
|
|
|
|
|
my %intro_para = ( |
1106
|
|
|
|
|
|
|
'pass' => <<'HERE', |
1107
|
|
|
|
|
|
|
Thank you for uploading your work to CPAN. Congratulations! |
1108
|
|
|
|
|
|
|
All tests were successful. |
1109
|
|
|
|
|
|
|
HERE |
1110
|
|
|
|
|
|
|
|
1111
|
|
|
|
|
|
|
'fail' => <<'HERE', |
1112
|
|
|
|
|
|
|
Thank you for uploading your work to CPAN. However, there was a problem |
1113
|
|
|
|
|
|
|
testing your distribution. |
1114
|
|
|
|
|
|
|
|
1115
|
|
|
|
|
|
|
If you think this report is invalid, please consult the CPAN Testers Wiki |
1116
|
|
|
|
|
|
|
for suggestions on how to avoid getting FAIL reports for missing library |
1117
|
|
|
|
|
|
|
or binary dependencies, unsupported operating systems, and so on: |
1118
|
|
|
|
|
|
|
|
1119
|
|
|
|
|
|
|
http://wiki.cpantesters.org/wiki/CPANAuthorNotes |
1120
|
|
|
|
|
|
|
HERE |
1121
|
|
|
|
|
|
|
|
1122
|
|
|
|
|
|
|
'unknown' => <<'HERE', |
1123
|
|
|
|
|
|
|
Thank you for uploading your work to CPAN. However, attempting to |
1124
|
|
|
|
|
|
|
test your distribution gave an inconclusive result. |
1125
|
|
|
|
|
|
|
|
1126
|
|
|
|
|
|
|
This could be because your distribution had an error during the make/build |
1127
|
|
|
|
|
|
|
stage, did not define tests, tests could not be found, because your tests were |
1128
|
|
|
|
|
|
|
interrupted before they finished, or because the results of the tests could not |
1129
|
|
|
|
|
|
|
be parsed. You may wish to consult the CPAN Testers Wiki: |
1130
|
|
|
|
|
|
|
|
1131
|
|
|
|
|
|
|
http://wiki.cpantesters.org/wiki/CPANAuthorNotes |
1132
|
|
|
|
|
|
|
HERE |
1133
|
|
|
|
|
|
|
|
1134
|
|
|
|
|
|
|
'na' => <<'HERE', |
1135
|
|
|
|
|
|
|
Thank you for uploading your work to CPAN. While attempting to build or test |
1136
|
|
|
|
|
|
|
this distribution, the distribution signaled that support is not available |
1137
|
|
|
|
|
|
|
either for this operating system or this version of Perl. Nevertheless, any |
1138
|
|
|
|
|
|
|
diagnostic output produced is provided below for reference. If this is not |
1139
|
|
|
|
|
|
|
what you expect, you may wish to consult the CPAN Testers Wiki: |
1140
|
|
|
|
|
|
|
|
1141
|
|
|
|
|
|
|
http://wiki.cpantesters.org/wiki/CPANAuthorNotes |
1142
|
|
|
|
|
|
|
HERE |
1143
|
|
|
|
|
|
|
|
1144
|
|
|
|
|
|
|
); |
1145
|
|
|
|
|
|
|
|
1146
|
|
|
|
|
|
|
sub _comment_text { |
1147
|
|
|
|
|
|
|
|
1148
|
|
|
|
|
|
|
|
1149
|
|
|
|
|
|
|
|
1150
|
117
|
|
|
117
|
|
131
|
my @comment_parts; |
1151
|
|
|
|
|
|
|
|
1152
|
|
|
|
|
|
|
|
1153
|
117
|
100
|
|
|
|
371
|
if ($ENV{AUTOMATED_TESTING}) { |
1154
|
111
|
|
|
|
|
261
|
push @comment_parts, |
1155
|
|
|
|
|
|
|
"this report is from an automated smoke testing program\n" |
1156
|
|
|
|
|
|
|
. "and was not reviewed by a human for accuracy" |
1157
|
|
|
|
|
|
|
} |
1158
|
|
|
|
|
|
|
|
1159
|
|
|
|
|
|
|
|
1160
|
117
|
|
|
|
|
277
|
my $confdir = CPAN::Reporter::Config::_get_config_dir(); |
1161
|
117
|
|
|
|
|
717
|
my $comment_file = File::Spec->catfile($confdir, 'comment.txt'); |
1162
|
117
|
100
|
66
|
|
|
2827
|
if ( -d $confdir && -f $comment_file && -r $comment_file ) { |
|
|
|
66
|
|
|
|
|
1163
|
2
|
50
|
|
1
|
|
76
|
open my $fh, '<:encoding(UTF-8)', $comment_file or die($!); |
|
1
|
|
|
|
|
6
|
|
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
11
|
|
1164
|
2
|
|
|
|
|
1372
|
my $text; |
1165
|
2
|
|
|
|
|
3
|
do { |
1166
|
2
|
|
|
|
|
6
|
local $/ = undef; |
1167
|
2
|
50
|
|
|
|
43
|
defined( $text = <$fh> ) or die($!); |
1168
|
|
|
|
|
|
|
}; |
1169
|
2
|
|
|
|
|
31
|
chomp($text); |
1170
|
2
|
|
|
|
|
4
|
push @comment_parts, $text; |
1171
|
2
|
|
|
|
|
21
|
close $fh; |
1172
|
|
|
|
|
|
|
} |
1173
|
|
|
|
|
|
|
|
1174
|
|
|
|
|
|
|
|
1175
|
117
|
100
|
|
|
|
350
|
if (scalar(@comment_parts) == 0) { |
1176
|
5
|
|
|
|
|
15
|
push @comment_parts, 'none provided'; |
1177
|
|
|
|
|
|
|
} |
1178
|
|
|
|
|
|
|
|
1179
|
|
|
|
|
|
|
|
1180
|
117
|
|
|
|
|
448
|
return join "\n\n", @comment_parts; |
1181
|
|
|
|
|
|
|
} |
1182
|
|
|
|
|
|
|
|
1183
|
|
|
|
|
|
|
sub _report_text { |
1184
|
117
|
|
|
117
|
|
141
|
my $data = shift; |
1185
|
117
|
|
|
|
|
148
|
my $test_log = join(q{},@{$data->{output}}); |
|
117
|
|
|
|
|
771
|
|
1186
|
117
|
50
|
|
|
|
364
|
if ( length $test_log > MAX_OUTPUT_LENGTH ) { |
1187
|
0
|
|
|
|
|
0
|
$test_log = substr( $test_log, 0, MAX_OUTPUT_LENGTH) . "\n"; |
1188
|
0
|
|
|
|
|
0
|
my $max_k = int(MAX_OUTPUT_LENGTH/1000) . "K"; |
1189
|
0
|
|
|
|
|
0
|
$test_log .= "\n[Output truncated after $max_k]\n\n"; |
1190
|
|
|
|
|
|
|
} |
1191
|
|
|
|
|
|
|
|
1192
|
117
|
|
|
|
|
288
|
my $comment_body = _comment_text(); |
1193
|
|
|
|
|
|
|
|
1194
|
|
|
|
|
|
|
|
1195
|
117
|
|
|
|
|
1959
|
my $output = << "ENDREPORT"; |
1196
|
|
|
|
|
|
|
Dear $data->{author}, |
1197
|
|
|
|
|
|
|
|
1198
|
|
|
|
|
|
|
This is a computer-generated report for $data->{dist_name} |
1199
|
|
|
|
|
|
|
on perl $data->{perl_version}, created by CPAN-Reporter-$CPAN::Reporter::VERSION\. |
1200
|
|
|
|
|
|
|
|
1201
|
|
|
|
|
|
|
$intro_para{ $data->{grade} } |
1202
|
|
|
|
|
|
|
Sections of this report: |
1203
|
|
|
|
|
|
|
|
1204
|
|
|
|
|
|
|
* Tester comments |
1205
|
|
|
|
|
|
|
* Program output |
1206
|
|
|
|
|
|
|
* Prerequisites |
1207
|
|
|
|
|
|
|
* Environment and other context |
1208
|
|
|
|
|
|
|
|
1209
|
|
|
|
|
|
|
------------------------------ |
1210
|
|
|
|
|
|
|
TESTER COMMENTS |
1211
|
|
|
|
|
|
|
------------------------------ |
1212
|
|
|
|
|
|
|
|
1213
|
|
|
|
|
|
|
Additional comments from tester: |
1214
|
|
|
|
|
|
|
|
1215
|
|
|
|
|
|
|
$comment_body |
1216
|
|
|
|
|
|
|
|
1217
|
|
|
|
|
|
|
------------------------------ |
1218
|
|
|
|
|
|
|
PROGRAM OUTPUT |
1219
|
|
|
|
|
|
|
------------------------------ |
1220
|
|
|
|
|
|
|
|
1221
|
|
|
|
|
|
|
Output from '$data->{command}': |
1222
|
|
|
|
|
|
|
|
1223
|
|
|
|
|
|
|
$test_log |
1224
|
|
|
|
|
|
|
------------------------------ |
1225
|
|
|
|
|
|
|
PREREQUISITES |
1226
|
|
|
|
|
|
|
------------------------------ |
1227
|
|
|
|
|
|
|
|
1228
|
|
|
|
|
|
|
Prerequisite modules loaded: |
1229
|
|
|
|
|
|
|
|
1230
|
|
|
|
|
|
|
$data->{prereq_pm} |
1231
|
|
|
|
|
|
|
------------------------------ |
1232
|
|
|
|
|
|
|
ENVIRONMENT AND OTHER CONTEXT |
1233
|
|
|
|
|
|
|
------------------------------ |
1234
|
|
|
|
|
|
|
|
1235
|
|
|
|
|
|
|
Environment variables: |
1236
|
|
|
|
|
|
|
|
1237
|
|
|
|
|
|
|
$data->{env_vars} |
1238
|
|
|
|
|
|
|
Perl special variables (and OS-specific diagnostics, for MSWin32): |
1239
|
|
|
|
|
|
|
|
1240
|
|
|
|
|
|
|
$data->{special_vars} |
1241
|
|
|
|
|
|
|
Perl module toolchain versions installed: |
1242
|
|
|
|
|
|
|
|
1243
|
|
|
|
|
|
|
$data->{toolchain_versions} |
1244
|
|
|
|
|
|
|
ENDREPORT |
1245
|
|
|
|
|
|
|
|
1246
|
117
|
|
|
|
|
453
|
return $output; |
1247
|
|
|
|
|
|
|
} |
1248
|
|
|
|
|
|
|
|
1249
|
|
|
|
|
|
|
|
1250
|
|
|
|
|
|
|
|
1251
|
|
|
|
|
|
|
|
1252
|
|
|
|
|
|
|
|
1253
|
|
|
|
|
|
|
sub _special_vars_report { |
1254
|
176
|
|
|
176
|
|
5387
|
my $special_vars = << "HERE"; |
1255
|
|
|
|
|
|
|
\$^X = $^X |
1256
|
|
|
|
|
|
|
\$UID/\$EUID = $< / $> |
1257
|
|
|
|
|
|
|
\$GID = $( |
1258
|
|
|
|
|
|
|
\$EGID = $) |
1259
|
|
|
|
|
|
|
HERE |
1260
|
176
|
50
|
33
|
|
|
686
|
if ( $^O eq 'MSWin32' && eval "require Win32" ) { |
1261
|
0
|
|
|
|
|
0
|
my @getosversion = Win32::GetOSVersion(); |
1262
|
0
|
|
|
|
|
0
|
my $getosversion = join(", ", @getosversion); |
1263
|
0
|
|
|
|
|
0
|
$special_vars .= " Win32::GetOSName = " . Win32::GetOSName() . "\n"; |
1264
|
0
|
|
|
|
|
0
|
$special_vars .= " Win32::GetOSVersion = $getosversion\n"; |
1265
|
0
|
|
|
|
|
0
|
$special_vars .= " Win32::FsType = " . Win32::FsType() . "\n"; |
1266
|
0
|
|
|
|
|
0
|
$special_vars .= " Win32::IsAdminUser = " . Win32::IsAdminUser() . "\n"; |
1267
|
|
|
|
|
|
|
} |
1268
|
176
|
|
|
|
|
641
|
return $special_vars; |
1269
|
|
|
|
|
|
|
} |
1270
|
|
|
|
|
|
|
|
1271
|
|
|
|
|
|
|
|
1272
|
|
|
|
|
|
|
|
1273
|
|
|
|
|
|
|
|
1274
|
|
|
|
|
|
|
|
1275
|
|
|
|
|
|
|
sub _split_redirect { |
1276
|
186
|
|
|
186
|
|
302
|
my $command = shift; |
1277
|
186
|
|
|
|
|
537
|
my ($cmd, $prefix) = ($command =~ m{\A(.+?)(\|.*)\z}); |
1278
|
186
|
100
|
|
|
|
399
|
if (defined $cmd) { |
1279
|
1
|
|
|
|
|
4
|
return ($cmd, $prefix); |
1280
|
|
|
|
|
|
|
} |
1281
|
|
|
|
|
|
|
else { |
1282
|
185
|
|
|
|
|
420
|
return $command |
1283
|
|
|
|
|
|
|
} |
1284
|
|
|
|
|
|
|
} |
1285
|
|
|
|
|
|
|
|
1286
|
|
|
|
|
|
|
|
1287
|
|
|
|
|
|
|
|
1288
|
|
|
|
|
|
|
|
1289
|
|
|
|
|
|
|
|
1290
|
|
|
|
|
|
|
|
1291
|
|
|
|
|
|
|
|
1292
|
|
|
|
|
|
|
|
1293
|
|
|
|
|
|
|
|
1294
|
|
|
|
|
|
|
|
1295
|
|
|
|
|
|
|
|
1296
|
|
|
|
|
|
|
my @CHARS = (qw/ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z |
1297
|
|
|
|
|
|
|
a b c d e f g h i j k l m n o p q r s t u v w x y z |
1298
|
|
|
|
|
|
|
0 1 2 3 4 5 6 7 8 9 _ |
1299
|
|
|
|
|
|
|
/); |
1300
|
|
|
|
|
|
|
|
1301
|
|
|
|
|
|
|
sub _temp_filename { |
1302
|
500
|
|
|
500
|
|
1119
|
my ($prefix) = @_; |
1303
|
500
|
50
|
|
|
|
1269
|
$prefix = q{} unless defined $prefix; |
1304
|
500
|
|
|
|
|
5562
|
$prefix .= $CHARS[ int( rand(@CHARS) ) ] for 0 .. 7; |
1305
|
500
|
|
|
|
|
11934
|
return File::Spec->catfile(File::Spec->tmpdir(), $prefix); |
1306
|
|
|
|
|
|
|
} |
1307
|
|
|
|
|
|
|
|
1308
|
|
|
|
|
|
|
|
1309
|
|
|
|
|
|
|
|
1310
|
|
|
|
|
|
|
|
1311
|
|
|
|
|
|
|
|
1312
|
|
|
|
|
|
|
|
1313
|
|
|
|
|
|
|
sub _timeout_wrapper { |
1314
|
15
|
|
|
15
|
|
25
|
my ($cmd, $timeout) = @_; |
1315
|
|
|
|
|
|
|
|
1316
|
|
|
|
|
|
|
|
1317
|
15
|
|
|
|
|
37
|
$cmd = quotemeta($cmd); |
1318
|
|
|
|
|
|
|
|
1319
|
15
|
|
|
|
|
103
|
my $wrapper = sprintf << 'HERE', $timeout, $cmd, $cmd; |
1320
|
|
|
|
|
|
|
use strict; |
1321
|
|
|
|
|
|
|
my ($pid, $exitcode); |
1322
|
|
|
|
|
|
|
eval { |
1323
|
|
|
|
|
|
|
$pid = fork; |
1324
|
|
|
|
|
|
|
if ($pid) { |
1325
|
|
|
|
|
|
|
local $SIG{CHLD}; |
1326
|
|
|
|
|
|
|
local $SIG{ALRM} = sub {die 'Timeout'}; |
1327
|
|
|
|
|
|
|
alarm %s; |
1328
|
|
|
|
|
|
|
my $wstat = waitpid $pid, 0; |
1329
|
|
|
|
|
|
|
alarm 0; |
1330
|
|
|
|
|
|
|
$exitcode = $wstat == -1 ? -1 : $?; |
1331
|
|
|
|
|
|
|
} elsif ( $pid == 0 ) { |
1332
|
|
|
|
|
|
|
setpgrp(0,0); # new process group |
1333
|
|
|
|
|
|
|
exec "%s"; |
1334
|
|
|
|
|
|
|
} |
1335
|
|
|
|
|
|
|
else { |
1336
|
|
|
|
|
|
|
die "Cannot fork: $!\n" unless defined $pid; |
1337
|
|
|
|
|
|
|
} |
1338
|
|
|
|
|
|
|
}; |
1339
|
|
|
|
|
|
|
if ($pid && $@ =~ /Timeout/){ |
1340
|
|
|
|
|
|
|
kill -9 => $pid; # and send to our child's whole process group |
1341
|
|
|
|
|
|
|
waitpid $pid, 0; |
1342
|
|
|
|
|
|
|
$exitcode = 9; # force result to look like SIGKILL |
1343
|
|
|
|
|
|
|
} |
1344
|
|
|
|
|
|
|
elsif ($@) { |
1345
|
|
|
|
|
|
|
die $@; |
1346
|
|
|
|
|
|
|
} |
1347
|
|
|
|
|
|
|
print "(%s exited with $exitcode)\n"; |
1348
|
|
|
|
|
|
|
HERE |
1349
|
15
|
|
|
|
|
34
|
return $wrapper; |
1350
|
|
|
|
|
|
|
} |
1351
|
|
|
|
|
|
|
|
1352
|
|
|
|
|
|
|
|
1353
|
|
|
|
|
|
|
|
1354
|
|
|
|
|
|
|
|
1355
|
|
|
|
|
|
|
|
1356
|
|
|
|
|
|
|
sub _timeout_wrapper_win32 { |
1357
|
0
|
|
|
0
|
|
0
|
my ($cmd, $timeout) = @_; |
1358
|
|
|
|
|
|
|
|
1359
|
0
|
|
0
|
|
|
0
|
$timeout ||= 0; |
1360
|
|
|
|
|
|
|
|
1361
|
0
|
|
|
|
|
0
|
eval "use Win32::Job ();"; |
1362
|
0
|
0
|
|
|
|
0
|
if ($@) { |
1363
|
0
|
|
|
|
|
0
|
$CPAN::Frontend->mywarn( << 'HERE' ); |
1364
|
|
|
|
|
|
|
CPAN::Reporter: you need Win32::Job for inactivity_timeout support. |
1365
|
|
|
|
|
|
|
Continuing without timeout... |
1366
|
|
|
|
|
|
|
HERE |
1367
|
0
|
|
|
|
|
0
|
return; |
1368
|
|
|
|
|
|
|
} |
1369
|
|
|
|
|
|
|
|
1370
|
0
|
|
|
|
|
0
|
my ($program) = split " ", $cmd; |
1371
|
0
|
0
|
|
|
|
0
|
if (! File::Spec->file_name_is_absolute( $program ) ) { |
1372
|
0
|
|
|
|
|
0
|
my $exe = $program . ".exe"; |
1373
|
0
|
|
|
|
|
0
|
my ($path) = grep { -e File::Spec->catfile($_,$exe) } |
1374
|
0
|
|
|
|
|
0
|
split /$Config{path_sep}/, $ENV{PATH}; |
1375
|
0
|
0
|
|
|
|
0
|
if (! $path) { |
1376
|
0
|
|
|
|
|
0
|
$CPAN::Frontend->mywarn( << "HERE" ); |
1377
|
|
|
|
|
|
|
CPAN::Reporter: can't locate $exe in the PATH. |
1378
|
|
|
|
|
|
|
Continuing without timeout... |
1379
|
|
|
|
|
|
|
HERE |
1380
|
0
|
|
|
|
|
0
|
return; |
1381
|
|
|
|
|
|
|
} |
1382
|
0
|
|
|
|
|
0
|
$program = File::Spec->catfile($path,$exe); |
1383
|
|
|
|
|
|
|
} |
1384
|
|
|
|
|
|
|
|
1385
|
|
|
|
|
|
|
|
1386
|
0
|
|
|
|
|
0
|
$_ = quotemeta($_) for ($program, $cmd); |
1387
|
|
|
|
|
|
|
|
1388
|
0
|
|
|
|
|
0
|
my $wrapper = sprintf << 'HERE', $program, $cmd, $timeout; |
1389
|
|
|
|
|
|
|
use strict; |
1390
|
|
|
|
|
|
|
use Win32::Job; |
1391
|
|
|
|
|
|
|
my $executable = "%s"; |
1392
|
|
|
|
|
|
|
my $cmd_line = "%s"; |
1393
|
|
|
|
|
|
|
my $timeout = %s; |
1394
|
|
|
|
|
|
|
|
1395
|
|
|
|
|
|
|
my $job = Win32::Job->new() or die $^E; |
1396
|
|
|
|
|
|
|
my $ppid = $job->spawn($executable, $cmd_line); |
1397
|
|
|
|
|
|
|
$job->run($timeout); |
1398
|
|
|
|
|
|
|
my $status = $job->status; |
1399
|
|
|
|
|
|
|
my $exitcode = $status->{$ppid}{exitcode}; |
1400
|
|
|
|
|
|
|
if ( $exitcode == 293 ) { |
1401
|
|
|
|
|
|
|
$exitcode = 9; # map Win32::Job kill (293) to SIGKILL (9) |
1402
|
|
|
|
|
|
|
} |
1403
|
|
|
|
|
|
|
elsif ( $exitcode & 255 ) { |
1404
|
|
|
|
|
|
|
$exitcode = $exitcode << 8; # how perl expects it |
1405
|
|
|
|
|
|
|
} |
1406
|
|
|
|
|
|
|
print "($cmd_line exited with $exitcode)\n"; |
1407
|
|
|
|
|
|
|
HERE |
1408
|
0
|
|
|
|
|
0
|
return $wrapper; |
1409
|
|
|
|
|
|
|
} |
1410
|
|
|
|
|
|
|
|
1411
|
|
|
|
|
|
|
|
1412
|
|
|
|
|
|
|
|
1413
|
|
|
|
|
|
|
|
1414
|
|
|
|
|
|
|
|
1415
|
|
|
|
|
|
|
my @toolchain_mods= qw( |
1416
|
|
|
|
|
|
|
CPAN |
1417
|
|
|
|
|
|
|
CPAN::Meta |
1418
|
|
|
|
|
|
|
Cwd |
1419
|
|
|
|
|
|
|
ExtUtils::CBuilder |
1420
|
|
|
|
|
|
|
ExtUtils::Command |
1421
|
|
|
|
|
|
|
ExtUtils::Install |
1422
|
|
|
|
|
|
|
ExtUtils::MakeMaker |
1423
|
|
|
|
|
|
|
ExtUtils::Manifest |
1424
|
|
|
|
|
|
|
ExtUtils::ParseXS |
1425
|
|
|
|
|
|
|
File::Spec |
1426
|
|
|
|
|
|
|
JSON |
1427
|
|
|
|
|
|
|
JSON::PP |
1428
|
|
|
|
|
|
|
Module::Build |
1429
|
|
|
|
|
|
|
Module::Signature |
1430
|
|
|
|
|
|
|
Parse::CPAN::Meta |
1431
|
|
|
|
|
|
|
Test::Harness |
1432
|
|
|
|
|
|
|
Test::More |
1433
|
|
|
|
|
|
|
YAML |
1434
|
|
|
|
|
|
|
YAML::Syck |
1435
|
|
|
|
|
|
|
version |
1436
|
|
|
|
|
|
|
); |
1437
|
|
|
|
|
|
|
|
1438
|
|
|
|
|
|
|
sub _toolchain_report { |
1439
|
176
|
|
|
176
|
|
1744
|
my ($result) = @_; |
1440
|
|
|
|
|
|
|
|
1441
|
176
|
|
|
|
|
486
|
my $installed = _version_finder( map { $_ => 0 } @toolchain_mods ); |
|
3520
|
|
|
|
|
4059
|
|
1442
|
176
|
|
|
|
|
2041
|
$result->{toolchain} = $installed; |
1443
|
|
|
|
|
|
|
|
1444
|
176
|
|
|
|
|
1588
|
my $mod_width = _max_length( keys %$installed ); |
1445
|
|
|
|
|
|
|
my $ver_width = _max_length( |
1446
|
176
|
|
|
|
|
751
|
map { $installed->{$_}{have} } keys %$installed |
|
3520
|
|
|
|
|
3442
|
|
1447
|
|
|
|
|
|
|
); |
1448
|
|
|
|
|
|
|
|
1449
|
176
|
|
|
|
|
905
|
my $format = " \%-${mod_width}s \%-${ver_width}s\n"; |
1450
|
|
|
|
|
|
|
|
1451
|
176
|
|
|
|
|
424
|
my $report = ""; |
1452
|
176
|
|
|
|
|
1234
|
$report .= sprintf( $format, "Module", "Have" ); |
1453
|
176
|
|
|
|
|
801
|
$report .= sprintf( $format, "-" x $mod_width, "-" x $ver_width ); |
1454
|
|
|
|
|
|
|
|
1455
|
176
|
|
|
|
|
2126
|
for my $var ( sort keys %$installed ) { |
1456
|
|
|
|
|
|
|
$report .= sprintf(" \%-${mod_width}s \%-${ver_width}s\n", |
1457
|
3520
|
|
|
|
|
5745
|
$var, $installed->{$var}{have} ); |
1458
|
|
|
|
|
|
|
} |
1459
|
|
|
|
|
|
|
|
1460
|
176
|
|
|
|
|
1083
|
return $report; |
1461
|
|
|
|
|
|
|
} |
1462
|
|
|
|
|
|
|
|
1463
|
|
|
|
|
|
|
|
1464
|
|
|
|
|
|
|
|
1465
|
|
|
|
|
|
|
|
1466
|
|
|
|
|
|
|
|
1467
|
|
|
|
|
|
|
|
1468
|
|
|
|
|
|
|
|
1469
|
|
|
|
|
|
|
|
1470
|
|
|
|
|
|
|
|
1471
|
|
|
|
|
|
|
sub _validate_metabase_args { |
1472
|
116
|
|
|
116
|
|
302
|
my @transport_args = @_; |
1473
|
116
|
|
|
|
|
158
|
shift @transport_args; |
1474
|
116
|
|
|
|
|
146
|
my (%args, $error); |
1475
|
|
|
|
|
|
|
|
1476
|
116
|
50
|
|
|
|
397
|
if ( @transport_args % 2 != 0 ) { |
1477
|
0
|
|
|
|
|
0
|
$error = << "TRANSPORT_ARGS"; |
1478
|
|
|
|
|
|
|
|
1479
|
|
|
|
|
|
|
CPAN::Reporter: Metabase 'transport' option had odd number of |
1480
|
|
|
|
|
|
|
parameters in the config file. See documentation for proper |
1481
|
|
|
|
|
|
|
configuration format. |
1482
|
|
|
|
|
|
|
|
1483
|
|
|
|
|
|
|
TRANSPORT_ARGS |
1484
|
|
|
|
|
|
|
} |
1485
|
|
|
|
|
|
|
else { |
1486
|
116
|
|
|
|
|
554
|
%args = @transport_args; |
1487
|
|
|
|
|
|
|
|
1488
|
116
|
|
|
|
|
261
|
for my $key ( qw/uri id_file/ ) { |
1489
|
232
|
50
|
|
|
|
572
|
if ( ! $args{$key} ) { |
1490
|
0
|
|
|
|
|
0
|
$error = << "TRANSPORT_ARGS"; |
1491
|
|
|
|
|
|
|
|
1492
|
|
|
|
|
|
|
CPAN::Reporter: Metabase 'transport' option did not have |
1493
|
|
|
|
|
|
|
a '$key' parameter in the config file. See documentation for |
1494
|
|
|
|
|
|
|
proper configuration format. |
1495
|
|
|
|
|
|
|
|
1496
|
|
|
|
|
|
|
TRANSPORT_ARGS |
1497
|
|
|
|
|
|
|
} |
1498
|
|
|
|
|
|
|
} |
1499
|
|
|
|
|
|
|
} |
1500
|
|
|
|
|
|
|
|
1501
|
116
|
50
|
|
|
|
297
|
if ( $error ) { |
1502
|
0
|
|
|
|
|
0
|
$CPAN::Frontend->mywarn( $error ); |
1503
|
0
|
|
|
|
|
0
|
return; |
1504
|
|
|
|
|
|
|
} |
1505
|
|
|
|
|
|
|
|
1506
|
116
|
|
|
|
|
372
|
$args{id_file} = CPAN::Reporter::Config::_normalize_id_file( $args{id_file} ); |
1507
|
|
|
|
|
|
|
|
1508
|
116
|
50
|
|
|
|
1819
|
if ( ! -r $args{id_file} ) { |
1509
|
0
|
|
|
|
|
0
|
$CPAN::Frontend->mywarn( <<"TRANSPORT_ARGS" ); |
1510
|
|
|
|
|
|
|
|
1511
|
|
|
|
|
|
|
CPAN::Reporter: Could not find Metabase transport 'id_file' parameter |
1512
|
|
|
|
|
|
|
located at '$args{id_file}'. |
1513
|
|
|
|
|
|
|
See documentation for proper configuration of the 'transport' setting. |
1514
|
|
|
|
|
|
|
|
1515
|
|
|
|
|
|
|
TRANSPORT_ARGS |
1516
|
0
|
|
|
|
|
0
|
return; |
1517
|
|
|
|
|
|
|
} |
1518
|
|
|
|
|
|
|
|
1519
|
116
|
|
|
|
|
688
|
return ('Metabase', %args); |
1520
|
|
|
|
|
|
|
} |
1521
|
|
|
|
|
|
|
|
1522
|
|
|
|
|
|
|
|
1523
|
|
|
|
|
|
|
|
1524
|
|
|
|
|
|
|
|
1525
|
|
|
|
|
|
|
|
1526
|
|
|
|
|
|
|
|
1527
|
|
|
|
|
|
|
|
1528
|
|
|
|
|
|
|
|
1529
|
|
|
|
|
|
|
|
1530
|
|
|
|
|
|
|
|
1531
|
|
|
|
|
|
|
|
1532
|
|
|
|
|
|
|
|
1533
|
|
|
|
|
|
|
|
1534
|
|
|
|
|
|
|
|
1535
|
|
|
|
|
|
|
|
1536
|
|
|
|
|
|
|
|
1537
|
|
|
|
|
|
|
|
1538
|
|
|
|
|
|
|
my $version_finder = $INC{'CPAN/Reporter/PrereqCheck.pm'}; |
1539
|
|
|
|
|
|
|
|
1540
|
|
|
|
|
|
|
sub _version_finder { |
1541
|
314
|
|
|
314
|
|
5212
|
my %prereqs = @_; |
1542
|
|
|
|
|
|
|
|
1543
|
314
|
|
|
|
|
4699
|
my $perl = Probe::Perl->find_perl_interpreter(); |
1544
|
314
|
|
|
|
|
6709
|
my @prereq_results; |
1545
|
|
|
|
|
|
|
|
1546
|
314
|
|
|
|
|
1107
|
my $prereq_input = _temp_filename( 'CPAN-Reporter-PI-' ); |
1547
|
314
|
50
|
|
|
|
4094
|
my $fh = IO::File->new( $prereq_input, "w" ) |
1548
|
|
|
|
|
|
|
or die "Could not create temporary '$prereq_input' for prereq analysis: $!"; |
1549
|
314
|
|
|
|
|
61784
|
$fh->print( map { "$_ $prereqs{$_}\n" } keys %prereqs ); |
|
3719
|
|
|
|
|
7660
|
|
1550
|
314
|
|
|
|
|
4237
|
$fh->close; |
1551
|
|
|
|
|
|
|
|
1552
|
314
|
|
|
314
|
|
26533
|
my $prereq_result = capture { system( $perl, $version_finder, '<', $prereq_input ) }; |
|
314
|
|
|
|
|
85240257
|
|
1553
|
|
|
|
|
|
|
|
1554
|
314
|
|
|
|
|
419075
|
unlink $prereq_input; |
1555
|
|
|
|
|
|
|
|
1556
|
314
|
|
|
|
|
724
|
my %result; |
1557
|
314
|
|
|
|
|
2534
|
for my $line ( split "\n", $prereq_result ) { |
1558
|
3719
|
50
|
|
|
|
5866
|
next unless length $line; |
1559
|
3719
|
|
|
|
|
7668
|
my ($mod, $met, $have) = split " ", $line; |
1560
|
3719
|
50
|
33
|
|
|
17634
|
unless ( defined($mod) && defined($met) && defined($have) ) { |
|
|
|
33
|
|
|
|
|
1561
|
0
|
|
|
|
|
0
|
$CPAN::Frontend->mywarn( |
1562
|
|
|
|
|
|
|
"Error parsing output from CPAN::Reporter::PrereqCheck:\n" . |
1563
|
|
|
|
|
|
|
$line |
1564
|
|
|
|
|
|
|
); |
1565
|
0
|
|
|
|
|
0
|
next; |
1566
|
|
|
|
|
|
|
} |
1567
|
3719
|
|
|
|
|
11468
|
$result{$mod}{have} = $have; |
1568
|
3719
|
|
|
|
|
5442
|
$result{$mod}{met} = $met; |
1569
|
|
|
|
|
|
|
} |
1570
|
314
|
|
|
|
|
4523
|
return \%result; |
1571
|
|
|
|
|
|
|
} |
1572
|
|
|
|
|
|
|
|
1573
|
|
|
|
|
|
|
1; |
1574
|
|
|
|
|
|
|
|
1575
|
|
|
|
|
|
|
|
1576
|
|
|
|
|
|
|
|
1577
|
|
|
|
|
|
|
=pod |
1578
|
|
|
|
|
|
|
|
1579
|
|
|
|
|
|
|
=encoding UTF-8 |
1580
|
|
|
|
|
|
|
|
1581
|
|
|
|
|
|
|
=head1 NAME |
1582
|
|
|
|
|
|
|
|
1583
|
|
|
|
|
|
|
CPAN::Reporter - Adds CPAN Testers reporting to CPAN.pm |
1584
|
|
|
|
|
|
|
|
1585
|
|
|
|
|
|
|
=head1 VERSION |
1586
|
|
|
|
|
|
|
|
1587
|
|
|
|
|
|
|
version 1.2017 |
1588
|
|
|
|
|
|
|
|
1589
|
|
|
|
|
|
|
=head1 SYNOPSIS |
1590
|
|
|
|
|
|
|
|
1591
|
|
|
|
|
|
|
From the CPAN shell: |
1592
|
|
|
|
|
|
|
|
1593
|
|
|
|
|
|
|
cpan> install Task::CPAN::Reporter |
1594
|
|
|
|
|
|
|
cpan> reload cpan |
1595
|
|
|
|
|
|
|
cpan> o conf init test_report |
1596
|
|
|
|
|
|
|
|
1597
|
|
|
|
|
|
|
Installing L<Task::CPAN::Reporter> will pull in additional dependencies |
1598
|
|
|
|
|
|
|
that new CPAN Testers will need. |
1599
|
|
|
|
|
|
|
|
1600
|
|
|
|
|
|
|
Advanced CPAN Testers with custom L<Test::Reporter::Transport> setups |
1601
|
|
|
|
|
|
|
may wish to install only CPAN::Reporter, which has fewer dependencies. |
1602
|
|
|
|
|
|
|
|
1603
|
|
|
|
|
|
|
=head1 DESCRIPTION |
1604
|
|
|
|
|
|
|
|
1605
|
|
|
|
|
|
|
The CPAN Testers project captures and analyzes detailed results from building |
1606
|
|
|
|
|
|
|
and testing CPAN distributions on multiple operating systems and multiple |
1607
|
|
|
|
|
|
|
versions of Perl. This provides valuable feedback to module authors and |
1608
|
|
|
|
|
|
|
potential users to identify bugs or platform compatibility issues and improves |
1609
|
|
|
|
|
|
|
the overall quality and value of CPAN. |
1610
|
|
|
|
|
|
|
|
1611
|
|
|
|
|
|
|
One way individuals can contribute is to send a report for each module that |
1612
|
|
|
|
|
|
|
they test or install. CPAN::Reporter is an add-on for the CPAN.pm module to |
1613
|
|
|
|
|
|
|
send the results of building and testing modules to the CPAN Testers project. |
1614
|
|
|
|
|
|
|
Full support for CPAN::Reporter is available in CPAN.pm as of version 1.92. |
1615
|
|
|
|
|
|
|
|
1616
|
|
|
|
|
|
|
=for Pod::Coverage configure |
1617
|
|
|
|
|
|
|
grade_PL |
1618
|
|
|
|
|
|
|
grade_make |
1619
|
|
|
|
|
|
|
grade_test |
1620
|
|
|
|
|
|
|
record_command |
1621
|
|
|
|
|
|
|
test |
1622
|
|
|
|
|
|
|
|
1623
|
|
|
|
|
|
|
=head1 GETTING STARTED |
1624
|
|
|
|
|
|
|
|
1625
|
|
|
|
|
|
|
=head2 Installation |
1626
|
|
|
|
|
|
|
|
1627
|
|
|
|
|
|
|
The first step in using CPAN::Reporter is to install it using whatever |
1628
|
|
|
|
|
|
|
version of CPAN.pm is already installed. CPAN.pm will be upgraded as |
1629
|
|
|
|
|
|
|
a dependency if necessary. |
1630
|
|
|
|
|
|
|
|
1631
|
|
|
|
|
|
|
cpan> install CPAN::Reporter |
1632
|
|
|
|
|
|
|
|
1633
|
|
|
|
|
|
|
If CPAN.pm was upgraded, it needs to be reloaded. |
1634
|
|
|
|
|
|
|
|
1635
|
|
|
|
|
|
|
cpan> reload cpan |
1636
|
|
|
|
|
|
|
|
1637
|
|
|
|
|
|
|
=head2 Configuration |
1638
|
|
|
|
|
|
|
|
1639
|
|
|
|
|
|
|
If upgrading from a very old version of CPAN.pm, users may be prompted to renew |
1640
|
|
|
|
|
|
|
their configuration settings, including the 'test_report' option to enable |
1641
|
|
|
|
|
|
|
CPAN::Reporter. |
1642
|
|
|
|
|
|
|
|
1643
|
|
|
|
|
|
|
If not prompted automatically, users should manually initialize CPAN::Reporter |
1644
|
|
|
|
|
|
|
support. After enabling CPAN::Reporter, CPAN.pm will automatically continue |
1645
|
|
|
|
|
|
|
with interactive configuration of CPAN::Reporter options. |
1646
|
|
|
|
|
|
|
|
1647
|
|
|
|
|
|
|
cpan> o conf init test_report |
1648
|
|
|
|
|
|
|
|
1649
|
|
|
|
|
|
|
Users will need to enter an email address in one of the following formats: |
1650
|
|
|
|
|
|
|
|
1651
|
|
|
|
|
|
|
johndoe@example.com |
1652
|
|
|
|
|
|
|
John Doe <johndoe@example.com> |
1653
|
|
|
|
|
|
|
"John Q. Public" <johnqpublic@example.com> |
1654
|
|
|
|
|
|
|
|
1655
|
|
|
|
|
|
|
Users that are new to CPAN::Reporter should accept the recommended values |
1656
|
|
|
|
|
|
|
for other configuration options. |
1657
|
|
|
|
|
|
|
|
1658
|
|
|
|
|
|
|
Users will be prompted to create a I<Metabase profile> file that uniquely |
1659
|
|
|
|
|
|
|
identifies their test reports. See L</"The Metabase"> below for details. |
1660
|
|
|
|
|
|
|
|
1661
|
|
|
|
|
|
|
After completing interactive configuration, be sure to commit (save) the CPAN |
1662
|
|
|
|
|
|
|
configuration changes. |
1663
|
|
|
|
|
|
|
|
1664
|
|
|
|
|
|
|
cpan> o conf commit |
1665
|
|
|
|
|
|
|
|
1666
|
|
|
|
|
|
|
See L<CPAN::Reporter::Config> for advanced configuration settings. |
1667
|
|
|
|
|
|
|
|
1668
|
|
|
|
|
|
|
=head3 The Metabase |
1669
|
|
|
|
|
|
|
|
1670
|
|
|
|
|
|
|
CPAN::Reporter sends test reports to a server known as the Metabase. This |
1671
|
|
|
|
|
|
|
requires an active Internet connection and a profile file. To create the |
1672
|
|
|
|
|
|
|
profile, users will need to run C<<< metabase-profile >>> from a terminal window and |
1673
|
|
|
|
|
|
|
fill the information at the prompts. This will create a file called |
1674
|
|
|
|
|
|
|
C<<< metabase_id.json >>> in the current directory. That file should be moved to the |
1675
|
|
|
|
|
|
|
C<<< .cpanreporter >>> directory inside the user's home directory. |
1676
|
|
|
|
|
|
|
|
1677
|
|
|
|
|
|
|
Users with an existing metabase profile file (e.g. from another machine), |
1678
|
|
|
|
|
|
|
should copy it into the C<<< .cpanreporter >>> directory instead of creating |
1679
|
|
|
|
|
|
|
a new one. Profile files may be located outside the C<<< .cpanreporter >>> |
1680
|
|
|
|
|
|
|
directory by following instructions in L<CPAN::Reporter::Config>. |
1681
|
|
|
|
|
|
|
|
1682
|
|
|
|
|
|
|
=head3 Default Test Comments |
1683
|
|
|
|
|
|
|
|
1684
|
|
|
|
|
|
|
This module puts default text into the "TESTER COMMENTS" section, typically, |
1685
|
|
|
|
|
|
|
"none provided" if doing interactive testing, or, if doing smoke testing that |
1686
|
|
|
|
|
|
|
sets CE<lt>$ENV{AUTOMATED_TESTING}E<gt> to a true value, "this report is from an |
1687
|
|
|
|
|
|
|
automated smoke testing program and was not reviewed by a human for |
1688
|
|
|
|
|
|
|
accuracy." If CE<lt>CPAN::ReporterE<gt> is configured to allow editing of the |
1689
|
|
|
|
|
|
|
report, this can be edited during submission. |
1690
|
|
|
|
|
|
|
|
1691
|
|
|
|
|
|
|
If you wish to override the default comment, you can create a file named |
1692
|
|
|
|
|
|
|
CE<lt>comment.txtE<gt> in the configuration directory (typically C<<< .cpanreporter >>> |
1693
|
|
|
|
|
|
|
under the user's home directory), with the default comment you would |
1694
|
|
|
|
|
|
|
like to appear. |
1695
|
|
|
|
|
|
|
|
1696
|
|
|
|
|
|
|
Note that if your test is an automated smoke |
1697
|
|
|
|
|
|
|
test (CE<lt>$ENV{AUTOMATED_TESTING}E<gt> is set to a true value), the smoke |
1698
|
|
|
|
|
|
|
test notice ("this report is from an automated smoke testing program and |
1699
|
|
|
|
|
|
|
was not reviewed by a human for accuracy") is included along with a blank |
1700
|
|
|
|
|
|
|
line before your CE<lt>comment.txtE<gt>, so that it is always possible to |
1701
|
|
|
|
|
|
|
distinguish automated tests from non-automated tests that use this |
1702
|
|
|
|
|
|
|
module. |
1703
|
|
|
|
|
|
|
|
1704
|
|
|
|
|
|
|
=head2 Using CPAN::Reporter |
1705
|
|
|
|
|
|
|
|
1706
|
|
|
|
|
|
|
Once CPAN::Reporter is enabled and configured, test or install modules with |
1707
|
|
|
|
|
|
|
CPAN.pm as usual. |
1708
|
|
|
|
|
|
|
|
1709
|
|
|
|
|
|
|
For example, to test the File::Marker module: |
1710
|
|
|
|
|
|
|
|
1711
|
|
|
|
|
|
|
cpan> test File::Marker |
1712
|
|
|
|
|
|
|
|
1713
|
|
|
|
|
|
|
If a distribution's tests fail, users will be prompted to edit the report to |
1714
|
|
|
|
|
|
|
add additional information that might help the author understand the failure. |
1715
|
|
|
|
|
|
|
|
1716
|
|
|
|
|
|
|
=head1 UNDERSTANDING TEST GRADES |
1717
|
|
|
|
|
|
|
|
1718
|
|
|
|
|
|
|
CPAN::Reporter will assign one of the following grades to the report: |
1719
|
|
|
|
|
|
|
|
1720
|
|
|
|
|
|
|
=over |
1721
|
|
|
|
|
|
|
|
1722
|
|
|
|
|
|
|
=item * |
1723
|
|
|
|
|
|
|
|
1724
|
|
|
|
|
|
|
C<<< pass >>> -- distribution built and tested correctly |
1725
|
|
|
|
|
|
|
|
1726
|
|
|
|
|
|
|
=item * |
1727
|
|
|
|
|
|
|
|
1728
|
|
|
|
|
|
|
C<<< fail >>> -- distribution failed to test correctly |
1729
|
|
|
|
|
|
|
|
1730
|
|
|
|
|
|
|
=item * |
1731
|
|
|
|
|
|
|
|
1732
|
|
|
|
|
|
|
C<<< unknown >>> -- distribution failed to build, had no test suite or outcome was |
1733
|
|
|
|
|
|
|
inconclusive |
1734
|
|
|
|
|
|
|
|
1735
|
|
|
|
|
|
|
=item * |
1736
|
|
|
|
|
|
|
|
1737
|
|
|
|
|
|
|
C<<< na >>> --- distribution is not applicable to this platform andE<sol>or |
1738
|
|
|
|
|
|
|
version of Perl |
1739
|
|
|
|
|
|
|
|
1740
|
|
|
|
|
|
|
=back |
1741
|
|
|
|
|
|
|
|
1742
|
|
|
|
|
|
|
In returning results of the test suite to CPAN.pm, "pass" and "unknown" are |
1743
|
|
|
|
|
|
|
considered successful attempts to "make test" or "Build test" and will not |
1744
|
|
|
|
|
|
|
prevent installation. "fail" and "na" are considered to be failures and |
1745
|
|
|
|
|
|
|
CPAN.pm will not install unless forced. |
1746
|
|
|
|
|
|
|
|
1747
|
|
|
|
|
|
|
An error from Makefile.PLE<sol>Build.PL or makeE<sol>Build will also be graded as |
1748
|
|
|
|
|
|
|
"unknown" and a failure will be signaled to CPAN.pm. |
1749
|
|
|
|
|
|
|
|
1750
|
|
|
|
|
|
|
If prerequisites specified in C<<< Makefile.PL >>> or C<<< Build.PL >>> are not available, |
1751
|
|
|
|
|
|
|
no report will be generated and a failure will be signaled to CPAN.pm. |
1752
|
|
|
|
|
|
|
|
1753
|
|
|
|
|
|
|
=head1 PRIVACY WARNING |
1754
|
|
|
|
|
|
|
|
1755
|
|
|
|
|
|
|
CPAN::Reporter includes information in the test report about environment |
1756
|
|
|
|
|
|
|
variables and special Perl variables that could be affecting test results in |
1757
|
|
|
|
|
|
|
order to help module authors interpret the results of the tests. This includes |
1758
|
|
|
|
|
|
|
information about paths, terminal, locale, userE<sol>group ID, installed toolchain |
1759
|
|
|
|
|
|
|
modules (e.g. ExtUtils::MakeMaker) and so on. |
1760
|
|
|
|
|
|
|
|
1761
|
|
|
|
|
|
|
These have been intentionally limited to items that should not cause harmful |
1762
|
|
|
|
|
|
|
personal information to be revealed -- it does I<not> include your entire |
1763
|
|
|
|
|
|
|
environment. Nevertheless, please do not use CPAN::Reporter if you are |
1764
|
|
|
|
|
|
|
concerned about the disclosure of this information as part of your test report. |
1765
|
|
|
|
|
|
|
|
1766
|
|
|
|
|
|
|
Users wishing to review this information may choose to edit the report |
1767
|
|
|
|
|
|
|
prior to sending it. |
1768
|
|
|
|
|
|
|
|
1769
|
|
|
|
|
|
|
=head1 BUGS |
1770
|
|
|
|
|
|
|
|
1771
|
|
|
|
|
|
|
Using command_timeout on Linux may cause problems. See |
1772
|
|
|
|
|
|
|
L<https://rt.cpan.org/Ticket/Display.html?id=62310> |
1773
|
|
|
|
|
|
|
|
1774
|
|
|
|
|
|
|
Please report any bugs or feature using the CPAN Request Tracker. |
1775
|
|
|
|
|
|
|
Bugs can be submitted through the web interface at |
1776
|
|
|
|
|
|
|
L<http://rt.cpan.org/Dist/Display.html?Queue=CPAN-Reporter> |
1777
|
|
|
|
|
|
|
|
1778
|
|
|
|
|
|
|
When submitting a bug or request, please include a test-file or a patch to an |
1779
|
|
|
|
|
|
|
existing test-file that illustrates the bug or desired feature. |
1780
|
|
|
|
|
|
|
|
1781
|
|
|
|
|
|
|
=head1 SEE ALSO |
1782
|
|
|
|
|
|
|
|
1783
|
|
|
|
|
|
|
Information about CPAN::Testers: |
1784
|
|
|
|
|
|
|
|
1785
|
|
|
|
|
|
|
=over |
1786
|
|
|
|
|
|
|
|
1787
|
|
|
|
|
|
|
=item * |
1788
|
|
|
|
|
|
|
|
1789
|
|
|
|
|
|
|
L<CPAN::Testers> -- overview of CPAN Testers architecture stack |
1790
|
|
|
|
|
|
|
|
1791
|
|
|
|
|
|
|
=item * |
1792
|
|
|
|
|
|
|
|
1793
|
|
|
|
|
|
|
L<http://www.cpantesters.org> -- project home with all reports |
1794
|
|
|
|
|
|
|
|
1795
|
|
|
|
|
|
|
=item * |
1796
|
|
|
|
|
|
|
|
1797
|
|
|
|
|
|
|
L<http://wiki.cpantesters.org> -- documentation and wiki |
1798
|
|
|
|
|
|
|
|
1799
|
|
|
|
|
|
|
=back |
1800
|
|
|
|
|
|
|
|
1801
|
|
|
|
|
|
|
Additional Documentation: |
1802
|
|
|
|
|
|
|
|
1803
|
|
|
|
|
|
|
=over |
1804
|
|
|
|
|
|
|
|
1805
|
|
|
|
|
|
|
=item * |
1806
|
|
|
|
|
|
|
|
1807
|
|
|
|
|
|
|
L<CPAN::Reporter::Config> -- advanced configuration settings |
1808
|
|
|
|
|
|
|
|
1809
|
|
|
|
|
|
|
=item * |
1810
|
|
|
|
|
|
|
|
1811
|
|
|
|
|
|
|
L<CPAN::Reporter::FAQ> -- hints and tips |
1812
|
|
|
|
|
|
|
|
1813
|
|
|
|
|
|
|
=back |
1814
|
|
|
|
|
|
|
|
1815
|
|
|
|
|
|
|
=for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan |
1816
|
|
|
|
|
|
|
|
1817
|
|
|
|
|
|
|
=head1 SUPPORT |
1818
|
|
|
|
|
|
|
|
1819
|
|
|
|
|
|
|
=head2 Bugs / Feature Requests |
1820
|
|
|
|
|
|
|
|
1821
|
|
|
|
|
|
|
Please report any bugs or feature requests through the issue tracker |
1822
|
|
|
|
|
|
|
at L<https://github.com/cpan-testers/CPAN-Reporter/issues>. |
1823
|
|
|
|
|
|
|
You will be notified automatically of any progress on your issue. |
1824
|
|
|
|
|
|
|
|
1825
|
|
|
|
|
|
|
=head2 Source Code |
1826
|
|
|
|
|
|
|
|
1827
|
|
|
|
|
|
|
This is open source software. The code repository is available for |
1828
|
|
|
|
|
|
|
public review and contribution under the terms of the license. |
1829
|
|
|
|
|
|
|
|
1830
|
|
|
|
|
|
|
L<https://github.com/cpan-testers/CPAN-Reporter> |
1831
|
|
|
|
|
|
|
|
1832
|
|
|
|
|
|
|
git clone https://github.com/cpan-testers/CPAN-Reporter.git |
1833
|
|
|
|
|
|
|
|
1834
|
|
|
|
|
|
|
=head1 AUTHOR |
1835
|
|
|
|
|
|
|
|
1836
|
|
|
|
|
|
|
David Golden <dagolden@cpan.org> |
1837
|
|
|
|
|
|
|
|
1838
|
|
|
|
|
|
|
=head1 CONTRIBUTORS |
1839
|
|
|
|
|
|
|
|
1840
|
|
|
|
|
|
|
=for stopwords Alexandr Ciornii Breno G. de Oliveira Christian Walde Ed J Joel Maslak Kent Fredric Matthew Musgrove Patrice Clement Reini Urban Scott Wiersdorf Slaven Rezic |
1841
|
|
|
|
|
|
|
|
1842
|
|
|
|
|
|
|
=over 4 |
1843
|
|
|
|
|
|
|
|
1844
|
|
|
|
|
|
|
=item * |
1845
|
|
|
|
|
|
|
|
1846
|
|
|
|
|
|
|
Alexandr Ciornii <alexchorny@gmail.com> |
1847
|
|
|
|
|
|
|
|
1848
|
|
|
|
|
|
|
=item * |
1849
|
|
|
|
|
|
|
|
1850
|
|
|
|
|
|
|
Breno G. de Oliveira <garu@cpan.org> |
1851
|
|
|
|
|
|
|
|
1852
|
|
|
|
|
|
|
=item * |
1853
|
|
|
|
|
|
|
|
1854
|
|
|
|
|
|
|
Christian Walde <walde.christian@googlemail.com> |
1855
|
|
|
|
|
|
|
|
1856
|
|
|
|
|
|
|
=item * |
1857
|
|
|
|
|
|
|
|
1858
|
|
|
|
|
|
|
Ed J <mohawk2@users.noreply.github.com> |
1859
|
|
|
|
|
|
|
|
1860
|
|
|
|
|
|
|
=item * |
1861
|
|
|
|
|
|
|
|
1862
|
|
|
|
|
|
|
Joel Maslak <jmaslak@antelope.net> |
1863
|
|
|
|
|
|
|
|
1864
|
|
|
|
|
|
|
=item * |
1865
|
|
|
|
|
|
|
|
1866
|
|
|
|
|
|
|
Kent Fredric <kentfredric@gmail.com> |
1867
|
|
|
|
|
|
|
|
1868
|
|
|
|
|
|
|
=item * |
1869
|
|
|
|
|
|
|
|
1870
|
|
|
|
|
|
|
Matthew Musgrove <mr.muskrat@gmail.com> |
1871
|
|
|
|
|
|
|
|
1872
|
|
|
|
|
|
|
=item * |
1873
|
|
|
|
|
|
|
|
1874
|
|
|
|
|
|
|
Patrice Clement <monsieurp@gentoo.org> |
1875
|
|
|
|
|
|
|
|
1876
|
|
|
|
|
|
|
=item * |
1877
|
|
|
|
|
|
|
|
1878
|
|
|
|
|
|
|
Reini Urban <rurban@cpanel.net> |
1879
|
|
|
|
|
|
|
|
1880
|
|
|
|
|
|
|
=item * |
1881
|
|
|
|
|
|
|
|
1882
|
|
|
|
|
|
|
Scott Wiersdorf <scott@perlcode.org> |
1883
|
|
|
|
|
|
|
|
1884
|
|
|
|
|
|
|
=item * |
1885
|
|
|
|
|
|
|
|
1886
|
|
|
|
|
|
|
Slaven Rezic <slaven@rezic.de> |
1887
|
|
|
|
|
|
|
|
1888
|
|
|
|
|
|
|
=back |
1889
|
|
|
|
|
|
|
|
1890
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
1891
|
|
|
|
|
|
|
|
1892
|
|
|
|
|
|
|
This software is Copyright (c) 2006 by David Golden. |
1893
|
|
|
|
|
|
|
|
1894
|
|
|
|
|
|
|
This is free software, licensed under: |
1895
|
|
|
|
|
|
|
|
1896
|
|
|
|
|
|
|
The Apache License, Version 2.0, January 2004 |
1897
|
|
|
|
|
|
|
|
1898
|
|
|
|
|
|
|
=cut |
1899
|
|
|
|
|
|
|
|
1900
|
|
|
|
|
|
|
__END__ |
1901
|
|
|
|
|
|
|
|
1902
|
|
|
|
|
|
|
|
1903
|
|
|
|
|
|
|
# vim: ts=4 sts=4 sw=4 et: |
1904
|
|
|
|
|
|
|
|