File Coverage

blib/lib/App/PTP.pm
Criterion Covered Total %
statement 75 78 96.1
branch 20 30 66.6
condition 2 3 66.6
subroutine 13 13 100.0
pod 0 3 0.0
total 110 127 86.6


line stmt bran cond sub pod time code
1             package App::PTP;
2              
3 18     18   221419 use 5.022;
  18         165  
4 18     18   93 use strict;
  18         37  
  18         346  
5 18     18   88 use warnings;
  18         38  
  18         426  
6              
7 18     18   8461 use App::PTP::Args;
  18         67  
  18         754  
8 18     18   132 use App::PTP::Commands 'warn_or_die_if_needed';
  18         43  
  18         1015  
9 18     18   116 use App::PTP::Files;
  18         42  
  18         987  
10 18     18   114 use Data::Dumper;
  18         44  
  18         765  
11 18     18   108 use File::Find;
  18         38  
  18         849  
12 18     18   122 use Safe;
  18         44  
  18         14196  
13              
14             our $VERSION = '1.09';
15              
16             $Data::Dumper::Terse = 1; # Don't output variable names.
17             $Data::Dumper::Sortkeys = 1; # Sort the content of the hash variables.
18             $Data::Dumper::Useqq = 1; # Use double quote for string (better escaping).
19              
20             my $safe = Safe->new();
21             $safe->deny_only(':subprocess', ':ownprocess', ':others', ':dangerous');
22             $safe->reval('use App::PTP::PerlEnv;');
23             $safe->reval('use File::Spec::Functions qw(:ALL);');
24              
25             # maybe_expand_dirs(filepath)
26             # If filepath is a normal file, then returns it as, is.
27             # If filepath does not exist, then terminates the program with an error.
28             # If filepath is a directory and the $recursive option is not set then
29             # terminates the program with an error, otherwise returns the list of all files
30             # that it contains.
31             sub maybe_expand_dirs {
32 154     154 0 346 my ($f, $options) = @_;
33 154 100       805 if (ref $f) {
    50          
    100          
34             # This will be the $stdin_marker reference.
35 129 50       375 if ($options->{in_place}) {
36 0         0 die "Reading from STDIN is incompatible with the --in-place option.\n";
37             }
38 129         489 return $f;
39             } elsif (not -e $f) {
40 0         0 die "File does not exist: ${f}\n";
41             } elsif (-d _) {
42 1 50       6 if (not $options->{recursive}) {
43 0         0 die "Input is a directory (did you forget the -R option?): ${f}\n";
44             }
45 1         4 my @files;
46             my $filter;
47 1 50       4 if (defined $options->{input_filter}) {
48 1         8 $filter = $safe->reval("sub { $options->{input_filter} }");
49 1 50       989 die "FATAL: Cannot wrap code for --input_filter: ${@}" if $@;
50             }
51             find({
52             # Because of the follow option, a stat has already been done on the file,
53             # so the '_' magic is guaranteed to work.
54             wanted => sub {
55 11 100   11   287 if (-f _) {
56 9         16 my $f = $_;
57 9 50       19 if (defined $filter) {
58 9         35 my $r = $filter->();
59 9 100 66     4815 return if warn_or_die_if_needed(
60             'Perl code failed while filtering input') || !$r;
61             }
62 2         59 push @files, $f;
63             }
64             } ,
65 1         174 follow => 1,
66             no_chdir => 1,
67             }, $f);
68 1         28 return sort @files;
69             } else {
70             # We assume that everything else is a file.
71 24         120 return $f;
72             }
73             }
74              
75             sub process_all {
76 138     138 0 333 my ($inputs, $pipeline, $options, $stdin) = @_;
77 138         560 $App::PTP::Commands::I_setter->set(1);
78 138 100       359 if ($options->{merge}) {
79 4 50       23 print "Merging all the inputs.\n" if $options->{debug_mode};
80 4         7 my $missing_final_separator = 0;
81 4         8 my @content;
82 4         10 for my $input (@$inputs) {
83 7         24 my ($content, $missing_separator) =
84             read_input($input, $options, $stdin);
85 7         23 push @content, @$content;
86 7         22 $missing_final_separator = $missing_separator;
87             }
88             App::PTP::Commands::process(
89 4         22 \$App::PTP::Files::merged_marker, $pipeline, $options, \@content,
90             $missing_final_separator);
91 4         17 write_output(\$App::PTP::Files::merged_marker, \@content,
92             $missing_final_separator, $options);
93             } else {
94 134         313 for my $file_name (@$inputs) {
95 148         464 my ($content, $missing_final_separator) =
96             read_input($file_name, $options, $stdin);
97             # Note that process can modify the input $file_name variable.
98 148         660 App::PTP::Commands::process($file_name, $pipeline, $options, $content,
99             $missing_final_separator);
100 146         2019 write_output($file_name, $content, $missing_final_separator, $options);
101 146         524 $App::PTP::Commands::I_setter->inc();
102             }
103             }
104             }
105              
106             sub Run {
107 138     138 0 1045 my ($stdin, $stdout, $stderr, $argv) = @_;
108 138         344 select($stderr); # All debug output, this applies inside the safe too.
109 138         603 my ($inputs, $pipeline, $options) =
110             App::PTP::Args::parse_command_line($argv);
111              
112 138 50       431 if ($options->{debug_mode}) {
113 138         566 print 'options = '.Dumper($options)."\n";
114 138         18031 print 'inputs = '.Dumper($inputs)."\n";
115 138         7021 print 'pipeline = '.Dumper($pipeline)."\n";
116             }
117              
118 138         13944 @$inputs = map { maybe_expand_dirs($_, $options) } @$inputs;
  154         386  
119 138 50       595 print 'expanded @inputs = '.Dumper($inputs)."\n" if $options->{debug_mode};
120              
121 138 50       6140 return if $options->{abort};
122              
123 138         541 init_global_output($options, $stdout);
124 138         22814 process_all($inputs, $pipeline, $options, $stdin);
125 136         491 close_global_output($options);
126             }
127              
128             1;