line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Module::CPANTS::Kwalitee::FindModules; |
2
|
7
|
|
|
7
|
|
40526
|
use warnings; |
|
7
|
|
|
|
|
37
|
|
|
7
|
|
|
|
|
323
|
|
3
|
7
|
|
|
7
|
|
50
|
use strict; |
|
7
|
|
|
|
|
19
|
|
|
7
|
|
|
|
|
239
|
|
4
|
7
|
|
|
7
|
|
409
|
use File::Spec::Functions qw(catfile); |
|
7
|
|
|
|
|
686
|
|
|
7
|
|
|
|
|
10901
|
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
our $VERSION = '1.01'; |
7
|
|
|
|
|
|
|
$VERSION =~ s/_//; ## no critic |
8
|
|
|
|
|
|
|
|
9
|
49
|
|
|
49
|
1
|
163
|
sub order { 30 } |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
################################################################## |
12
|
|
|
|
|
|
|
# Analyse |
13
|
|
|
|
|
|
|
################################################################## |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
sub analyse { |
16
|
11
|
|
|
11
|
1
|
30
|
my $class = shift; |
17
|
11
|
|
|
|
|
19
|
my $me = shift; |
18
|
11
|
|
50
|
|
|
228
|
my $files = $me->d->{files_array} || []; |
19
|
|
|
|
|
|
|
|
20
|
11
|
50
|
66
|
|
|
226
|
if ($me->d->{meta_yml} && $me->d->{meta_yml}{provides}) { |
21
|
0
|
|
|
|
|
0
|
my $provides = $me->d->{meta_yml}{provides}; |
22
|
0
|
|
|
|
|
0
|
for my $module (sort keys %$provides) { |
23
|
0
|
|
|
|
|
0
|
my $data = $provides->{$module}; |
24
|
0
|
0
|
|
|
|
0
|
next unless ref $data eq ref {}; # ignore wrong format |
25
|
0
|
|
0
|
|
|
0
|
my $file = $data->{file} || ''; |
26
|
0
|
|
|
|
|
0
|
my $found = { |
27
|
|
|
|
|
|
|
module => $module, |
28
|
|
|
|
|
|
|
file => $file, |
29
|
|
|
|
|
|
|
in_basedir => 0, |
30
|
|
|
|
|
|
|
in_lib => 0, |
31
|
|
|
|
|
|
|
}; |
32
|
0
|
|
|
|
|
0
|
my $loc; |
33
|
0
|
0
|
|
|
|
0
|
if ($file =~ /^lib\W/) { |
|
|
0
|
|
|
|
|
|
34
|
0
|
|
|
|
|
0
|
$found->{in_lib} = 1; |
35
|
|
|
|
|
|
|
} |
36
|
|
|
|
|
|
|
elsif ($file !~ /\//) { |
37
|
0
|
|
|
|
|
0
|
$found->{in_basedir} = 1; |
38
|
|
|
|
|
|
|
} |
39
|
|
|
|
|
|
|
|
40
|
0
|
|
|
|
|
0
|
push @{$me->d->{modules}}, $found; |
|
0
|
|
|
|
|
0
|
|
41
|
0
|
0
|
|
|
|
0
|
if (exists $me->d->{files_hash}{$file}) { |
42
|
0
|
|
|
|
|
0
|
(my $path_part = $module) =~ s|::|/|g; |
43
|
0
|
0
|
|
|
|
0
|
if ($file =~ /\b$path_part\.pm$/) { |
|
|
0
|
|
|
|
|
|
44
|
0
|
|
|
|
|
0
|
$me->d->{files_hash}{$file}{module} = $module; |
45
|
|
|
|
|
|
|
} elsif ("$path_part.pm" =~ /\b$file$/) { |
46
|
0
|
|
0
|
|
|
0
|
$me->d->{files_hash}{$file}{module} ||= $module; |
47
|
|
|
|
|
|
|
} |
48
|
|
|
|
|
|
|
} else { |
49
|
0
|
|
|
|
|
0
|
$found->{not_exists} = 1; |
50
|
|
|
|
|
|
|
} |
51
|
|
|
|
|
|
|
} |
52
|
|
|
|
|
|
|
} |
53
|
|
|
|
|
|
|
else { |
54
|
11
|
|
|
|
|
161
|
my %in_basedir = map {$_ => 1} grep {/^[^\/]+\.pm$/} @$files; |
|
3
|
|
|
|
|
21
|
|
|
19
|
|
|
|
|
122
|
|
55
|
|
|
|
|
|
|
|
56
|
11
|
|
|
|
|
59
|
foreach my $file (@$files) { |
57
|
19
|
100
|
|
|
|
97
|
next unless $file =~ /\.pm$/; |
58
|
9
|
50
|
|
|
|
33
|
next if $file =~ m{^x?t/}; |
59
|
9
|
50
|
|
|
|
28
|
next if $file =~ m{^test/}; |
60
|
9
|
50
|
|
|
|
51
|
next if $file =~ m/^(bin|scripts?|ex|eg|examples?|samples?|demos?)\/\w/i; |
61
|
9
|
50
|
|
|
|
29
|
next if $file =~ m{^inc/}; # skip Module::Install stuff |
62
|
9
|
50
|
|
|
|
43
|
next if $file =~ m{^(local|perl5|fatlib)/}; |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
# proper file in lib/ |
65
|
9
|
100
|
|
|
|
52
|
if ($file =~ m|^lib/(.*)\.pm$|) { |
66
|
6
|
|
|
|
|
29
|
my $module = $1; |
67
|
6
|
|
|
|
|
37
|
$module =~ s|/|::|g; |
68
|
6
|
|
|
|
|
11
|
push (@{$me->d->{modules}}, { |
|
6
|
|
|
|
|
108
|
|
69
|
|
|
|
|
|
|
module => $module, |
70
|
|
|
|
|
|
|
file => $file, |
71
|
|
|
|
|
|
|
in_basedir => 0, |
72
|
|
|
|
|
|
|
in_lib => 1, |
73
|
|
|
|
|
|
|
}); |
74
|
6
|
|
|
|
|
161
|
$me->d->{files_hash}{$file}{module} = $module; |
75
|
|
|
|
|
|
|
} |
76
|
|
|
|
|
|
|
else { |
77
|
|
|
|
|
|
|
# open file and find first package |
78
|
3
|
|
|
|
|
32
|
my ($basename) = $file =~ /(\w+)\.pm/; |
79
|
3
|
|
|
|
|
9
|
my $module; |
80
|
3
|
|
|
|
|
6
|
my $max_lines_to_look_at = 666; |
81
|
3
|
50
|
|
|
|
83
|
open (my $fh, "<", catfile($me->distdir, $file)) or die "__PACKAGE__: Cannot open $file to find package declaration: $!"; |
82
|
3
|
|
|
|
|
183
|
while (my $line = <$fh>) { |
83
|
3
|
50
|
|
|
|
15
|
next if $line =~ /^\s*#/; # ignore comments |
84
|
3
|
50
|
|
|
|
49
|
if ($line =~ /^\s*package\s*(.*?)\s*;/) { |
85
|
3
|
|
|
|
|
14
|
$module = $1; |
86
|
3
|
50
|
33
|
|
|
39
|
last if $basename and $module =~ /\b$basename$/; |
87
|
|
|
|
|
|
|
} |
88
|
0
|
0
|
|
|
|
0
|
last if $line =~ /^__(DATA|END)__/; |
89
|
0
|
|
|
|
|
0
|
$max_lines_to_look_at--; |
90
|
0
|
0
|
|
|
|
0
|
last unless $max_lines_to_look_at; |
91
|
|
|
|
|
|
|
} |
92
|
|
|
|
|
|
|
# try to guess from filename |
93
|
3
|
50
|
|
|
|
11
|
unless ($module) { |
94
|
0
|
|
|
|
|
0
|
$file =~ m|(.*)\.pm$|; |
95
|
0
|
|
|
|
|
0
|
$module = $1; |
96
|
0
|
|
|
|
|
0
|
$module =~ s|^[a-z]+/||; # remove lowercase prefixes which most likely are not part of the distname (but something like 'src/') |
97
|
0
|
|
|
|
|
0
|
$module =~ s|/|::|g; |
98
|
|
|
|
|
|
|
} |
99
|
3
|
50
|
|
|
|
10
|
if ($module) { |
100
|
3
|
|
|
|
|
68
|
push(@{$me->d->{modules}}, { |
101
|
|
|
|
|
|
|
module => $module, |
102
|
|
|
|
|
|
|
file => $file, |
103
|
3
|
50
|
|
|
|
4
|
in_basedir => $in_basedir{$file} ? 1 : 0, |
104
|
|
|
|
|
|
|
in_lib => 0, |
105
|
|
|
|
|
|
|
}); |
106
|
3
|
|
|
|
|
106
|
$me->d->{files_hash}{$file}{module} = $module; |
107
|
|
|
|
|
|
|
} |
108
|
|
|
|
|
|
|
} |
109
|
|
|
|
|
|
|
} |
110
|
|
|
|
|
|
|
} |
111
|
|
|
|
|
|
|
|
112
|
11
|
|
|
|
|
128
|
for my $file (keys %{$me->d->{files_hash}}) { |
|
11
|
|
|
|
|
198
|
|
113
|
19
|
50
|
|
|
|
142
|
next unless $file =~ /^inc\/(.+)\.pm/; |
114
|
0
|
|
|
|
|
0
|
my $module = $1; |
115
|
0
|
|
|
|
|
0
|
$module =~ s|/|::|g; |
116
|
0
|
|
0
|
|
|
0
|
push @{$me->d->{included_modules} ||= []}, $module; |
|
0
|
|
|
|
|
0
|
|
117
|
|
|
|
|
|
|
} |
118
|
|
|
|
|
|
|
|
119
|
11
|
100
|
|
|
|
192
|
if (exists $me->d->{modules}) { |
120
|
9
|
|
|
|
|
54
|
$me->d->{modules} = [sort {$a->{module} cmp $b->{module}} @{$me->d->{modules}}]; |
|
0
|
|
|
|
|
0
|
|
|
9
|
|
|
|
|
155
|
|
121
|
|
|
|
|
|
|
} |
122
|
11
|
50
|
|
|
|
240
|
if (exists $me->d->{included_modules}) { |
123
|
0
|
|
|
|
|
0
|
$me->d->{included_modules} = [sort @{$me->d->{included_modules}}]; |
|
0
|
|
|
|
|
0
|
|
124
|
|
|
|
|
|
|
} |
125
|
|
|
|
|
|
|
|
126
|
11
|
|
|
|
|
83
|
return 1; |
127
|
|
|
|
|
|
|
} |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
################################################################## |
132
|
|
|
|
|
|
|
# Kwalitee Indicators |
133
|
|
|
|
|
|
|
################################################################## |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
sub kwalitee_indicators { |
136
|
|
|
|
|
|
|
return [ |
137
|
|
|
|
|
|
|
{ |
138
|
|
|
|
|
|
|
name => 'proper_libs', |
139
|
|
|
|
|
|
|
error => q{There is more than one .pm file in the base dir, or the .pm files are not in lib/ directory.}, |
140
|
|
|
|
|
|
|
remedy => q{Move your *.pm files in a directory named 'lib'. The directory structure should look like 'lib/Your/Module.pm' for a module named 'Your::Module'. If you need to provide additional files, e.g. for testing, that should not be considered for Kwalitee, then you should look at the 'provides' map in META.yml to limit the files scanned; or use the 'no_index' map to exclude parts of the distribution.}, |
141
|
|
|
|
|
|
|
is_extra => 1, |
142
|
|
|
|
|
|
|
code => sub { |
143
|
11
|
|
|
11
|
|
77
|
my $d = shift; |
144
|
11
|
100
|
|
|
|
23
|
my @modules = @{$d->{modules} || []}; |
|
11
|
|
|
|
|
68
|
|
145
|
11
|
100
|
|
|
|
51
|
return 1 unless @modules; |
146
|
|
|
|
|
|
|
|
147
|
9
|
|
|
|
|
23
|
my @not_in_lib = grep { !$_->{in_lib} } @modules; |
|
9
|
|
|
|
|
42
|
|
148
|
9
|
100
|
|
|
|
31
|
return 1 unless @not_in_lib; |
149
|
|
|
|
|
|
|
|
150
|
3
|
|
|
|
|
8
|
my @in_basedir = grep { $_->{in_basedir} } @not_in_lib; |
|
3
|
|
|
|
|
8
|
|
151
|
3
|
50
|
|
|
|
14
|
return 1 if @in_basedir == 1; |
152
|
|
|
|
|
|
|
|
153
|
0
|
|
|
|
|
0
|
$d->{error}{proper_libs} = join ', ', map {$_->{file}} @not_in_lib; |
|
0
|
|
|
|
|
0
|
|
154
|
|
|
|
|
|
|
|
155
|
0
|
|
|
|
|
0
|
return 0; |
156
|
|
|
|
|
|
|
}, |
157
|
|
|
|
|
|
|
details => sub { |
158
|
0
|
|
|
0
|
|
0
|
my $d = shift; |
159
|
0
|
0
|
|
|
|
0
|
my @modules = @{$d->{modules} || []}; |
|
0
|
|
|
|
|
0
|
|
160
|
0
|
0
|
|
|
|
0
|
return "No modules were found" unless @modules; |
161
|
0
|
|
|
|
|
0
|
return "The following files were found: ".$d->{error}{proper_libs}; |
162
|
|
|
|
|
|
|
}, |
163
|
|
|
|
|
|
|
}, |
164
|
|
|
|
|
|
|
{ |
165
|
|
|
|
|
|
|
name => 'no_missing_files_in_provides', |
166
|
|
|
|
|
|
|
error => q{Provides field in the META.yml lists a file that does not found in the distribution.}, |
167
|
|
|
|
|
|
|
remedy => q{Use authoring tool like Dist::Zilla, Milla, and Minilla to generate correct provides.}, |
168
|
|
|
|
|
|
|
is_extra => 1, |
169
|
|
|
|
|
|
|
code => sub { |
170
|
11
|
|
|
11
|
|
72
|
my $d = shift; |
171
|
11
|
100
|
|
|
|
18
|
my @modules = @{$d->{modules} || []}; |
|
11
|
|
|
|
|
75
|
|
172
|
11
|
100
|
|
|
|
35
|
return 1 unless @modules; |
173
|
|
|
|
|
|
|
|
174
|
9
|
50
|
|
|
|
30
|
if (my @not_exists = grep { $_->{not_exists} } @modules) { |
|
9
|
|
|
|
|
75
|
|
175
|
0
|
|
|
|
|
0
|
$d->{error}{no_missing_files_in_provides} = join ', ', map {$_->{file}} @not_exists; |
|
0
|
|
|
|
|
0
|
|
176
|
0
|
|
|
|
|
0
|
return 0; |
177
|
|
|
|
|
|
|
} |
178
|
9
|
|
|
|
|
31
|
return 1; |
179
|
|
|
|
|
|
|
}, |
180
|
|
|
|
|
|
|
details => sub { |
181
|
0
|
|
|
0
|
|
0
|
my $d = shift; |
182
|
0
|
0
|
|
|
|
0
|
my @modules = @{$d->{modules} || []}; |
|
0
|
|
|
|
|
0
|
|
183
|
0
|
0
|
|
|
|
0
|
return "No modules were found" unless @modules; |
184
|
0
|
|
|
|
|
0
|
return "The following files were missing: ".$d->{error}{no_missing_files_in_provides}; |
185
|
|
|
|
|
|
|
}, |
186
|
|
|
|
|
|
|
}, |
187
|
8
|
|
|
8
|
1
|
213
|
]; |
188
|
|
|
|
|
|
|
} |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
q{Favourite record of the moment: |
192
|
|
|
|
|
|
|
Fat Freddys Drop: Based on a true story}; |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
__END__ |