File Coverage

blib/lib/Tangerine.pm
Criterion Covered Total %
statement 92 95 96.8
branch 30 40 75.0
condition 16 43 37.2
subroutine 18 21 85.7
pod 8 10 80.0
total 164 209 78.4


line stmt bran cond sub pod time code
1             package Tangerine;
2             $Tangerine::VERSION = '0.19';
3             # ABSTRACT: Examine perl files and report dependency metadata
4 15     15   254836 use 5.010;
  15         46  
5 15     15   67 use strict;
  15         22  
  15         354  
6 15     15   71 use warnings;
  15         18  
  15         407  
7 15     15   98500 use utf8;
  15         146  
  15         73  
8 15     15   9059 use PPI;
  15         1947531  
  15         735  
9 15     15   153 use List::MoreUtils qw(none);
  15         28  
  15         268  
10 15     15   9939 use Scalar::Util qw(blessed);
  15         29  
  15         1024  
11 15     15   7819 use Tangerine::Hook;
  15         44  
  15         545  
12 15     15   7089 use Tangerine::Occurence;
  15         31  
  15         523  
13 15     15   86 use Tangerine::Utils qw(accessor addoccurence);
  15         24  
  15         22299  
14              
15             sub new {
16 14     14 1 156 my $class = shift;
17 14         62 my %args = @_;
18             bless {
19             _file => $args{file},
20 14   50     288 _mode => $args{mode} // 'all',
21             _hooks => {
22             package => [ qw/package/ ],
23             compile => [ qw/use list prefixedlist if inline moduleload
24             moduleruntime mooselike testrequires tests xxx/ ],
25             runtime => [ qw/require/ ],
26             },
27             _package => {},
28             _compile => {},
29             _runtime => {},
30             }, $class
31             }
32              
33 28     28 0 106 sub file { accessor _file => @_ }
34 210     210 0 443 sub mode { accessor _mode => @_ }
35              
36 5     5 1 1174 sub package { accessor _package => @_ }
37 437     437 1 57509 sub compile { accessor _compile => @_ }
38 167     167 1 17328 sub runtime { accessor _runtime => @_ }
39             # For pre-0.15 compatibility
40 0     0 1 0 sub provides { accessor _package => @_ }
41 0     0 1 0 sub requires { accessor _runtime => @_ }
42 0     0 1 0 sub uses { accessor _compile => @_ }
43              
44             sub run {
45 14     14 1 85 my $self = shift;
46 14 50       48 return 0 unless -r $self->file;
47 14 50       61 $self->mode('all')
48             unless $self->mode =~
49             /^(a(ll)?|p(ackage|rov)?|compile|d(ep)?|r(untime|eq)?|u(se)?)$/;
50 14         54 my $document = PPI::Document->new($self->file, readonly => 1);
51 14 50       91251 return 0 unless $document;
52 14 50       126 my $statements = $document->find('Statement') or return 1;
53 14         28312 my @hooks;
54 14         45 for my $type (qw(package compile runtime)) {
55 42         68 for my $hname (@{$self->{_hooks}->{$type}}) {
  42         190  
56 182         384 my $hook = "Tangerine::hook::$hname";
57 182         10403 eval "require $hook";
58 182         2180 push @hooks, $hook->new(type => $type);
59             }
60             }
61             @hooks = grep {
62 14 50 0     42 if ($self->mode =~ /^a/o ||
  182   33     277  
      0        
      0        
      0        
      0        
63             $_->type eq 'package' && $self->mode =~ /^p/o ||
64             $_->type eq 'compile' && $self->mode =~ /^[cdu]/o ||
65             $_->type eq 'runtime' && $self->mode =~ /^[dr]/o) {
66 182         972 $_
67             }
68             } @hooks;
69 14         42 my $children;
70             my $forcetype;
71 14         54 STATEMENT: for my $statement (@$statements) {
72 147   100     933 $children //= [ $statement->schildren ];
73 147 100 100     2289 if ($children->[1] &&
      66        
74             ($children->[1] eq ',' || $children->[1] eq '=>')) {
75 15         251 undef $children;
76             next STATEMENT
77 15         37 }
78 132         2915 for my $hook (@hooks) {
79 1759 100       5113 if (my $data = $hook->run($children)) {
80 174         359 my $modules = $data->modules;
81 174         480 for my $k (keys %$modules) {
82 160 100 66     1223 if ($k !~ m/^[a-z_][a-z0-9_]*(::[a-z0-9_]+)*(::)?$/io ||
83             $k =~ m/^__[A-Z]+__$/o) {
84 8         13 delete $modules->{$k};
85             next
86 8         13 }
87 152 100       343 if (my ($class) = ($k =~ /^(.+)::$/o)) {
88             $modules->{$class} = $modules->{$k}
89 1 50       5 unless exists $modules->{$class};
90 1         3 delete $modules->{$k};
91 1         3 $k = $class
92             }
93 152         581 $modules->{$k}->line($statement->line_number);
94             }
95 174   66     1595 my $type = $forcetype // $hook->type;
96 174 100       469 if ($type eq 'package') {
    100          
    50          
97 1         6 $self->package(addoccurence($self->package, $modules));
98             } elsif ($type eq 'compile') {
99 124         248 $self->compile(addoccurence($self->compile, $modules));
100             } elsif ($type eq 'runtime') {
101 49         110 $self->runtime(addoccurence($self->runtime, $modules));
102             }
103 174 100       163 if (@{$data->hooks}) {
  174         365  
104 14         24 for my $newhook (@{$data->hooks}) {
  14         32  
105 14 50 33     44 next if ($newhook->type eq 'package') && ($self->mode =~ /^[dcru]/o);
106 14 50 33     38 next if ($newhook->type eq 'runtime') && ($self->mode =~ /^[pcu]/o);
107 14 50 33     37 next if ($newhook->type eq 'compile') && ($self->mode =~ /^[pr]/o);
108             push @hooks, $newhook
109             if none {
110 191 100   191   799 blessed($newhook) eq blessed($_) &&
111             $newhook->type eq $_->type
112 14 100       144 } @hooks;
113             }
114             }
115 174 100       151 if (@{$data->children}) {
  174         358  
116 22         39 $children = $data->children;
117 22         40 $forcetype = $data->type;
118 22         114 redo STATEMENT;
119             }
120             }
121             }
122 110         251 undef $children,
123             undef $forcetype;
124             }
125 14         890 1;
126             }
127              
128             1;
129              
130             __END__