line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
60
|
|
|
60
|
|
5306
|
use strict; |
|
60
|
|
|
|
|
105
|
|
|
60
|
|
|
|
|
1969
|
|
2
|
|
|
|
|
|
|
package CPAN::Reporter::Config; |
3
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
our $VERSION = '1.2018'; |
5
|
|
|
|
|
|
|
|
6
|
59
|
|
|
59
|
|
12588
|
use Config::Tiny 2.08 (); |
|
59
|
|
|
|
|
23133
|
|
|
59
|
|
|
|
|
890
|
|
7
|
59
|
|
|
59
|
|
384
|
use File::Glob (); |
|
59
|
|
|
|
|
101
|
|
|
59
|
|
|
|
|
909
|
|
8
|
57
|
|
|
57
|
|
304
|
use File::HomeDir 0.58 (); |
|
57
|
|
|
|
|
569
|
|
|
57
|
|
|
|
|
833
|
|
9
|
54
|
|
|
54
|
|
652
|
use File::Path qw/mkpath/; |
|
54
|
|
|
|
|
91
|
|
|
54
|
|
|
|
|
1761
|
|
10
|
53
|
|
|
53
|
|
981
|
use File::Spec 3.19 (); |
|
53
|
|
|
|
|
481
|
|
|
53
|
|
|
|
|
765
|
|
11
|
53
|
|
|
53
|
|
21687
|
use IPC::Cmd 0.76 (); |
|
53
|
|
|
|
|
1070222
|
|
|
53
|
|
|
|
|
997
|
|
12
|
44
|
|
|
44
|
|
290
|
use IO::File (); |
|
44
|
|
|
|
|
64
|
|
|
44
|
|
|
|
|
634
|
|
13
|
39
|
|
|
39
|
|
113
|
use CPAN 1.9301 (); # for printing warnings |
|
39
|
|
|
|
|
483
|
|
|
39
|
|
|
|
|
80485
|
|
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
#--------------------------------------------------------------------------# |
16
|
|
|
|
|
|
|
# Back-compatibility checks -- just once per load |
17
|
|
|
|
|
|
|
#--------------------------------------------------------------------------# |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
# 0.28_51 changed Mac OS X config file location -- if old directory is found, |
20
|
|
|
|
|
|
|
# move it to the new location |
21
|
|
|
|
|
|
|
if ( $^O eq 'darwin' ) { |
22
|
|
|
|
|
|
|
my $old = File::Spec->catdir(File::HomeDir->my_documents,".cpanreporter"); |
23
|
|
|
|
|
|
|
my $new = File::Spec->catdir(File::HomeDir->my_home,".cpanreporter"); |
24
|
|
|
|
|
|
|
if ( ( -d $old ) && (! -d $new ) ) { |
25
|
|
|
|
|
|
|
$CPAN::Frontend->mywarn( << "HERE"); |
26
|
|
|
|
|
|
|
CPAN::Reporter: since CPAN::Reporter 0.28_51, the Mac OSX config directory |
27
|
|
|
|
|
|
|
has changed. |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
Old: $old |
30
|
|
|
|
|
|
|
New: $new |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
Your existing configuration file will be moved automatically. |
33
|
|
|
|
|
|
|
HERE |
34
|
|
|
|
|
|
|
mkpath($new); |
35
|
|
|
|
|
|
|
my $OLD_CONFIG = IO::File->new( |
36
|
|
|
|
|
|
|
File::Spec->catfile($old, "config.ini"), "<" |
37
|
|
|
|
|
|
|
) or die $!; |
38
|
|
|
|
|
|
|
my $NEW_CONFIG = IO::File->new( |
39
|
|
|
|
|
|
|
File::Spec->catfile($new, "config.ini"), ">" |
40
|
|
|
|
|
|
|
) or die $!; |
41
|
|
|
|
|
|
|
$NEW_CONFIG->print( do { local $/; <$OLD_CONFIG> } ); |
42
|
|
|
|
|
|
|
$OLD_CONFIG->close; |
43
|
|
|
|
|
|
|
$NEW_CONFIG->close; |
44
|
|
|
|
|
|
|
unlink File::Spec->catfile($old, "config.ini") or die $!; |
45
|
|
|
|
|
|
|
rmdir($old) or die $!; |
46
|
|
|
|
|
|
|
} |
47
|
|
|
|
|
|
|
} |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
#--------------------------------------------------------------------------# |
50
|
|
|
|
|
|
|
# Public |
51
|
|
|
|
|
|
|
#--------------------------------------------------------------------------# |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
sub _configure { |
54
|
2
|
|
|
2
|
|
7
|
my $config_dir = _get_config_dir(); |
55
|
2
|
|
|
|
|
6
|
my $config_file = _get_config_file(); |
56
|
|
|
|
|
|
|
|
57
|
2
|
50
|
|
|
|
30
|
mkpath $config_dir if ! -d $config_dir; |
58
|
2
|
50
|
|
|
|
21
|
if ( ! -d $config_dir ) { |
59
|
0
|
|
|
|
|
0
|
$CPAN::Frontend->myprint( |
60
|
|
|
|
|
|
|
"\nCPAN::Reporter: couldn't create configuration directory '$config_dir': $!" |
61
|
|
|
|
|
|
|
); |
62
|
0
|
|
|
|
|
0
|
return; |
63
|
|
|
|
|
|
|
} |
64
|
|
|
|
|
|
|
|
65
|
2
|
|
|
|
|
4
|
my $config; |
66
|
|
|
|
|
|
|
my $existing_options; |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
# explain grade:action pairs |
69
|
2
|
|
|
|
|
5
|
$CPAN::Frontend->myprint( _grade_action_prompt() ); |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
# read or create |
72
|
2
|
100
|
|
|
|
68
|
if ( -f $config_file ) { |
73
|
1
|
|
|
|
|
7
|
$CPAN::Frontend->myprint( |
74
|
|
|
|
|
|
|
"\nCPAN::Reporter: found your CPAN::Reporter config file at:\n$config_file\n" |
75
|
|
|
|
|
|
|
); |
76
|
1
|
|
|
|
|
12
|
$config = _open_config_file(); |
77
|
|
|
|
|
|
|
# if we can't read it, bail out |
78
|
1
|
50
|
|
|
|
6
|
if ( ! $config ) { |
79
|
0
|
|
|
|
|
0
|
$CPAN::Frontend->mywarn("\n |
80
|
|
|
|
|
|
|
CPAN::Reporter: configuration will not be changed\n"); |
81
|
0
|
|
|
|
|
0
|
return; |
82
|
|
|
|
|
|
|
} |
83
|
|
|
|
|
|
|
# clone what's in the config file |
84
|
1
|
50
|
|
|
|
5
|
$existing_options = { %{$config->{_}} } if $config; |
|
1
|
|
|
|
|
7
|
|
85
|
1
|
|
|
|
|
5
|
$CPAN::Frontend->myprint( |
86
|
|
|
|
|
|
|
"\nCPAN::Reporter: Updating your CPAN::Reporter configuration settings:\n" |
87
|
|
|
|
|
|
|
); |
88
|
|
|
|
|
|
|
} |
89
|
|
|
|
|
|
|
else { |
90
|
1
|
|
|
|
|
3
|
$CPAN::Frontend->myprint( |
91
|
|
|
|
|
|
|
"\nCPAN::Reporter: no config file found; creating a new one.\n" |
92
|
|
|
|
|
|
|
); |
93
|
1
|
|
|
|
|
12
|
$config = Config::Tiny->new(); |
94
|
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
|
96
|
2
|
|
|
|
|
23
|
my %spec = _config_spec(); |
97
|
|
|
|
|
|
|
|
98
|
2
|
|
|
|
|
7
|
for my $k ( _config_order() ) { |
99
|
8
|
|
|
|
|
10
|
my $option_data = $spec{$k}; |
100
|
8
|
|
|
|
|
38
|
$CPAN::Frontend->myprint( "\n" . $option_data->{info}. "\n"); |
101
|
|
|
|
|
|
|
# options with defaults are mandatory |
102
|
8
|
50
|
|
|
|
91
|
if ( defined $option_data->{default} ) { |
103
|
|
|
|
|
|
|
# if we have a default, always show as a sane recommendation |
104
|
8
|
100
|
|
|
|
18
|
if ( length $option_data->{default} ) { |
105
|
6
|
|
|
|
|
20
|
$CPAN::Frontend->myprint( |
106
|
|
|
|
|
|
|
"(Recommended: '$option_data->{default}')\n\n" |
107
|
|
|
|
|
|
|
); |
108
|
|
|
|
|
|
|
} |
109
|
|
|
|
|
|
|
# repeat until validated |
110
|
|
|
|
|
|
|
PROMPT: |
111
|
8
|
|
66
|
|
|
78
|
while ( defined ( |
112
|
|
|
|
|
|
|
my $answer = CPAN::Shell::colorable_makemaker_prompt( |
113
|
|
|
|
|
|
|
"$k?", |
114
|
|
|
|
|
|
|
$existing_options->{$k} || $option_data->{default} |
115
|
|
|
|
|
|
|
) |
116
|
|
|
|
|
|
|
)) { |
117
|
8
|
50
|
66
|
|
|
299
|
if ( ! $option_data->{validate} || |
118
|
|
|
|
|
|
|
$option_data->{validate}->($k, $answer, $config->{_}) |
119
|
|
|
|
|
|
|
) { |
120
|
8
|
|
|
|
|
19
|
$config->{_}{$k} = $answer; |
121
|
8
|
|
|
|
|
16
|
last PROMPT; |
122
|
|
|
|
|
|
|
} |
123
|
|
|
|
|
|
|
} |
124
|
|
|
|
|
|
|
} |
125
|
|
|
|
|
|
|
else { |
126
|
|
|
|
|
|
|
# only initialize options without default if |
127
|
|
|
|
|
|
|
# answer matches non white space and validates, |
128
|
|
|
|
|
|
|
# otherwise reset it |
129
|
|
|
|
|
|
|
my $answer = CPAN::Shell::colorable_makemaker_prompt( |
130
|
|
|
|
|
|
|
"$k?", |
131
|
0
|
|
0
|
|
|
0
|
$existing_options->{$k} || q{} |
132
|
|
|
|
|
|
|
); |
133
|
0
|
0
|
|
|
|
0
|
if ( $answer =~ /\S/ ) { |
134
|
0
|
|
|
|
|
0
|
$config->{_}{$k} = $answer; |
135
|
|
|
|
|
|
|
} |
136
|
|
|
|
|
|
|
else { |
137
|
0
|
|
|
|
|
0
|
delete $config->{_}{$k}; |
138
|
|
|
|
|
|
|
} |
139
|
|
|
|
|
|
|
} |
140
|
|
|
|
|
|
|
# delete existing as we proceed so we know what's left |
141
|
8
|
|
|
|
|
20
|
delete $existing_options->{$k}; |
142
|
|
|
|
|
|
|
} |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
# initialize remaining existing options |
145
|
|
|
|
|
|
|
$CPAN::Frontend->myprint( |
146
|
2
|
100
|
|
|
|
12
|
"\nYour CPAN::Reporter config file also contains these advanced " . |
147
|
|
|
|
|
|
|
"options:\n\n") if keys %$existing_options; |
148
|
2
|
|
|
|
|
22
|
for my $k ( keys %$existing_options ) { |
149
|
|
|
|
|
|
|
$config->{_}{$k} = CPAN::Shell::colorable_makemaker_prompt( |
150
|
2
|
|
|
|
|
47
|
"$k?", $existing_options->{$k} |
151
|
|
|
|
|
|
|
); |
152
|
|
|
|
|
|
|
} |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
$CPAN::Frontend->myprint( |
155
|
2
|
|
|
|
|
42
|
"\nCPAN::Reporter: writing config file to '$config_file'.\n" |
156
|
|
|
|
|
|
|
); |
157
|
2
|
50
|
|
|
|
28
|
if ( $config->write( $config_file ) ) { |
158
|
2
|
|
|
|
|
297
|
return $config->{_}; |
159
|
|
|
|
|
|
|
} |
160
|
|
|
|
|
|
|
else { |
161
|
0
|
|
|
|
|
0
|
$CPAN::Frontend->mywarn( "\nCPAN::Reporter: error writing config file to '$config_file':\n" |
162
|
|
|
|
|
|
|
. Config::Tiny->errstr(). "\n"); |
163
|
0
|
|
|
|
|
0
|
return; |
164
|
|
|
|
|
|
|
} |
165
|
|
|
|
|
|
|
} |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
#--------------------------------------------------------------------------# |
168
|
|
|
|
|
|
|
# Private |
169
|
|
|
|
|
|
|
#--------------------------------------------------------------------------# |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
#--------------------------------------------------------------------------# |
172
|
|
|
|
|
|
|
# _config_order -- determines order of interactive config. Only items |
173
|
|
|
|
|
|
|
# in interactive config will be written to a starter config file |
174
|
|
|
|
|
|
|
#--------------------------------------------------------------------------# |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
sub _config_order { |
177
|
2
|
|
|
2
|
|
9
|
return qw( |
178
|
|
|
|
|
|
|
email_from |
179
|
|
|
|
|
|
|
edit_report |
180
|
|
|
|
|
|
|
send_report |
181
|
|
|
|
|
|
|
transport |
182
|
|
|
|
|
|
|
); |
183
|
|
|
|
|
|
|
} |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
#--------------------------------------------------------------------------# |
186
|
|
|
|
|
|
|
# _config_spec -- returns configuration options information |
187
|
|
|
|
|
|
|
# |
188
|
|
|
|
|
|
|
# Keys include |
189
|
|
|
|
|
|
|
# default -- recommended value, used in prompts and as a fallback |
190
|
|
|
|
|
|
|
# if an options is not set; mandatory if defined |
191
|
|
|
|
|
|
|
# prompt -- short prompt for EU::MM prompting |
192
|
|
|
|
|
|
|
# info -- long description shown before prompting |
193
|
|
|
|
|
|
|
# validate -- CODE ref; return normalized option or undef if invalid |
194
|
|
|
|
|
|
|
#--------------------------------------------------------------------------# |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
my %option_specs = ( |
197
|
|
|
|
|
|
|
email_from => { |
198
|
|
|
|
|
|
|
default => '', |
199
|
|
|
|
|
|
|
prompt => 'What email address will be used to reference your reports?', |
200
|
|
|
|
|
|
|
info => <<'HERE', |
201
|
|
|
|
|
|
|
CPAN::Reporter requires a valid email address to identify senders |
202
|
|
|
|
|
|
|
in the body of a test report. Please use a standard email format |
203
|
|
|
|
|
|
|
like: "John Doe" |
204
|
|
|
|
|
|
|
HERE |
205
|
|
|
|
|
|
|
}, |
206
|
|
|
|
|
|
|
smtp_server => { |
207
|
|
|
|
|
|
|
default => undef, # (deprecated) |
208
|
|
|
|
|
|
|
prompt => "[DEPRECATED] It's safe to remove this from your config file.", |
209
|
|
|
|
|
|
|
}, |
210
|
|
|
|
|
|
|
edit_report => { |
211
|
|
|
|
|
|
|
default => 'default:ask/no pass/na:no', |
212
|
|
|
|
|
|
|
prompt => "Do you want to review or edit the test report?", |
213
|
|
|
|
|
|
|
validate => \&_validate_grade_action_pair, |
214
|
|
|
|
|
|
|
info => <<'HERE', |
215
|
|
|
|
|
|
|
Before test reports are sent, you may want to review or edit the test |
216
|
|
|
|
|
|
|
report and add additional comments about the result or about your system |
217
|
|
|
|
|
|
|
or Perl configuration. By default, CPAN::Reporter will ask after |
218
|
|
|
|
|
|
|
each report is generated whether or not you would like to edit the |
219
|
|
|
|
|
|
|
report. This option takes "grade:action" pairs. |
220
|
|
|
|
|
|
|
HERE |
221
|
|
|
|
|
|
|
}, |
222
|
|
|
|
|
|
|
send_report => { |
223
|
|
|
|
|
|
|
default => 'default:ask/yes pass/na:yes', |
224
|
|
|
|
|
|
|
prompt => "Do you want to send the report?", |
225
|
|
|
|
|
|
|
validate => \&_validate_grade_action_pair, |
226
|
|
|
|
|
|
|
info => <<'HERE', |
227
|
|
|
|
|
|
|
By default, CPAN::Reporter will prompt you for confirmation that |
228
|
|
|
|
|
|
|
the test report should be sent before actually doing it. This |
229
|
|
|
|
|
|
|
gives the opportunity to skip sending particular reports if |
230
|
|
|
|
|
|
|
you need to (e.g. if you caused the failure). This option takes |
231
|
|
|
|
|
|
|
"grade:action" pairs. |
232
|
|
|
|
|
|
|
HERE |
233
|
|
|
|
|
|
|
}, |
234
|
|
|
|
|
|
|
transport => { |
235
|
|
|
|
|
|
|
default => 'Metabase uri https://metabase.cpantesters.org/api/v1/ id_file metabase_id.json', |
236
|
|
|
|
|
|
|
prompt => 'Which transport system will be used to transmit the reports?', |
237
|
|
|
|
|
|
|
validate => \&_validate_transport, |
238
|
|
|
|
|
|
|
info => <<'HERE', |
239
|
|
|
|
|
|
|
CPAN::Reporter sends your reports over HTTPS using Metabase. This option lets |
240
|
|
|
|
|
|
|
you set a different uri, transport mechanism and metabase profile path. If you |
241
|
|
|
|
|
|
|
are receiving HTTPS errors, you may change the uri to use plain HTTP, though |
242
|
|
|
|
|
|
|
this is not recommended. Unless you know what you're doing, just accept |
243
|
|
|
|
|
|
|
the default value. |
244
|
|
|
|
|
|
|
HERE |
245
|
|
|
|
|
|
|
}, |
246
|
|
|
|
|
|
|
send_duplicates => { |
247
|
|
|
|
|
|
|
default => 'default:no', |
248
|
|
|
|
|
|
|
prompt => "This report is identical to a previous one. Send it anyway?", |
249
|
|
|
|
|
|
|
validate => \&_validate_grade_action_pair, |
250
|
|
|
|
|
|
|
info => <<'HERE', |
251
|
|
|
|
|
|
|
CPAN::Reporter records tests grades for each distribution, version and |
252
|
|
|
|
|
|
|
platform. By default, duplicates of previous results will not be sent at |
253
|
|
|
|
|
|
|
all, regardless of the value of the "send_report" option. This option takes |
254
|
|
|
|
|
|
|
"grade:action" pairs. |
255
|
|
|
|
|
|
|
HERE |
256
|
|
|
|
|
|
|
}, |
257
|
|
|
|
|
|
|
send_PL_report => { |
258
|
|
|
|
|
|
|
prompt => "Do you want to send the PL report?", |
259
|
|
|
|
|
|
|
default => undef, |
260
|
|
|
|
|
|
|
validate => \&_validate_grade_action_pair, |
261
|
|
|
|
|
|
|
}, |
262
|
|
|
|
|
|
|
send_make_report => { |
263
|
|
|
|
|
|
|
prompt => "Do you want to send the make/Build report?", |
264
|
|
|
|
|
|
|
default => undef, |
265
|
|
|
|
|
|
|
validate => \&_validate_grade_action_pair, |
266
|
|
|
|
|
|
|
}, |
267
|
|
|
|
|
|
|
send_test_report => { |
268
|
|
|
|
|
|
|
prompt => "Do you want to send the test report?", |
269
|
|
|
|
|
|
|
default => undef, |
270
|
|
|
|
|
|
|
validate => \&_validate_grade_action_pair, |
271
|
|
|
|
|
|
|
}, |
272
|
|
|
|
|
|
|
send_skipfile => { |
273
|
|
|
|
|
|
|
prompt => "What file has patterns for things that shouldn't be reported?", |
274
|
|
|
|
|
|
|
default => undef, |
275
|
|
|
|
|
|
|
validate => \&_validate_skipfile, |
276
|
|
|
|
|
|
|
}, |
277
|
|
|
|
|
|
|
cc_skipfile => { |
278
|
|
|
|
|
|
|
prompt => "What file has patterns for things that shouldn't CC to authors?", |
279
|
|
|
|
|
|
|
default => undef, |
280
|
|
|
|
|
|
|
validate => \&_validate_skipfile, |
281
|
|
|
|
|
|
|
}, |
282
|
|
|
|
|
|
|
command_timeout => { |
283
|
|
|
|
|
|
|
prompt => "If no timeout is set by CPAN, halt system commands after how many seconds?", |
284
|
|
|
|
|
|
|
default => undef, |
285
|
|
|
|
|
|
|
validate => \&_validate_seconds, |
286
|
|
|
|
|
|
|
}, |
287
|
|
|
|
|
|
|
email_to => { |
288
|
|
|
|
|
|
|
default => undef, |
289
|
|
|
|
|
|
|
}, |
290
|
|
|
|
|
|
|
editor => { |
291
|
|
|
|
|
|
|
default => undef, |
292
|
|
|
|
|
|
|
}, |
293
|
|
|
|
|
|
|
debug => { |
294
|
|
|
|
|
|
|
default => undef, |
295
|
|
|
|
|
|
|
}, |
296
|
|
|
|
|
|
|
retry_submission => { |
297
|
|
|
|
|
|
|
default => undef, |
298
|
|
|
|
|
|
|
}, |
299
|
|
|
|
|
|
|
'_store_problems_in_dir' => { #experimental |
300
|
|
|
|
|
|
|
default => undef, |
301
|
|
|
|
|
|
|
}, |
302
|
|
|
|
|
|
|
'_problem_log' => { #experimental |
303
|
|
|
|
|
|
|
default => undef, |
304
|
|
|
|
|
|
|
}, |
305
|
|
|
|
|
|
|
); |
306
|
|
|
|
|
|
|
|
307
|
635
|
|
|
635
|
|
8366
|
sub _config_spec { return %option_specs } |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
#--------------------------------------------------------------------------# |
310
|
|
|
|
|
|
|
# _generate_profile |
311
|
|
|
|
|
|
|
# |
312
|
|
|
|
|
|
|
# Run 'metabase-profile' in the .cpanreporter directory |
313
|
|
|
|
|
|
|
#--------------------------------------------------------------------------# |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
sub _generate_profile { |
316
|
0
|
|
|
0
|
|
0
|
my ($id_file, $config) = @_; |
317
|
|
|
|
|
|
|
|
318
|
0
|
|
|
|
|
0
|
my $cmd = IPC::Cmd::can_run('metabase-profile'); |
319
|
0
|
0
|
|
|
|
0
|
return unless $cmd; |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
# XXX this is an evil assumption about email addresses, but |
322
|
|
|
|
|
|
|
# might do for simple cases that users might actually provide |
323
|
|
|
|
|
|
|
|
324
|
0
|
|
|
|
|
0
|
my @opts = ("--output" => $id_file); |
325
|
0
|
|
|
|
|
0
|
my $email = $config->{email_from}; |
326
|
|
|
|
|
|
|
|
327
|
0
|
0
|
|
|
|
0
|
if ($email =~ /\A(.+)\s+<([^>]+)>\z/ ) { |
328
|
0
|
|
|
|
|
0
|
push @opts, "--email" => $2; |
329
|
0
|
|
|
|
|
0
|
my $name = $1; |
330
|
0
|
|
|
|
|
0
|
$name =~ s/\A["'](.*)["']\z/$1/; |
331
|
0
|
0
|
|
|
|
0
|
push ( @opts, "--name" => $1) |
332
|
|
|
|
|
|
|
if length $name; |
333
|
|
|
|
|
|
|
} |
334
|
|
|
|
|
|
|
else { |
335
|
0
|
|
|
|
|
0
|
push @opts, "--email" => $email; |
336
|
|
|
|
|
|
|
} |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
# XXX profile 'secret' is really just a generated API key, so we |
339
|
|
|
|
|
|
|
# can create something fairly random for the user and use that |
340
|
0
|
|
|
|
|
0
|
push @opts, "--secret" => sprintf("%08x", rand(2**31)); |
341
|
|
|
|
|
|
|
|
342
|
0
|
|
|
|
|
0
|
return scalar IPC::Cmd::run( |
343
|
|
|
|
|
|
|
command => [ $cmd, @opts ], |
344
|
|
|
|
|
|
|
verbose => 1, |
345
|
|
|
|
|
|
|
); |
346
|
|
|
|
|
|
|
} |
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
#--------------------------------------------------------------------------# |
349
|
|
|
|
|
|
|
# _get_config_dir |
350
|
|
|
|
|
|
|
#--------------------------------------------------------------------------# |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
sub _get_config_dir { |
353
|
1371
|
100
|
66
|
1371
|
|
6684
|
if ( defined $ENV{PERL_CPAN_REPORTER_DIR} && |
354
|
|
|
|
|
|
|
length $ENV{PERL_CPAN_REPORTER_DIR} |
355
|
|
|
|
|
|
|
) { |
356
|
3
|
|
|
|
|
16
|
return $ENV{PERL_CPAN_REPORTER_DIR}; |
357
|
|
|
|
|
|
|
} |
358
|
|
|
|
|
|
|
|
359
|
1368
|
|
|
|
|
7045
|
my $conf_dir = File::Spec->catdir(File::HomeDir->my_home, ".cpanreporter"); |
360
|
|
|
|
|
|
|
|
361
|
1368
|
50
|
|
|
|
13271
|
if ($^O eq 'MSWin32') { |
362
|
0
|
|
|
|
|
0
|
my $alt_dir = File::Spec->catdir(File::HomeDir->my_documents, ".cpanreporter"); |
363
|
0
|
0
|
0
|
|
|
0
|
$conf_dir = $alt_dir if -d $alt_dir && ! -d $conf_dir; |
364
|
|
|
|
|
|
|
} |
365
|
|
|
|
|
|
|
|
366
|
1368
|
|
|
|
|
10972
|
return $conf_dir; |
367
|
|
|
|
|
|
|
} |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
#--------------------------------------------------------------------------# |
370
|
|
|
|
|
|
|
# _get_config_file |
371
|
|
|
|
|
|
|
#--------------------------------------------------------------------------# |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
sub _get_config_file { |
374
|
498
|
100
|
66
|
498
|
|
2675
|
if ( defined $ENV{PERL_CPAN_REPORTER_CONFIG} && |
375
|
|
|
|
|
|
|
length $ENV{PERL_CPAN_REPORTER_CONFIG} |
376
|
|
|
|
|
|
|
) { |
377
|
2
|
|
|
|
|
7
|
return $ENV{PERL_CPAN_REPORTER_CONFIG}; |
378
|
|
|
|
|
|
|
} |
379
|
|
|
|
|
|
|
else { |
380
|
496
|
|
|
|
|
1304
|
return File::Spec->catdir( _get_config_dir, "config.ini" ); |
381
|
|
|
|
|
|
|
} |
382
|
|
|
|
|
|
|
} |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
#--------------------------------------------------------------------------# |
385
|
|
|
|
|
|
|
# _get_config_options |
386
|
|
|
|
|
|
|
#--------------------------------------------------------------------------# |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
sub _get_config_options { |
389
|
305
|
|
|
305
|
|
29900
|
my $config = shift; |
390
|
|
|
|
|
|
|
# extract and return valid options, with fallback to defaults |
391
|
305
|
|
|
|
|
990
|
my %spec = CPAN::Reporter::Config::_config_spec(); |
392
|
305
|
|
|
|
|
919
|
my %active; |
393
|
305
|
|
|
|
|
1311
|
OPTION: for my $option ( keys %spec ) { |
394
|
5490
|
100
|
|
|
|
6404
|
if ( exists $config->{_}{$option} ) { |
395
|
1576
|
|
|
|
|
1844
|
my $val = $config->{_}{$option}; |
396
|
1576
|
100
|
100
|
|
|
5494
|
if ( $spec{$option}{validate} && |
397
|
|
|
|
|
|
|
! $spec{$option}{validate}->($option, $val) |
398
|
|
|
|
|
|
|
) { |
399
|
5
|
|
|
|
|
38
|
$CPAN::Frontend->mywarn( "\nCPAN::Reporter: invalid option '$val' in '$option'. Using default instead.\n\n" ); |
400
|
5
|
|
|
|
|
85
|
$active{$option} = $spec{$option}{default}; |
401
|
5
|
|
|
|
|
13
|
next OPTION; |
402
|
|
|
|
|
|
|
} |
403
|
1571
|
|
|
|
|
3286
|
$active{$option} = $val; |
404
|
|
|
|
|
|
|
} |
405
|
|
|
|
|
|
|
else { |
406
|
|
|
|
|
|
|
$active{$option} = $spec{$option}{default} |
407
|
3914
|
100
|
|
|
|
7786
|
if defined $spec{$option}{default}; |
408
|
|
|
|
|
|
|
} |
409
|
|
|
|
|
|
|
} |
410
|
305
|
|
|
|
|
1609
|
return \%active; |
411
|
|
|
|
|
|
|
} |
412
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
#--------------------------------------------------------------------------# |
415
|
|
|
|
|
|
|
# _grade_action_prompt -- describes grade action pairs |
416
|
|
|
|
|
|
|
#--------------------------------------------------------------------------# |
417
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
sub _grade_action_prompt { |
419
|
2
|
|
|
2
|
|
14
|
return << 'HERE'; |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
Some of the following configuration options require one or more "grade:action" |
422
|
|
|
|
|
|
|
pairs that determine what grade-specific action to take for that option. |
423
|
|
|
|
|
|
|
These pairs should be space-separated and are processed left-to-right. See |
424
|
|
|
|
|
|
|
CPAN::Reporter documentation for more details. |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
GRADE : ACTION ======> EXAMPLES |
427
|
|
|
|
|
|
|
------- ------- -------- |
428
|
|
|
|
|
|
|
pass yes default:no |
429
|
|
|
|
|
|
|
fail no default:yes pass:no |
430
|
|
|
|
|
|
|
unknown ask/no default:ask/no pass:yes fail:no |
431
|
|
|
|
|
|
|
na ask/yes |
432
|
|
|
|
|
|
|
default |
433
|
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
HERE |
435
|
|
|
|
|
|
|
} |
436
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
#--------------------------------------------------------------------------# |
438
|
|
|
|
|
|
|
# _is_valid_action |
439
|
|
|
|
|
|
|
#--------------------------------------------------------------------------# |
440
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
my @valid_actions = qw{ yes no ask/yes ask/no ask }; |
442
|
|
|
|
|
|
|
sub _is_valid_action { |
443
|
1449
|
|
|
1449
|
|
1464
|
my $action = shift; |
444
|
1449
|
|
|
|
|
1623
|
return grep { $action eq $_ } @valid_actions; |
|
7245
|
|
|
|
|
8755
|
|
445
|
|
|
|
|
|
|
} |
446
|
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
#--------------------------------------------------------------------------# |
448
|
|
|
|
|
|
|
# _is_valid_grade |
449
|
|
|
|
|
|
|
#--------------------------------------------------------------------------# |
450
|
|
|
|
|
|
|
|
451
|
|
|
|
|
|
|
my @valid_grades = qw{ pass fail unknown na default }; |
452
|
|
|
|
|
|
|
sub _is_valid_grade { |
453
|
765
|
|
|
765
|
|
666
|
my $grade = shift; |
454
|
765
|
|
|
|
|
695
|
return grep { $grade eq $_ } @valid_grades; |
|
3825
|
|
|
|
|
4817
|
|
455
|
|
|
|
|
|
|
} |
456
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
#--------------------------------------------------------------------------# |
459
|
|
|
|
|
|
|
# _normalize_id_file |
460
|
|
|
|
|
|
|
#--------------------------------------------------------------------------# |
461
|
|
|
|
|
|
|
|
462
|
|
|
|
|
|
|
sub _normalize_id_file { |
463
|
422
|
|
|
422
|
|
2299
|
my ($id_file) = @_; |
464
|
|
|
|
|
|
|
|
465
|
|
|
|
|
|
|
# Windows does not use ~ to signify a home directory |
466
|
422
|
50
|
33
|
|
|
2374
|
if ( $^O eq 'MSWin32' && $id_file =~ m{^~/(.*)} ) { |
|
|
100
|
|
|
|
|
|
467
|
0
|
|
|
|
|
0
|
$id_file = File::Spec->catdir(File::HomeDir->my_home, $1); |
468
|
|
|
|
|
|
|
} |
469
|
|
|
|
|
|
|
elsif ( $id_file =~ /~/ ) { |
470
|
1
|
|
|
|
|
60
|
$id_file = File::Spec->canonpath(File::Glob::bsd_glob( $id_file )); |
471
|
|
|
|
|
|
|
} |
472
|
422
|
100
|
|
|
|
3832
|
unless ( File::Spec->file_name_is_absolute( $id_file ) ) { |
473
|
419
|
|
|
|
|
790
|
$id_file = File::Spec->catfile( |
474
|
|
|
|
|
|
|
CPAN::Reporter::Config::_get_config_dir(), $id_file |
475
|
|
|
|
|
|
|
); |
476
|
|
|
|
|
|
|
} |
477
|
422
|
|
|
|
|
1222
|
return $id_file; |
478
|
|
|
|
|
|
|
} |
479
|
|
|
|
|
|
|
|
480
|
|
|
|
|
|
|
#--------------------------------------------------------------------------# |
481
|
|
|
|
|
|
|
# _open_config_file |
482
|
|
|
|
|
|
|
#--------------------------------------------------------------------------# |
483
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
sub _open_config_file { |
485
|
305
|
|
|
305
|
|
2760
|
my $config_file = _get_config_file(); |
486
|
305
|
100
|
|
|
|
3780
|
my $config = Config::Tiny->read( $config_file ) |
487
|
|
|
|
|
|
|
or $CPAN::Frontend->mywarn("CPAN::Reporter: couldn't read configuration file " . |
488
|
|
|
|
|
|
|
"'$config_file': \n" . Config::Tiny->errstr() . "\n"); |
489
|
305
|
|
|
|
|
51367
|
return $config; |
490
|
|
|
|
|
|
|
} |
491
|
|
|
|
|
|
|
|
492
|
|
|
|
|
|
|
#--------------------------------------------------------------------------# |
493
|
|
|
|
|
|
|
# _validate |
494
|
|
|
|
|
|
|
# |
495
|
|
|
|
|
|
|
# anything is OK if there is no validation subroutine |
496
|
|
|
|
|
|
|
#--------------------------------------------------------------------------# |
497
|
|
|
|
|
|
|
|
498
|
|
|
|
|
|
|
sub _validate { |
499
|
8
|
|
|
8
|
|
2710
|
my ($name, $value) = @_; |
500
|
8
|
50
|
|
|
|
22
|
return 1 if ! exists $option_specs{$name}{validate}; |
501
|
8
|
|
|
|
|
12
|
return $option_specs{$name}{validate}->($name, $value); |
502
|
|
|
|
|
|
|
} |
503
|
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
#--------------------------------------------------------------------------# |
505
|
|
|
|
|
|
|
# _validate_grade_action |
506
|
|
|
|
|
|
|
# returns hash of grade => action |
507
|
|
|
|
|
|
|
# returns undef |
508
|
|
|
|
|
|
|
#--------------------------------------------------------------------------# |
509
|
|
|
|
|
|
|
|
510
|
|
|
|
|
|
|
sub _validate_grade_action_pair { |
511
|
973
|
|
|
973
|
|
22573
|
my ($name, $option) = @_; |
512
|
973
|
|
100
|
|
|
1611
|
$option ||= "no"; |
513
|
|
|
|
|
|
|
|
514
|
973
|
|
|
|
|
902
|
my %ga_map; # grade => action |
515
|
|
|
|
|
|
|
|
516
|
973
|
|
|
|
|
2440
|
PAIR: for my $grade_action ( split q{ }, $option ) { |
517
|
1448
|
|
|
|
|
1129
|
my ($grade_list,$action); |
518
|
|
|
|
|
|
|
|
519
|
1448
|
100
|
|
|
|
4475
|
if ( $grade_action =~ m{.:.} ) { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
520
|
|
|
|
|
|
|
# parse pair for later check |
521
|
632
|
|
|
|
|
2047
|
($grade_list, $action) = $grade_action =~ m{\A([^:]+):(.+)\z}; |
522
|
|
|
|
|
|
|
} |
523
|
|
|
|
|
|
|
elsif ( _is_valid_action($grade_action) ) { |
524
|
|
|
|
|
|
|
# action by itself |
525
|
813
|
|
|
|
|
1941
|
$ga_map{default} = $grade_action; |
526
|
813
|
|
|
|
|
1599
|
next PAIR; |
527
|
|
|
|
|
|
|
} |
528
|
|
|
|
|
|
|
elsif ( _is_valid_grade($grade_action) ) { |
529
|
|
|
|
|
|
|
# grade by itself |
530
|
1
|
|
|
|
|
2
|
$ga_map{$grade_action} = "yes"; |
531
|
1
|
|
|
|
|
3
|
next PAIR; |
532
|
|
|
|
|
|
|
} |
533
|
|
|
|
|
|
|
elsif( $grade_action =~ m{./.} ) { |
534
|
|
|
|
|
|
|
# gradelist by itself, so setup for later check |
535
|
1
|
|
|
|
|
2
|
$grade_list = $grade_action; |
536
|
1
|
|
|
|
|
14
|
$action = "yes"; |
537
|
|
|
|
|
|
|
} |
538
|
|
|
|
|
|
|
else { |
539
|
|
|
|
|
|
|
# something weird, so warn and skip |
540
|
1
|
|
|
|
|
10
|
$CPAN::Frontend->mywarn( |
541
|
|
|
|
|
|
|
"\nCPAN::Reporter: ignoring invalid grade:action '$grade_action' for '$name'.\n\n" |
542
|
|
|
|
|
|
|
); |
543
|
1
|
|
|
|
|
47
|
next PAIR; |
544
|
|
|
|
|
|
|
} |
545
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
# check gradelist |
547
|
633
|
|
|
|
|
1166
|
my %grades = map { ($_,1) } split( "/", $grade_list); |
|
762
|
|
|
|
|
1874
|
|
548
|
633
|
|
|
|
|
1107
|
for my $g ( keys %grades ) { |
549
|
762
|
100
|
|
|
|
967
|
if ( ! _is_valid_grade($g) ) { |
550
|
1
|
|
|
|
|
17
|
$CPAN::Frontend->mywarn( |
551
|
|
|
|
|
|
|
"\nCPAN::Reporter: ignoring invalid grade '$g' in '$grade_action' for '$name'.\n\n" |
552
|
|
|
|
|
|
|
); |
553
|
1
|
|
|
|
|
41
|
delete $grades{$g}; |
554
|
|
|
|
|
|
|
} |
555
|
|
|
|
|
|
|
} |
556
|
|
|
|
|
|
|
|
557
|
|
|
|
|
|
|
# check action |
558
|
633
|
100
|
|
|
|
860
|
if ( ! _is_valid_action($action) ) { |
559
|
2
|
|
|
|
|
16
|
$CPAN::Frontend->mywarn( |
560
|
|
|
|
|
|
|
"\nCPAN::Reporter: ignoring invalid action '$action' in '$grade_action' for '$name'.\n\n" |
561
|
|
|
|
|
|
|
); |
562
|
2
|
|
|
|
|
38
|
next PAIR; |
563
|
|
|
|
|
|
|
} |
564
|
|
|
|
|
|
|
|
565
|
|
|
|
|
|
|
# otherwise, it all must be OK |
566
|
631
|
|
|
|
|
1964
|
$ga_map{$_} = $action for keys %grades; |
567
|
|
|
|
|
|
|
} |
568
|
|
|
|
|
|
|
|
569
|
973
|
100
|
|
|
|
4230
|
return scalar(keys %ga_map) ? \%ga_map : undef; |
570
|
|
|
|
|
|
|
} |
571
|
|
|
|
|
|
|
|
572
|
|
|
|
|
|
|
sub _validate_transport { |
573
|
307
|
|
|
307
|
|
536
|
my ($name, $option, $config) = @_; |
574
|
307
|
|
|
|
|
606
|
my $transport = ''; |
575
|
|
|
|
|
|
|
|
576
|
307
|
50
|
|
|
|
1821
|
if ( $option =~ /^(\w+(?:::\w+)*)\s?/ ) { |
577
|
307
|
|
|
|
|
626
|
$transport = $1; |
578
|
307
|
|
|
|
|
664
|
my $full_class = "Test::Reporter::Transport::$transport"; |
579
|
307
|
|
|
22
|
|
30575
|
eval "use $full_class ()"; |
|
22
|
|
|
22
|
|
198
|
|
|
22
|
|
|
21
|
|
35
|
|
|
22
|
|
|
21
|
|
248
|
|
|
22
|
|
|
20
|
|
185
|
|
|
22
|
|
|
20
|
|
46
|
|
|
22
|
|
|
20
|
|
242
|
|
|
21
|
|
|
20
|
|
238
|
|
|
21
|
|
|
14
|
|
60
|
|
|
21
|
|
|
|
|
266
|
|
|
21
|
|
|
|
|
206
|
|
|
21
|
|
|
|
|
47
|
|
|
21
|
|
|
|
|
247
|
|
|
20
|
|
|
|
|
463
|
|
|
19
|
|
|
|
|
52
|
|
|
19
|
|
|
|
|
240
|
|
|
20
|
|
|
|
|
503
|
|
|
19
|
|
|
|
|
47
|
|
|
19
|
|
|
|
|
263
|
|
|
20
|
|
|
|
|
725
|
|
|
19
|
|
|
|
|
55
|
|
|
19
|
|
|
|
|
225
|
|
|
20
|
|
|
|
|
360
|
|
|
19
|
|
|
|
|
51
|
|
|
19
|
|
|
|
|
237
|
|
|
14
|
|
|
|
|
154
|
|
|
14
|
|
|
|
|
38
|
|
|
14
|
|
|
|
|
177
|
|
580
|
307
|
100
|
|
|
|
1113
|
if ($@) { |
581
|
4
|
|
|
|
|
56
|
$CPAN::Frontend->mywarn( |
582
|
|
|
|
|
|
|
"\nCPAN::Reporter: error loading $full_class. Please install the missing module or choose a different transport mechanism.\n\n" |
583
|
|
|
|
|
|
|
); |
584
|
|
|
|
|
|
|
} |
585
|
|
|
|
|
|
|
} |
586
|
|
|
|
|
|
|
else { |
587
|
0
|
|
|
|
|
0
|
$CPAN::Frontend->mywarn( |
588
|
|
|
|
|
|
|
"\nCPAN::Reporter: Please provide a transport mechanism.\n\n" |
589
|
|
|
|
|
|
|
); |
590
|
0
|
|
|
|
|
0
|
return; |
591
|
|
|
|
|
|
|
} |
592
|
|
|
|
|
|
|
|
593
|
|
|
|
|
|
|
# we do extra validation for Metabase and offer to create the profile |
594
|
307
|
100
|
|
|
|
926
|
if ( $transport eq 'Metabase' ) { |
595
|
303
|
100
|
|
|
|
2122
|
unless ( $option =~ /\buri\s+\S+/ ) { |
596
|
2
|
|
|
|
|
24
|
$CPAN::Frontend->mywarn( |
597
|
|
|
|
|
|
|
"\nCPAN::Reporter: Please provide a target uri.\n\n" |
598
|
|
|
|
|
|
|
); |
599
|
2
|
|
|
|
|
39
|
return; |
600
|
|
|
|
|
|
|
} |
601
|
|
|
|
|
|
|
|
602
|
301
|
50
|
|
|
|
1868
|
unless ( $option =~ /\bid_file\s+(\S.+?)\s*$/ ) { |
603
|
0
|
|
|
|
|
0
|
$CPAN::Frontend->mywarn( |
604
|
|
|
|
|
|
|
"\nCPAN::Reporter: Please specify an id_file path.\n\n" |
605
|
|
|
|
|
|
|
); |
606
|
0
|
|
|
|
|
0
|
return; |
607
|
|
|
|
|
|
|
} |
608
|
|
|
|
|
|
|
|
609
|
301
|
|
|
|
|
933
|
my $id_file = _normalize_id_file($1); |
610
|
|
|
|
|
|
|
|
611
|
|
|
|
|
|
|
# Offer to create if it doesn't exist |
612
|
301
|
50
|
33
|
|
|
7951
|
if ( ! -e $id_file ) { |
|
|
50
|
|
|
|
|
|
613
|
0
|
|
|
|
|
0
|
my $answer = CPAN::Shell::colorable_makemaker_prompt( |
614
|
|
|
|
|
|
|
"\nWould you like to run 'metabase-profile' now to create '$id_file'?", "y" |
615
|
|
|
|
|
|
|
); |
616
|
0
|
0
|
|
|
|
0
|
if ( $answer =~ /^y/i ) { |
617
|
0
|
|
|
|
|
0
|
return _generate_profile( $id_file, $config ); |
618
|
|
|
|
|
|
|
} |
619
|
|
|
|
|
|
|
else { |
620
|
0
|
|
|
|
|
0
|
$CPAN::Frontend->mywarn( <<"END_ID_FILE" ); |
621
|
|
|
|
|
|
|
You can create a Metabase profile by typing 'metabase-profile' in your |
622
|
|
|
|
|
|
|
command prompt and moving the resulting file to the location you specified. |
623
|
|
|
|
|
|
|
If you did not specify an absolute path, put it in your .cpanreporter |
624
|
|
|
|
|
|
|
directory. You will need to do this before continuing. |
625
|
|
|
|
|
|
|
END_ID_FILE |
626
|
0
|
|
|
|
|
0
|
return; |
627
|
|
|
|
|
|
|
} |
628
|
|
|
|
|
|
|
} |
629
|
|
|
|
|
|
|
# Warn and fail validation if there but not readable |
630
|
|
|
|
|
|
|
elsif ( |
631
|
|
|
|
|
|
|
not ( -r $id_file |
632
|
|
|
|
|
|
|
or -r File::Spec->catdir(_get_config_dir(), $id_file) |
633
|
|
|
|
|
|
|
) |
634
|
|
|
|
|
|
|
) { |
635
|
0
|
|
|
|
|
0
|
$CPAN::Frontend->mywarn( |
636
|
|
|
|
|
|
|
"CPAN::Reporter: '$id_file' was not readable.\n\n" |
637
|
|
|
|
|
|
|
); |
638
|
0
|
|
|
|
|
0
|
return; |
639
|
|
|
|
|
|
|
} |
640
|
|
|
|
|
|
|
} # end Metabase |
641
|
|
|
|
|
|
|
|
642
|
305
|
|
|
|
|
1237
|
return 1; |
643
|
|
|
|
|
|
|
} |
644
|
|
|
|
|
|
|
|
645
|
|
|
|
|
|
|
sub _validate_seconds { |
646
|
22
|
|
|
22
|
|
47
|
my ($name, $option) = @_; |
647
|
22
|
100
|
100
|
|
|
308
|
return unless defined($option) && length($option) |
|
|
|
100
|
|
|
|
|
|
|
|
66
|
|
|
|
|
648
|
|
|
|
|
|
|
&& ($option =~ /^\d/) && $option >= 0; |
649
|
18
|
|
|
|
|
53
|
return $option; |
650
|
|
|
|
|
|
|
} |
651
|
|
|
|
|
|
|
|
652
|
|
|
|
|
|
|
sub _validate_skipfile { |
653
|
16
|
|
|
16
|
|
39
|
my ($name, $option) = @_; |
654
|
16
|
50
|
|
|
|
32
|
return unless $option; |
655
|
16
|
100
|
|
|
|
158
|
my $skipfile = File::Spec->file_name_is_absolute( $option ) |
656
|
|
|
|
|
|
|
? $option : File::Spec->catfile( _get_config_dir(), $option ); |
657
|
16
|
100
|
|
|
|
318
|
return -r $skipfile ? $skipfile : undef; |
658
|
|
|
|
|
|
|
} |
659
|
|
|
|
|
|
|
|
660
|
|
|
|
|
|
|
1; |
661
|
|
|
|
|
|
|
|
662
|
|
|
|
|
|
|
# ABSTRACT: Config file options for CPAN::Reporter |
663
|
|
|
|
|
|
|
|
664
|
|
|
|
|
|
|
=pod |
665
|
|
|
|
|
|
|
|
666
|
|
|
|
|
|
|
=encoding UTF-8 |
667
|
|
|
|
|
|
|
|
668
|
|
|
|
|
|
|
=head1 NAME |
669
|
|
|
|
|
|
|
|
670
|
|
|
|
|
|
|
CPAN::Reporter::Config - Config file options for CPAN::Reporter |
671
|
|
|
|
|
|
|
|
672
|
|
|
|
|
|
|
=head1 VERSION |
673
|
|
|
|
|
|
|
|
674
|
|
|
|
|
|
|
version 1.2018 |
675
|
|
|
|
|
|
|
|
676
|
|
|
|
|
|
|
=head1 SYNOPSIS |
677
|
|
|
|
|
|
|
|
678
|
|
|
|
|
|
|
From the CPAN shell: |
679
|
|
|
|
|
|
|
|
680
|
|
|
|
|
|
|
cpan> o conf init test_report |
681
|
|
|
|
|
|
|
|
682
|
|
|
|
|
|
|
=head1 DESCRIPTION |
683
|
|
|
|
|
|
|
|
684
|
|
|
|
|
|
|
Default options for CPAN::Reporter are read from a configuration file |
685
|
|
|
|
|
|
|
C<<< .cpanreporter/config.ini >>> in the user's home directory. (On Win32 platforms, |
686
|
|
|
|
|
|
|
the directory will be located in the user's "Documents" directory.) |
687
|
|
|
|
|
|
|
The location of the configuration directory or file may be specified |
688
|
|
|
|
|
|
|
using environment variables instead. |
689
|
|
|
|
|
|
|
|
690
|
|
|
|
|
|
|
The configuration file is in "ini" format, with the option name and value |
691
|
|
|
|
|
|
|
separated by an "=" sign |
692
|
|
|
|
|
|
|
|
693
|
|
|
|
|
|
|
email_from = "John Doe" |
694
|
|
|
|
|
|
|
edit_report = no |
695
|
|
|
|
|
|
|
|
696
|
|
|
|
|
|
|
Interactive configuration of email address and common |
697
|
|
|
|
|
|
|
action prompts may be repeated at any time from the CPAN shell. |
698
|
|
|
|
|
|
|
|
699
|
|
|
|
|
|
|
cpan> o conf init test_report |
700
|
|
|
|
|
|
|
|
701
|
|
|
|
|
|
|
If a configuration file does not exist, it will be created the first |
702
|
|
|
|
|
|
|
time interactive configuration is performed. |
703
|
|
|
|
|
|
|
|
704
|
|
|
|
|
|
|
Subsequent interactive configuration will also include any advanced |
705
|
|
|
|
|
|
|
options that have been added manually to the configuration file. |
706
|
|
|
|
|
|
|
|
707
|
|
|
|
|
|
|
=head1 INTERACTIVE CONFIGURATION OPTIONS |
708
|
|
|
|
|
|
|
|
709
|
|
|
|
|
|
|
=head2 Email Address (required) |
710
|
|
|
|
|
|
|
|
711
|
|
|
|
|
|
|
email_from = |
712
|
|
|
|
|
|
|
|
713
|
|
|
|
|
|
|
CPAN::Reporter requires users to provide an email address that will be used |
714
|
|
|
|
|
|
|
in the header of the report. |
715
|
|
|
|
|
|
|
|
716
|
|
|
|
|
|
|
The email address provided should be a valid address format, e.g.: |
717
|
|
|
|
|
|
|
|
718
|
|
|
|
|
|
|
email_from = user@domain |
719
|
|
|
|
|
|
|
email_from = John Doe |
720
|
|
|
|
|
|
|
email_from = "John Q. Public" |
721
|
|
|
|
|
|
|
|
722
|
|
|
|
|
|
|
=head2 Transport (required) |
723
|
|
|
|
|
|
|
|
724
|
|
|
|
|
|
|
transport = [transport args] |
725
|
|
|
|
|
|
|
|
726
|
|
|
|
|
|
|
This sets the transport mechanism passed to the C<<< transport() >>> method of |
727
|
|
|
|
|
|
|
L. Normally, CPAN::Reporter uses 'Metabase' for transport class |
728
|
|
|
|
|
|
|
(i.e. L) and will provide a default set of |
729
|
|
|
|
|
|
|
transport arguments. |
730
|
|
|
|
|
|
|
|
731
|
|
|
|
|
|
|
Metabase transport arguments are two space-separated keyEvalue pairs: |
732
|
|
|
|
|
|
|
|
733
|
|
|
|
|
|
|
=over |
734
|
|
|
|
|
|
|
|
735
|
|
|
|
|
|
|
=item * |
736
|
|
|
|
|
|
|
|
737
|
|
|
|
|
|
|
C<<< uri >>> -- URI for the Metabase API. Defaults to |
738
|
|
|
|
|
|
|
C<<< https://metabase.cpantesters.org/api/v1/ >>> |
739
|
|
|
|
|
|
|
|
740
|
|
|
|
|
|
|
=item * |
741
|
|
|
|
|
|
|
|
742
|
|
|
|
|
|
|
C<<< id_file >>> -- path to the user's Metabase profile file. |
743
|
|
|
|
|
|
|
Defaults to C<<< metabase_id.json >>>. (Assumed to be in the C<<< .cpanreporter >>> |
744
|
|
|
|
|
|
|
directory). |
745
|
|
|
|
|
|
|
|
746
|
|
|
|
|
|
|
=back |
747
|
|
|
|
|
|
|
|
748
|
|
|
|
|
|
|
Prior to sending reports, a user must have a valid profile file at the path |
749
|
|
|
|
|
|
|
specified. For Metabase transport, CPAN::Reporter will automatically rewrite a |
750
|
|
|
|
|
|
|
relative C<<< id_file >>> path as an absolute path located in the C<<< .cpanreporter >>> |
751
|
|
|
|
|
|
|
directory. |
752
|
|
|
|
|
|
|
|
753
|
|
|
|
|
|
|
If the specified profile file does not exist, CPAN::Reporter will offer |
754
|
|
|
|
|
|
|
to run C<<< metabase-profile >>> to create it. |
755
|
|
|
|
|
|
|
|
756
|
|
|
|
|
|
|
For other transport types, see the documentation that comes with your choice of |
757
|
|
|
|
|
|
|
Test::Reporter::Transport subclass for the proper way to set the C<<< transport >>> |
758
|
|
|
|
|
|
|
configuration option. |
759
|
|
|
|
|
|
|
|
760
|
|
|
|
|
|
|
=head2 Action Prompts |
761
|
|
|
|
|
|
|
|
762
|
|
|
|
|
|
|
Several steps in the generation of a test report are optional. Configuration |
763
|
|
|
|
|
|
|
options control whether an action should be taken automatically or whether |
764
|
|
|
|
|
|
|
CPAN::Reporter should prompt the user for the action to take. The action to |
765
|
|
|
|
|
|
|
take may be different for each report grade. For example, users may wish to |
766
|
|
|
|
|
|
|
customize for which grades they wish to manually review a report before sending |
767
|
|
|
|
|
|
|
it. |
768
|
|
|
|
|
|
|
|
769
|
|
|
|
|
|
|
Most users should just accept the default settings until they have some |
770
|
|
|
|
|
|
|
experience as CPAN Testers. |
771
|
|
|
|
|
|
|
|
772
|
|
|
|
|
|
|
Valid actions, and their associated meaning, are as follows: |
773
|
|
|
|
|
|
|
|
774
|
|
|
|
|
|
|
=over |
775
|
|
|
|
|
|
|
|
776
|
|
|
|
|
|
|
=item * |
777
|
|
|
|
|
|
|
|
778
|
|
|
|
|
|
|
C<<< yes >>> -- automatic yes |
779
|
|
|
|
|
|
|
|
780
|
|
|
|
|
|
|
=item * |
781
|
|
|
|
|
|
|
|
782
|
|
|
|
|
|
|
C<<< no >>> -- automatic no |
783
|
|
|
|
|
|
|
|
784
|
|
|
|
|
|
|
=item * |
785
|
|
|
|
|
|
|
|
786
|
|
|
|
|
|
|
C<<< ask/no >>> or just C<<< ask >>> -- ask each time, but default to no |
787
|
|
|
|
|
|
|
|
788
|
|
|
|
|
|
|
=item * |
789
|
|
|
|
|
|
|
|
790
|
|
|
|
|
|
|
C<<< ask/yes >>> -- ask each time, but default to yes |
791
|
|
|
|
|
|
|
|
792
|
|
|
|
|
|
|
=back |
793
|
|
|
|
|
|
|
|
794
|
|
|
|
|
|
|
For "ask" prompts, the default will be used if return is pressed immediately at |
795
|
|
|
|
|
|
|
the prompt or if the C<<< PERL_MM_USE_DEFAULT >>> environment variable is set to a |
796
|
|
|
|
|
|
|
true value. |
797
|
|
|
|
|
|
|
|
798
|
|
|
|
|
|
|
Action prompt options take one or more space-separated "grade:action" pairs, |
799
|
|
|
|
|
|
|
which are processed left to right. |
800
|
|
|
|
|
|
|
|
801
|
|
|
|
|
|
|
edit_report = fail:ask/yes pass:no |
802
|
|
|
|
|
|
|
|
803
|
|
|
|
|
|
|
An action by itself is taken as a default to be used for any grade which does |
804
|
|
|
|
|
|
|
not have a grade-specific action. A default action may also be set by using |
805
|
|
|
|
|
|
|
the word "default" in place of a grade. |
806
|
|
|
|
|
|
|
|
807
|
|
|
|
|
|
|
edit_report = ask/no |
808
|
|
|
|
|
|
|
edit_report = default:ask/no |
809
|
|
|
|
|
|
|
|
810
|
|
|
|
|
|
|
A grade by itself is taken to have the action "yes" for that grade. |
811
|
|
|
|
|
|
|
|
812
|
|
|
|
|
|
|
edit_report = default:no fail |
813
|
|
|
|
|
|
|
|
814
|
|
|
|
|
|
|
Multiple grades may be specified together by separating them with a slash. |
815
|
|
|
|
|
|
|
|
816
|
|
|
|
|
|
|
edit_report = pass:no fail/na/unknown:ask/yes |
817
|
|
|
|
|
|
|
|
818
|
|
|
|
|
|
|
The action prompt options included in interactive configuration are: |
819
|
|
|
|
|
|
|
|
820
|
|
|
|
|
|
|
=over |
821
|
|
|
|
|
|
|
|
822
|
|
|
|
|
|
|
=item * |
823
|
|
|
|
|
|
|
|
824
|
|
|
|
|
|
|
C<<< edit_report = ... >>> -- edit the test report before sending? |
825
|
|
|
|
|
|
|
(default:askEno passEna:no) |
826
|
|
|
|
|
|
|
|
827
|
|
|
|
|
|
|
=item * |
828
|
|
|
|
|
|
|
|
829
|
|
|
|
|
|
|
C<<< send_report = ... >>> -- should test reports be sent at all? |
830
|
|
|
|
|
|
|
(default:askEyes passEna:yes) |
831
|
|
|
|
|
|
|
|
832
|
|
|
|
|
|
|
=back |
833
|
|
|
|
|
|
|
|
834
|
|
|
|
|
|
|
Note that if C<<< send_report >>> is set to "no", CPAN::Reporter will still go through |
835
|
|
|
|
|
|
|
the motions of preparing a report, but will discard it rather than send it. |
836
|
|
|
|
|
|
|
|
837
|
|
|
|
|
|
|
A better way to disable CPAN::Reporter temporarily is with the CPAN option |
838
|
|
|
|
|
|
|
C<<< test_report >>>: |
839
|
|
|
|
|
|
|
|
840
|
|
|
|
|
|
|
cpan> o conf test_report 0 |
841
|
|
|
|
|
|
|
|
842
|
|
|
|
|
|
|
=head2 Mail Server (DEPRECATED) |
843
|
|
|
|
|
|
|
|
844
|
|
|
|
|
|
|
CPAN::Reporter used to send mail directly to perl.org mail servers. The |
845
|
|
|
|
|
|
|
C<<< smtp_server >>> option is now deprecated and will be ignored if it exists. |
846
|
|
|
|
|
|
|
|
847
|
|
|
|
|
|
|
=head1 ADVANCED CONFIGURATION OPTIONS |
848
|
|
|
|
|
|
|
|
849
|
|
|
|
|
|
|
These additional options are only necessary in special cases, for example if |
850
|
|
|
|
|
|
|
the default editor cannot be found or if reports shouldn't be sent in |
851
|
|
|
|
|
|
|
certain situations or for automated testing, and so on. |
852
|
|
|
|
|
|
|
|
853
|
|
|
|
|
|
|
=over |
854
|
|
|
|
|
|
|
|
855
|
|
|
|
|
|
|
=item * |
856
|
|
|
|
|
|
|
|
857
|
|
|
|
|
|
|
C<<< command_timeout >>> -- if greater than zero and the CPAN config is |
858
|
|
|
|
|
|
|
C<<< inactivity_timeout >>> is not set, then any commands executed by CPAN::Reporter |
859
|
|
|
|
|
|
|
will be halted after this many seconds; useful for unattended smoke testing |
860
|
|
|
|
|
|
|
to stop after some amount of time; generally, this should be large -- |
861
|
|
|
|
|
|
|
900 seconds or more -- as some distributions' tests take quite a long time to |
862
|
|
|
|
|
|
|
run. On MSWin32, L is a needed and trying to kill a process may |
863
|
|
|
|
|
|
|
actually deadlock in some situations -- so use at your own risk. |
864
|
|
|
|
|
|
|
|
865
|
|
|
|
|
|
|
=item * |
866
|
|
|
|
|
|
|
|
867
|
|
|
|
|
|
|
C<<< editor = >>> -- editor to use to edit the test report; if not set, |
868
|
|
|
|
|
|
|
Test::Reporter will use environment variables C<<< VISUAL >>>, C<<< EDITOR >>> or C<<< EDIT >>> |
869
|
|
|
|
|
|
|
(in that order) to find an editor |
870
|
|
|
|
|
|
|
|
871
|
|
|
|
|
|
|
=item * |
872
|
|
|
|
|
|
|
|
873
|
|
|
|
|
|
|
C<<< retry_submission >>> -- if greater than zero, CPAN::Reporter will try to |
874
|
|
|
|
|
|
|
resend the report after a few seconds in case the first attempt fails. |
875
|
|
|
|
|
|
|
|
876
|
|
|
|
|
|
|
=item * |
877
|
|
|
|
|
|
|
|
878
|
|
|
|
|
|
|
C<<< send_duplicates = ... >>> -- should duplicates of previous |
879
|
|
|
|
|
|
|
reports be sent, regardless of C<<< send_report >>>? (default:no) |
880
|
|
|
|
|
|
|
|
881
|
|
|
|
|
|
|
=item * |
882
|
|
|
|
|
|
|
|
883
|
|
|
|
|
|
|
C<<< send_PL_report = ... >>> -- if defined, used in place of |
884
|
|
|
|
|
|
|
C<<< send_report >>> during the PL phase |
885
|
|
|
|
|
|
|
|
886
|
|
|
|
|
|
|
=item * |
887
|
|
|
|
|
|
|
|
888
|
|
|
|
|
|
|
C<<< send_make_report = ... >>> -- if defined, used in place of |
889
|
|
|
|
|
|
|
C<<< send_report >>> during the make phase |
890
|
|
|
|
|
|
|
|
891
|
|
|
|
|
|
|
=item * |
892
|
|
|
|
|
|
|
|
893
|
|
|
|
|
|
|
C<<< send_test_report = ... >>> -- if defined, used in place of |
894
|
|
|
|
|
|
|
C<<< send_report >>> during the test phase |
895
|
|
|
|
|
|
|
|
896
|
|
|
|
|
|
|
=item * |
897
|
|
|
|
|
|
|
|
898
|
|
|
|
|
|
|
C<<< send_skipfile = >>> -- filename containing regular expressions (one |
899
|
|
|
|
|
|
|
per line) to match against the distribution ID (e.g. |
900
|
|
|
|
|
|
|
'AUTHOREDist-Name-0.01.tar.gz'); the report will not be sent if a match is |
901
|
|
|
|
|
|
|
found; non-absolute filename must be in the .cpanreporter config directory; |
902
|
|
|
|
|
|
|
|
903
|
|
|
|
|
|
|
=back |
904
|
|
|
|
|
|
|
|
905
|
|
|
|
|
|
|
If these options are manually added to the configuration file, they will |
906
|
|
|
|
|
|
|
be included (and preserved) in subsequent interactive configuration. |
907
|
|
|
|
|
|
|
|
908
|
|
|
|
|
|
|
=head2 Skipfile regular expressions |
909
|
|
|
|
|
|
|
|
910
|
|
|
|
|
|
|
Skip files are expected to have one regular expression per line and will be |
911
|
|
|
|
|
|
|
matched against the distribution ID, composed of the author's CPAN ID and the |
912
|
|
|
|
|
|
|
distribution tarball name. |
913
|
|
|
|
|
|
|
|
914
|
|
|
|
|
|
|
DAGOLDEN/CPAN-Reporter-1.00.tar.gz |
915
|
|
|
|
|
|
|
|
916
|
|
|
|
|
|
|
Lines that begin with a sharp (#) are considered comments and will not be |
917
|
|
|
|
|
|
|
matched. All regular expressions will be matched case insensitive and will |
918
|
|
|
|
|
|
|
not be anchored unless you provide one. |
919
|
|
|
|
|
|
|
|
920
|
|
|
|
|
|
|
As the format of a distribution ID is "AUTHOREtarball", anchoring at the |
921
|
|
|
|
|
|
|
start of the line with a caret (^) will match the author and with a slash (E) |
922
|
|
|
|
|
|
|
will match the distribution. |
923
|
|
|
|
|
|
|
|
924
|
|
|
|
|
|
|
# any distributions by JOHNDOE |
925
|
|
|
|
|
|
|
^JOHNDOE |
926
|
|
|
|
|
|
|
# any distributions starting with Win32 |
927
|
|
|
|
|
|
|
/Win32 |
928
|
|
|
|
|
|
|
# a particular very specific distribution |
929
|
|
|
|
|
|
|
^JOHNDOE/Foo-Bar-3.14 |
930
|
|
|
|
|
|
|
|
931
|
|
|
|
|
|
|
=head1 CONFIGURATION OPTIONS FOR DEBUGGING |
932
|
|
|
|
|
|
|
|
933
|
|
|
|
|
|
|
These options are useful for debugging only: |
934
|
|
|
|
|
|
|
|
935
|
|
|
|
|
|
|
=over |
936
|
|
|
|
|
|
|
|
937
|
|
|
|
|
|
|
=item * |
938
|
|
|
|
|
|
|
|
939
|
|
|
|
|
|
|
C<<< debug = >>> -- turns debugging onEoff |
940
|
|
|
|
|
|
|
|
941
|
|
|
|
|
|
|
=back |
942
|
|
|
|
|
|
|
|
943
|
|
|
|
|
|
|
=head1 ENVIRONMENT |
944
|
|
|
|
|
|
|
|
945
|
|
|
|
|
|
|
The following environment variables may be set to alter the default locations |
946
|
|
|
|
|
|
|
for CPAN::Reporter files: |
947
|
|
|
|
|
|
|
|
948
|
|
|
|
|
|
|
=over |
949
|
|
|
|
|
|
|
|
950
|
|
|
|
|
|
|
=item * |
951
|
|
|
|
|
|
|
|
952
|
|
|
|
|
|
|
C<<< PERL_CPAN_REPORTER_DIR >>> -- if set, this directory is used in place of |
953
|
|
|
|
|
|
|
the default C<<< .cpanreporter >>> directory; this will affect not only the location |
954
|
|
|
|
|
|
|
of the default C<<< config.ini >>>, but also the location of the |
955
|
|
|
|
|
|
|
L database and any other files that live in that |
956
|
|
|
|
|
|
|
directory |
957
|
|
|
|
|
|
|
|
958
|
|
|
|
|
|
|
=item * |
959
|
|
|
|
|
|
|
|
960
|
|
|
|
|
|
|
C<<< PERL_CPAN_REPORTER_CONFIG >>> -- if set, this file is used in place of |
961
|
|
|
|
|
|
|
the default C<<< config.ini >>> file; it may be in any directory, regardless of the |
962
|
|
|
|
|
|
|
choice of configuration directory |
963
|
|
|
|
|
|
|
|
964
|
|
|
|
|
|
|
=back |
965
|
|
|
|
|
|
|
|
966
|
|
|
|
|
|
|
=head1 SEE ALSO |
967
|
|
|
|
|
|
|
|
968
|
|
|
|
|
|
|
=over |
969
|
|
|
|
|
|
|
|
970
|
|
|
|
|
|
|
=item * |
971
|
|
|
|
|
|
|
|
972
|
|
|
|
|
|
|
L |
973
|
|
|
|
|
|
|
|
974
|
|
|
|
|
|
|
=item * |
975
|
|
|
|
|
|
|
|
976
|
|
|
|
|
|
|
L |
977
|
|
|
|
|
|
|
|
978
|
|
|
|
|
|
|
=item * |
979
|
|
|
|
|
|
|
|
980
|
|
|
|
|
|
|
L |
981
|
|
|
|
|
|
|
|
982
|
|
|
|
|
|
|
=back |
983
|
|
|
|
|
|
|
|
984
|
|
|
|
|
|
|
=head1 AUTHOR |
985
|
|
|
|
|
|
|
|
986
|
|
|
|
|
|
|
David Golden |
987
|
|
|
|
|
|
|
|
988
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
989
|
|
|
|
|
|
|
|
990
|
|
|
|
|
|
|
This software is Copyright (c) 2006 by David Golden. |
991
|
|
|
|
|
|
|
|
992
|
|
|
|
|
|
|
This is free software, licensed under: |
993
|
|
|
|
|
|
|
|
994
|
|
|
|
|
|
|
The Apache License, Version 2.0, January 2004 |
995
|
|
|
|
|
|
|
|
996
|
|
|
|
|
|
|
=cut |
997
|
|
|
|
|
|
|
|
998
|
|
|
|
|
|
|
__END__ |