File Coverage

blib/lib/Tangerine.pm
Criterion Covered Total %
statement 94 95 98.9
branch 32 44 72.7
condition 16 43 37.2
subroutine 19 19 100.0
pod 5 7 71.4
total 166 208 79.8


line stmt bran cond sub pod time code
1             package Tangerine;
2             $Tangerine::VERSION = '0.20';
3             # ABSTRACT: Examine perl files and report dependency metadata
4 15     15   295460 use 5.010;
  15         54  
5 15     15   92 use strict;
  15         28  
  15         343  
6 15     15   86 use warnings;
  15         23  
  15         440  
7 15     15   13437 use utf8;
  15         154  
  15         78  
8 15     15   12791 use PPI;
  15         2293611  
  15         686  
9 15     15   137 use List::Util 1.33 qw(any none);
  15         510  
  15         1572  
10 15     15   80 use Scalar::Util qw(blessed);
  15         34  
  15         737  
11 15     15   7969 use Tangerine::Hook;
  15         39  
  15         421  
12 15     15   7898 use Tangerine::Occurence;
  15         39  
  15         485  
13 15     15   77 use Tangerine::Utils qw(accessor addoccurence);
  15         25  
  15         19890  
14              
15             sub new {
16 14     14 1 141 my $class = shift;
17 14         61 my %args = @_;
18             bless {
19             _file => $args{file},
20 14   50     310 _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 119 sub file { accessor _file => @_ }
34 210     210 0 614 sub mode { accessor _mode => @_ }
35              
36 5     5 1 1403 sub package { accessor _package => @_ }
37 453     453 1 54439 sub compile { accessor _compile => @_ }
38 167     167 1 15418 sub runtime { accessor _runtime => @_ }
39             # For pre-0.15 compatibility
40             *provides = \&package;
41             *requires = \&runtime;
42             *uses = \&compile;
43              
44             sub run {
45 14     14 1 85 my $self = shift;
46 14 50       51 return 0 unless -r $self->file;
47 14 50       57 $self->mode('all')
48             unless $self->mode =~
49             /^(a(ll)?|p(ackage|rov)?|compile|d(ep)?|r(untime|eq)?|u(se)?)$/;
50 14         55 my $document = PPI::Document->new($self->file, readonly => 1);
51 14 50       122082 return 0 unless $document;
52 14 50       120 my $statements = $document->find('Statement') or return 1;
53 14         32887 my @hooks;
54 14         44 for my $type (qw(package compile runtime)) {
55 42         77 for my $hname (@{$self->{_hooks}->{$type}}) {
  42         167  
56 182         389 my $hook = "Tangerine::hook::$hname";
57 182 50       10333 if (eval "require $hook; 1") {
58 182         1739 push @hooks, $hook->new(type => $type);
59             } else {
60 0         0 warn "Couldn't load the tangerine hook `${hname}'!";
61             }
62             }
63             }
64             @hooks = grep {
65 14 50 0     346 if ($self->mode =~ /^a/o ||
  182   33     401  
      0        
      0        
      0        
      0        
66             $_->type eq 'package' && $self->mode =~ /^p/o ||
67             $_->type eq 'compile' && $self->mode =~ /^[cdu]/o ||
68             $_->type eq 'runtime' && $self->mode =~ /^[dr]/o) {
69 182         1700 $_
70             }
71             } @hooks;
72 14         41 my $children;
73             my $forcetype;
74 14         256 STATEMENT: for my $statement (@$statements) {
75 151   100     816 $children //= [ $statement->schildren ];
76 151 100 100     2537 if ($children->[1] &&
      66        
77             ($children->[1] eq ',' || $children->[1] eq '=>')) {
78 15         312 undef $children;
79             next STATEMENT
80 15         41 }
81 136         3867 for my $hook (@hooks) {
82 1811 100       5268 if (my $data = $hook->run($children)) {
83 178         493 my $modules = $data->modules;
84 178 50   165   1019 undef %$modules if any { $_ eq '->' } keys %$modules;
  165         427  
85 178         625 for my $k (keys %$modules) {
86 165 100 66     1259 if ($k !~ m/^[a-z_][a-z0-9_]*(?:::[a-z0-9_]+)*(?:::)?$/io ||
87             $k =~ m/^__[A-Z]+__$/o) {
88 8         15 delete $modules->{$k};
89             next
90 8         19 }
91 157 100       414 if (my ($class) = ($k =~ /^(.+)::$/o)) {
92             $modules->{$class} = $modules->{$k}
93 1 50       5 unless exists $modules->{$class};
94 1         3 delete $modules->{$k};
95 1         2 $k = $class
96             }
97 157         624 $modules->{$k}->line($statement->line_number);
98             }
99 178   66     873 my $type = $forcetype // $hook->type;
100 178 100       630 if ($type eq 'package') {
    100          
    50          
101 1         4 $self->package(addoccurence($self->package, $modules));
102             } elsif ($type eq 'compile') {
103 128         365 $self->compile(addoccurence($self->compile, $modules));
104             } elsif ($type eq 'runtime') {
105 49         127 $self->runtime(addoccurence($self->runtime, $modules));
106             }
107 178 100       257 if (@{$data->hooks}) {
  178         464  
108 14         28 for my $newhook (@{$data->hooks}) {
  14         42  
109 14 50 33     50 next if ($newhook->type eq 'package') && ($self->mode =~ /^[dcru]/o);
110 14 50 33     43 next if ($newhook->type eq 'runtime') && ($self->mode =~ /^[pcu]/o);
111 14 50 33     49 next if ($newhook->type eq 'compile') && ($self->mode =~ /^[pr]/o);
112             push @hooks, $newhook
113             if none {
114 191 100   191   988 blessed($newhook) eq blessed($_) &&
115             $newhook->type eq $_->type
116 14 100       89 } @hooks;
117             }
118             }
119 178 100       227 if (@{$data->children}) {
  178         468  
120 22         60 $children = $data->children;
121 22         55 $forcetype = $data->type;
122 22         126 redo STATEMENT;
123             }
124             }
125             }
126 114         300 undef $children,
127             undef $forcetype;
128             }
129 14         907 1;
130             }
131              
132             1;
133              
134             __END__