File Coverage

blib/lib/CPAN/Reporter/Config.pm
Criterion Covered Total %
statement 178 215 82.7
branch 63 90 70.0
condition 24 37 64.8
subroutine 34 35 97.1
pod n/a
total 299 377 79.3


line stmt bran cond sub pod time code
1 60     60   9908 use strict;
  60         296  
  60         2652  
2             package CPAN::Reporter::Config;
3              
4             our $VERSION = '1.2019';
5              
6 59     59   16629 use Config::Tiny 2.08 ();
  59         39282  
  59         1437  
7 59     59   946 use File::Glob ();
  59         288  
  59         1291  
8 57     57   833 use File::HomeDir 0.58 ();
  57         897  
  57         1448  
9 54     54   817 use File::Path qw/mkpath/;
  54         249  
  54         2451  
10 53     53   743 use File::Spec 3.19 ();
  53         757  
  53         1213  
11 53     53   27603 use IPC::Cmd 0.76 ();
  53         1575379  
  53         1473  
12 44     44   505 use IO::File ();
  44         149  
  44         914  
13 39     39   222 use CPAN 1.9301 (); # for printing warnings
  39         625  
  39         125688  
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   5 my $config_dir = _get_config_dir();
55 2         4 my $config_file = _get_config_file();
56              
57 2 50       29 mkpath $config_dir if ! -d $config_dir;
58 2 50       22 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         9 $CPAN::Frontend->myprint( _grade_action_prompt() );
70              
71             # read or create
72 2 100       100 if ( -f $config_file ) {
73 1         13 $CPAN::Frontend->myprint(
74             "\nCPAN::Reporter: found your CPAN::Reporter config file at:\n$config_file\n"
75             );
76 1         21 $config = _open_config_file();
77             # if we can't read it, bail out
78 1 50       4 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       3 $existing_options = { %{$config->{_}} } if $config;
  1         6  
85 1         6 $CPAN::Frontend->myprint(
86             "\nCPAN::Reporter: Updating your CPAN::Reporter configuration settings:\n"
87             );
88             }
89             else {
90 1         5 $CPAN::Frontend->myprint(
91             "\nCPAN::Reporter: no config file found; creating a new one.\n"
92             );
93 1         23 $config = Config::Tiny->new();
94             }
95              
96 2         30 my %spec = _config_spec();
97              
98 2         7 for my $k ( _config_order() ) {
99 8         15 my $option_data = $spec{$k};
100 8         54 $CPAN::Frontend->myprint( "\n" . $option_data->{info}. "\n");
101             # options with defaults are mandatory
102 8 50       152 if ( defined $option_data->{default} ) {
103             # if we have a default, always show as a sane recommendation
104 8 100       19 if ( length $option_data->{default} ) {
105 6         27 $CPAN::Frontend->myprint(
106             "(Recommended: '$option_data->{default}')\n\n"
107             );
108             }
109             # repeat until validated
110             PROMPT:
111 8   100     119 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     511 if ( ! $option_data->{validate} ||
118             $option_data->{validate}->($k, $answer, $config->{_})
119             ) {
120 8         24 $config->{_}{$k} = $answer;
121 8         18 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         23 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         26 for my $k ( keys %$existing_options ) {
149             $config->{_}{$k} = CPAN::Shell::colorable_makemaker_prompt(
150 2         62 "$k?", $existing_options->{$k}
151             );
152             }
153              
154             $CPAN::Frontend->myprint(
155 2         59 "\nCPAN::Reporter: writing config file to '$config_file'.\n"
156             );
157 2 50       42 if ( $config->write( $config_file ) ) {
158 2         434 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   7 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   20587 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   10306 if ( defined $ENV{PERL_CPAN_REPORTER_DIR} &&
354             length $ENV{PERL_CPAN_REPORTER_DIR}
355             ) {
356 3         27 return $ENV{PERL_CPAN_REPORTER_DIR};
357             }
358              
359 1368         17876 my $conf_dir = File::Spec->catdir(File::HomeDir->my_home, ".cpanreporter");
360              
361 1368 50       27296 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         19809 return $conf_dir;
367             }
368              
369             #--------------------------------------------------------------------------#
370             # _get_config_file
371             #--------------------------------------------------------------------------#
372              
373             sub _get_config_file {
374 498 100 66 498   5396 if ( defined $ENV{PERL_CPAN_REPORTER_CONFIG} &&
375             length $ENV{PERL_CPAN_REPORTER_CONFIG}
376             ) {
377 2         14 return $ENV{PERL_CPAN_REPORTER_CONFIG};
378             }
379             else {
380 496         3347 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   37829 my $config = shift;
390             # extract and return valid options, with fallback to defaults
391 305         2218 my %spec = CPAN::Reporter::Config::_config_spec();
392 305         1531 my %active;
393 305         3112 OPTION: for my $option ( keys %spec ) {
394 5490 100       12410 if ( exists $config->{_}{$option} ) {
395 1576         4142 my $val = $config->{_}{$option};
396 1576 100 100     11482 if ( $spec{$option}{validate} &&
397             ! $spec{$option}{validate}->($option, $val)
398             ) {
399 5         86 $CPAN::Frontend->mywarn( "\nCPAN::Reporter: invalid option '$val' in '$option'. Using default instead.\n\n" );
400 5         145 $active{$option} = $spec{$option}{default};
401 5         39 next OPTION;
402             }
403 1571         6120 $active{$option} = $val;
404             }
405             else {
406             $active{$option} = $spec{$option}{default}
407 3914 100       14170 if defined $spec{$option}{default};
408             }
409             }
410 305         2968 return \%active;
411             }
412              
413              
414             #--------------------------------------------------------------------------#
415             # _grade_action_prompt -- describes grade action pairs
416             #--------------------------------------------------------------------------#
417              
418             sub _grade_action_prompt {
419 2     2   19 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   3220 my $action = shift;
444 1449         3589 return grep { $action eq $_ } @valid_actions;
  7245         16732  
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   1416 my $grade = shift;
454 765         1388 return grep { $grade eq $_ } @valid_grades;
  3825         8521  
455             }
456              
457              
458             #--------------------------------------------------------------------------#
459             # _normalize_id_file
460             #--------------------------------------------------------------------------#
461              
462             sub _normalize_id_file {
463 422     422   4140 my ($id_file) = @_;
464              
465             # Windows does not use ~ to signify a home directory
466 422 50 33     4907 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         52 $id_file = File::Spec->canonpath(File::Glob::bsd_glob( $id_file ));
471             }
472 422 100       9808 unless ( File::Spec->file_name_is_absolute( $id_file ) ) {
473 419         1717 $id_file = File::Spec->catfile(
474             CPAN::Reporter::Config::_get_config_dir(), $id_file
475             );
476             }
477 422         3009 return $id_file;
478             }
479              
480             #--------------------------------------------------------------------------#
481             # _open_config_file
482             #--------------------------------------------------------------------------#
483              
484             sub _open_config_file {
485 305     305   4939 my $config_file = _get_config_file();
486 305 100       10336 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         121744 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   3669 my ($name, $value) = @_;
500 8 50       27 return 1 if ! exists $option_specs{$name}{validate};
501 8         19 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   52586 my ($name, $option) = @_;
512 973   100     2783 $option ||= "no";
513              
514 973         1861 my %ga_map; # grade => action
515              
516 973         4685 PAIR: for my $grade_action ( split q{ }, $option ) {
517 1448         3173 my ($grade_list,$action);
518              
519 1448 100       8637 if ( $grade_action =~ m{.:.} ) {
    100          
    100          
    100          
520             # parse pair for later check
521 632         3747 ($grade_list, $action) = $grade_action =~ m{\A([^:]+):(.+)\z};
522             }
523             elsif ( _is_valid_action($grade_action) ) {
524             # action by itself
525 813         4328 $ga_map{default} = $grade_action;
526 813         3672 next PAIR;
527             }
528             elsif ( _is_valid_grade($grade_action) ) {
529             # grade by itself
530 1         3 $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         3 $grade_list = $grade_action;
536 1         16 $action = "yes";
537             }
538             else {
539             # something weird, so warn and skip
540 1         13 $CPAN::Frontend->mywarn(
541             "\nCPAN::Reporter: ignoring invalid grade:action '$grade_action' for '$name'.\n\n"
542             );
543 1         57 next PAIR;
544             }
545              
546             # check gradelist
547 633         2188 my %grades = map { ($_,1) } split( "/", $grade_list);
  762         4135  
548 633         2098 for my $g ( keys %grades ) {
549 762 100       1915 if ( ! _is_valid_grade($g) ) {
550 1         10 $CPAN::Frontend->mywarn(
551             "\nCPAN::Reporter: ignoring invalid grade '$g' in '$grade_action' for '$name'.\n\n"
552             );
553 1         53 delete $grades{$g};
554             }
555             }
556              
557             # check action
558 633 100       1636 if ( ! _is_valid_action($action) ) {
559 2         20 $CPAN::Frontend->mywarn(
560             "\nCPAN::Reporter: ignoring invalid action '$action' in '$grade_action' for '$name'.\n\n"
561             );
562 2         101 next PAIR;
563             }
564              
565             # otherwise, it all must be OK
566 631         3025 $ga_map{$_} = $action for keys %grades;
567             }
568              
569 973 100       6983 return scalar(keys %ga_map) ? \%ga_map : undef;
570             }
571              
572             sub _validate_transport {
573 307     307   2012 my ($name, $option, $config) = @_;
574 307         1278 my $transport = '';
575              
576 307 50       4637 if ( $option =~ /^(\w+(?:::\w+)*)\s?/ ) {
577 307         1744 $transport = $1;
578 307         4986 my $full_class = "Test::Reporter::Transport::$transport";
579 307     22   61305 eval "use $full_class ()";
  22     22   431  
  22     21   103  
  22     21   419  
  22     20   527  
  22     20   94  
  22     20   406  
  21     20   646  
  21     14   238  
  21         546  
  21         594  
  21         152  
  21         532  
  20         1013  
  19         195  
  19         495  
  20         847  
  19         193  
  19         457  
  20         876  
  19         160  
  19         469  
  20         853  
  19         243  
  19         523  
  14         448  
  14         160  
  14         384  
580 307 100       2475 if ($@) {
581 4         132 $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       1798 if ( $transport eq 'Metabase' ) {
595 303 100       4126 unless ( $option =~ /\buri\s+\S+/ ) {
596 2         61 $CPAN::Frontend->mywarn(
597             "\nCPAN::Reporter: Please provide a target uri.\n\n"
598             );
599 2         104 return;
600             }
601              
602 301 50       4314 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         2194 my $id_file = _normalize_id_file($1);
610              
611             # Offer to create if it doesn't exist
612 301 50 33     11610 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         2220 return 1;
643             }
644              
645             sub _validate_seconds {
646 22     22   93 my ($name, $option) = @_;
647 22 100 100     455 return unless defined($option) && length($option)
      100        
      66        
648             && ($option =~ /^\d/) && $option >= 0;
649 18         96 return $option;
650             }
651              
652             sub _validate_skipfile {
653 16     16   72 my ($name, $option) = @_;
654 16 50       65 return unless $option;
655 16 100       296 my $skipfile = File::Spec->file_name_is_absolute( $option )
656             ? $option : File::Spec->catfile( _get_config_dir(), $option );
657 16 100       345 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.2019
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) 2023 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__