File Coverage

blib/lib/App/perlminlint.pm
Criterion Covered Total %
statement 20 108 18.5
branch 0 32 0.0
condition 0 24 0.0
subroutine 7 22 31.8
pod 0 15 0.0
total 27 201 13.4


line stmt bran cond sub pod time code
1             package App::perlminlint; sub MY () {__PACKAGE__}
2             # -*- coding: utf-8 -*-
3 1     1   22349 use 5.009;
  1         4  
4 1     1   6 use strict;
  1         1  
  1         24  
5 1     1   5 use warnings FATAL => 'all';
  1         7  
  1         53  
6              
7             our $VERSION = '0.22';
8              
9 1     1   5 use Carp;
  1         2  
  1         79  
10 1     1   912 use autodie;
  1         148498  
  1         5  
11              
12 1         17 use App::perlminlint::Object -as_base,
13             [fields => qw/libs
14             no_stderr
15             help
16 1     1   7206 _plugins/];
  1         4  
17              
18             require lib;
19             require File::Basename;
20              
21 1     1   1367 use Module::Pluggable require => 1, sub_name => '_plugins';
  1         13679  
  1         9  
22              
23             sub usage {
24 0     0 0   (my MY $app) = @_;
25 0           die <
26 0           Usage: @{[$app->basename($0)]} FILES...
27             END
28             }
29              
30             sub run {
31 0     0 0   my ($pack, $argv) = @_;
32              
33 0           my MY $app = $pack->new($pack->parse_argv
34             ($argv, {h => 'help'
35             # Just to ignore -w -c -wc
36             , w => '', c => '', wc => ''
37             }));
38              
39 0 0         if ($app->{no_stderr}) {
40 0           close STDERR;
41 0           open STDERR, '>&STDOUT';
42             }
43              
44 0 0 0       if ($app->{help} or not @$argv) {
45 0           $app->usage;
46             }
47              
48 0           $app->add_lib_to_inc_for(@$argv);
49              
50 0           my @res = $app->lint(@$argv);
51 0 0         if (@res) {
52 0 0 0       print join("\n", @res), "\n" unless @res == 1 and ($res[0] // '') eq '';
      0        
53             } else {
54 0           print "OK\n";
55             }
56             }
57              
58             sub add_lib_to_inc_for {
59 0     0 0   (my MY $self, my $fn) = @_;
60 0           my @dirs = $self->splitdir($self->rel2abs($fn));
61 0           pop @dirs;
62 0           while (@dirs) {
63 0 0         -d (my $libdir = $self->catdir(@dirs, "lib"))
64             or next;
65 0           import lib $libdir;
66 0           last;
67             } continue {
68 0           pop @dirs;
69             }
70             }
71              
72             sub lint {
73 0     0 0   (my MY $self, my $fn) = @_;
74              
75 0           my @fallback;
76 0           foreach my $plugin ($self->plugins) {
77              
78 0 0         if (my $obj = $self->apply_to($plugin, handle_match => $fn)) {
    0          
79             #
80 0 0         my @res = $obj->handle_test($fn)
81             or next;
82              
83 0           return @res;
84              
85             } elsif ($plugin->is_generic) {
86              
87 0           push @fallback, $plugin;
88             }
89             }
90              
91 0 0         unless (@fallback) {
92 0           die "Don't know how to lint $fn\n";
93             }
94              
95 0           foreach my $plugin (@fallback) {
96              
97 0 0         my @res = $self->apply_to($plugin, handle_test => $fn)
98             or next;
99              
100 0           return @res;
101             }
102              
103 0           return "";
104             }
105              
106             sub apply_to {
107 0     0 0   (my MY $self, my ($plugin, $method, @args)) = @_;
108              
109 0           $plugin->new(app => $self)->$method(@args);
110             }
111              
112             sub plugins {
113 0     0 0   (my MY $self) = @_;
114             my $plugins = $self->{_plugins}
115 0   0       //= [sort {$b->priority <=> $a->priority} $self->_plugins];
  0            
116 0 0         wantarray ? @$plugins : $plugins;
117             }
118              
119             sub run_perl {
120 0     0 0   my MY $self = shift;
121 0 0         system($^X, @_) == 0
122             or exit $? >> 8;
123             }
124              
125             sub read_file {
126 0     0 0   (my MY $self, my $fn) = @_;
127 0           open my $fh, '<', $fn;
128 0           local $/;
129 0           scalar <$fh>;
130             }
131              
132             sub basename {
133 0     0 0   shift; File::Basename::basename(@_);
  0            
134             }
135              
136             sub dirname {
137 0     0 0   shift; File::Basename::dirname(@_);
  0            
138             }
139              
140             sub rootname {
141 0     0 0   shift;
142 0           my $fn = shift;
143 0           $fn =~ s/\.\w+$//;
144 0           join "", $fn, @_;
145             }
146              
147             sub inc_opt {
148 0     0 0   my ($app, $file, $modname) = @_;
149 0           (my $no_pm = $file) =~ s/\.\w+$//;
150 0           my @filepath = $app->splitdir($app->rel2abs($no_pm));
151 0           my @modpath = grep {$_ ne ''} split "::", $modname;
  0            
152 0           my @popped;
153 0   0       while (@modpath and @filepath and $modpath[-1] eq $filepath[-1]) {
      0        
154 0           unshift @popped, pop @modpath;
155 0           pop @filepath;
156             }
157 0 0         if (@modpath) {
158 0           die "Can't find library root directory of $modname in file $file\n@modpath\n";
159             }
160 0           '-I' . $app->catdir(@filepath);
161             }
162              
163             sub read_shbang_opts {
164 0     0 0   (my MY $app, my $fn) = @_;
165              
166 0           my @opts;
167              
168 0           my $body = $app->read_file($fn);
169              
170 0           my (@shbang) = $app->parse_shbang($body);
171              
172 0 0         if (grep {$_ eq "-T"} @shbang) {
  0            
173 0           push @opts, "-T";
174             }
175              
176 0           @opts;
177             }
178              
179             sub parse_shbang {
180 0     0 0   my MY $app = shift;
181 0 0         my ($shbang) = $_[0] =~ m{^(\#![^\n]+)}
182             or return;
183 0           split " ", $shbang;
184             }
185              
186             # XXX: Real new and options...
187              
188             sub parse_argv {
189 0     0 0   my ($pack, $list, $alias) = @_;
190 0           my @opts;
191 0   0       while (@$list
192             and my ($k, $v) = $list->[0] =~ /^--?([-\w]+)(?:=(.*))?/) {
193 0           $k =~ s/-/_/g;
194 0   0       my $opt = $alias->{$k} // $k;
195 0 0         next if $opt eq ''; # To drop compat-only option.
196 0   0       push @opts, $opt => ($v // 1);
197             } continue {
198 0           shift @$list;
199             }
200 0           @opts;
201             }
202              
203             1; # End of App::perlminlint
204              
205             __END__