line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Test::DistManifest; |
2
|
|
|
|
|
|
|
{ |
3
|
|
|
|
|
|
|
$Test::DistManifest::VERSION = '1.012'; |
4
|
|
|
|
|
|
|
} |
5
|
|
|
|
|
|
|
# ABSTRACT: Author test that validates a package MANIFEST |
6
|
|
|
|
|
|
|
|
7
|
4
|
|
|
4
|
|
89533
|
use strict; |
|
4
|
|
|
|
|
11
|
|
|
4
|
|
|
|
|
146
|
|
8
|
4
|
|
|
4
|
|
23
|
use warnings; |
|
4
|
|
|
|
|
8
|
|
|
4
|
|
|
|
|
114
|
|
9
|
4
|
|
|
4
|
|
22
|
use Carp (); |
|
4
|
|
|
|
|
12
|
|
|
4
|
|
|
|
|
74
|
|
10
|
4
|
|
|
4
|
|
4305
|
use ExtUtils::Manifest; |
|
4
|
|
|
|
|
56959
|
|
|
4
|
|
|
|
|
1658
|
|
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
# File management commands |
14
|
4
|
|
|
4
|
|
379
|
use Cwd (); |
|
4
|
|
|
|
|
9
|
|
|
4
|
|
|
|
|
261
|
|
15
|
4
|
|
|
4
|
|
24
|
use File::Spec; # Portability |
|
4
|
|
|
|
|
11
|
|
|
4
|
|
|
|
|
263
|
|
16
|
4
|
|
|
4
|
|
220
|
use File::Spec::Unix; # To get UNIX-style paths |
|
4
|
|
|
|
|
8
|
|
|
4
|
|
|
|
|
494
|
|
17
|
4
|
|
|
4
|
|
209
|
use File::Find (); # Traverse the filesystem tree |
|
4
|
|
|
|
|
11
|
|
|
4
|
|
|
|
|
272
|
|
18
|
|
|
|
|
|
|
|
19
|
4
|
|
|
4
|
|
4240
|
use Module::Manifest; |
|
4
|
|
|
|
|
21853
|
|
|
4
|
|
|
|
|
128
|
|
20
|
4
|
|
|
4
|
|
1342
|
use Test::Builder; |
|
4
|
|
|
|
|
11566
|
|
|
4
|
|
|
|
|
483
|
|
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
my $test = Test::Builder->new; |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
my @EXPORTS = ( |
25
|
|
|
|
|
|
|
'manifest_ok', |
26
|
|
|
|
|
|
|
); |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
# These platforms were copied from File::Spec |
29
|
|
|
|
|
|
|
my %platforms = ( |
30
|
|
|
|
|
|
|
MacOS => 1, |
31
|
|
|
|
|
|
|
MSWin32 => 1, |
32
|
|
|
|
|
|
|
os2 => 1, |
33
|
|
|
|
|
|
|
VMS => 1, |
34
|
|
|
|
|
|
|
epoc => 1, |
35
|
|
|
|
|
|
|
NetWare => 1, |
36
|
|
|
|
|
|
|
symbian => 1, |
37
|
|
|
|
|
|
|
dos => 1, |
38
|
|
|
|
|
|
|
cygwin => 1, |
39
|
|
|
|
|
|
|
); |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
# Looking at other Test modules this seems to be an ad-hoc standard |
42
|
|
|
|
|
|
|
sub import { |
43
|
4
|
|
|
4
|
|
48
|
my ($self, @plan) = @_; |
44
|
4
|
|
|
|
|
14
|
my $caller = caller; |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
{ |
47
|
4
|
|
|
4
|
|
27
|
no strict 'refs'; |
|
4
|
|
|
|
|
8
|
|
|
4
|
|
|
|
|
3357
|
|
|
4
|
|
|
|
|
4
|
|
48
|
4
|
|
|
|
|
12
|
for my $func (@EXPORTS) { |
49
|
4
|
|
|
|
|
7
|
*{$caller . '::' . $func} = \&{$func}; |
|
4
|
|
|
|
|
36
|
|
|
4
|
|
|
|
|
13
|
|
50
|
|
|
|
|
|
|
} |
51
|
|
|
|
|
|
|
} |
52
|
|
|
|
|
|
|
|
53
|
4
|
|
|
|
|
27
|
$test->exported_to($caller); |
54
|
4
|
|
|
|
|
49
|
$test->plan(@plan); |
55
|
4
|
|
|
|
|
1526
|
return; |
56
|
|
|
|
|
|
|
} |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
sub manifest_ok { |
60
|
8
|
|
100
|
8
|
1
|
19690
|
my $warn_only = $ENV{MANIFEST_WARN_ONLY} || 0; |
61
|
|
|
|
|
|
|
|
62
|
8
|
|
100
|
|
|
37
|
my $manifile = shift || 'MANIFEST'; |
63
|
8
|
|
100
|
|
|
44
|
my $skipfile = shift || 'MANIFEST.SKIP'; |
64
|
|
|
|
|
|
|
|
65
|
8
|
|
|
|
|
225
|
my $root = Cwd::getcwd(); # this is Build.PL's Cwd |
66
|
8
|
|
|
|
|
87
|
my $manifest = Module::Manifest->new; |
67
|
|
|
|
|
|
|
|
68
|
8
|
100
|
|
|
|
167
|
unless ($test->has_plan) { |
69
|
1
|
|
|
|
|
24
|
$test->plan(tests => 4); |
70
|
|
|
|
|
|
|
} |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
# Try to parse the MANIFEST and MANIFEST.SKIP files |
73
|
8
|
|
|
|
|
266
|
eval { |
74
|
8
|
|
|
|
|
278
|
$manifest->open(manifest => $manifile); |
75
|
|
|
|
|
|
|
}; |
76
|
8
|
100
|
|
|
|
3638
|
if ($@) { |
77
|
2
|
|
|
|
|
35
|
$test->diag($!); |
78
|
|
|
|
|
|
|
} |
79
|
8
|
|
|
|
|
375
|
$test->ok(!$@, 'Parse MANIFEST or equivalent'); |
80
|
|
|
|
|
|
|
|
81
|
8
|
|
|
|
|
3883
|
eval { |
82
|
8
|
|
|
|
|
36
|
$manifest->open(skip => $skipfile); |
83
|
|
|
|
|
|
|
}; |
84
|
8
|
50
|
|
|
|
4986
|
if ($@) { |
85
|
0
|
|
|
|
|
0
|
$test->diag('Unable to parse MANIFEST.SKIP file:'); |
86
|
0
|
|
|
|
|
0
|
$test->diag($!); |
87
|
0
|
|
|
|
|
0
|
$test->diag('Using default skip data from ExtUtils::Manifest ' . ExtUtils::Manifest->VERSION); |
88
|
|
|
|
|
|
|
|
89
|
0
|
0
|
|
|
|
0
|
open my $fh, '<', $ExtUtils::Manifest::DEFAULT_MSKIP |
90
|
|
|
|
|
|
|
or die "Cannot open $ExtUtils::Manifest::DEFAULT_MSKIP: $!"; |
91
|
0
|
|
|
|
|
0
|
chomp(my @manifest_content = <$fh>); |
92
|
0
|
|
|
|
|
0
|
$manifest->parse( skip => \@manifest_content ); |
93
|
|
|
|
|
|
|
} |
94
|
|
|
|
|
|
|
|
95
|
8
|
|
|
|
|
19
|
my @files; |
96
|
|
|
|
|
|
|
# Callback function called by File::Find |
97
|
|
|
|
|
|
|
my $closure = sub { |
98
|
|
|
|
|
|
|
# Trim off the package root to determine the relative path. |
99
|
516
|
|
|
516
|
|
46033
|
my $path = File::Spec->abs2rel($File::Find::name, $root); |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
# Portably deal with different OSes |
102
|
516
|
50
|
|
|
|
6361
|
if ($platforms{$^O}) { # Check if we are on a non-Unix platform |
103
|
|
|
|
|
|
|
# Get path info from File::Spec, split apart |
104
|
0
|
|
|
|
|
0
|
my (undef, $dir, $file) = File::Spec->splitpath($path); |
105
|
0
|
|
|
|
|
0
|
my @dir = File::Spec->splitdir($dir); |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
# Reconstruct the path in Unix-style |
108
|
0
|
|
|
|
|
0
|
$dir = File::Spec::Unix->catdir(@dir); |
109
|
0
|
|
|
|
|
0
|
$path = File::Spec::Unix->catpath(undef, $dir, $file); |
110
|
|
|
|
|
|
|
} |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
# Test that the path is a file and then make sure it's not skipped |
113
|
516
|
100
|
100
|
|
|
13648
|
if (-f $path && !$manifest->skipped($path)) { |
114
|
182
|
|
|
|
|
80261
|
push @files, $path; |
115
|
|
|
|
|
|
|
} |
116
|
516
|
|
|
|
|
79305
|
return; |
117
|
8
|
|
|
|
|
66
|
}; |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
# Traverse the directory recursively |
120
|
8
|
|
|
|
|
903
|
File::Find::find({ |
121
|
|
|
|
|
|
|
wanted => $closure, |
122
|
|
|
|
|
|
|
untaint => 1, |
123
|
|
|
|
|
|
|
no_chdir => 1, |
124
|
|
|
|
|
|
|
}, $root); |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
# The two arrays have no duplicates. Thus we loop through them and |
127
|
|
|
|
|
|
|
# add the result to a hash. |
128
|
8
|
|
|
|
|
37
|
my %seen; |
129
|
|
|
|
|
|
|
# Allocate buckets for the hash |
130
|
8
|
|
|
|
|
44
|
keys(%seen) = 2 * scalar(@files); |
131
|
8
|
|
|
|
|
52
|
foreach my $path (@files, $manifest->files) { |
132
|
304
|
|
|
|
|
698
|
$seen{$path}++; |
133
|
|
|
|
|
|
|
} |
134
|
|
|
|
|
|
|
|
135
|
8
|
|
|
|
|
26
|
my $flag = 1; |
136
|
8
|
|
|
|
|
19
|
foreach my $path (@files) { |
137
|
|
|
|
|
|
|
# Skip the path if it was seen twice (the expected condition) |
138
|
182
|
100
|
|
|
|
13790
|
next if ($seen{$path} == 2); |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
# Oh no, we have files in @files not in $manifest->files |
141
|
72
|
100
|
|
|
|
168
|
if ($flag == 1) { |
142
|
4
|
|
|
|
|
32
|
$test->diag('Distribution files are missing in MANIFEST:'); |
143
|
4
|
|
|
|
|
623
|
$flag = 0; |
144
|
|
|
|
|
|
|
} |
145
|
72
|
|
|
|
|
210
|
$test->diag($path); |
146
|
|
|
|
|
|
|
} |
147
|
8
|
|
100
|
|
|
261
|
$test->ok($warn_only || $flag, 'All files are listed in MANIFEST or ' . |
148
|
|
|
|
|
|
|
'skipped'); |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
# Reset the flag and test $manifest->files now |
151
|
8
|
|
|
|
|
3741
|
$flag = 1; |
152
|
8
|
|
|
|
|
22
|
my @circular = (); # for detecting circular logic |
153
|
8
|
|
|
|
|
38
|
foreach my $path ($manifest->files) { |
154
|
|
|
|
|
|
|
# Skip the path if it was seen twice (the expected condition) |
155
|
122
|
100
|
|
|
|
1619
|
next if ($seen{$path} == 2); |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
# If the file should exist but is passed by MANIFEST.SKIP, we have |
158
|
|
|
|
|
|
|
# a strange circular logic condition. |
159
|
12
|
100
|
|
|
|
39
|
if ($manifest->skipped($path)) { |
160
|
2
|
|
|
|
|
66
|
push (@circular, $path); |
161
|
2
|
|
|
|
|
6
|
next; |
162
|
|
|
|
|
|
|
} |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
# Oh no, we have files in $manifest->files not in @files |
165
|
10
|
100
|
|
|
|
3063
|
if ($flag == 1) { |
166
|
2
|
|
|
|
|
10
|
$test->diag('MANIFEST lists the following missing files:'); |
167
|
2
|
|
|
|
|
158
|
$flag = 0; |
168
|
|
|
|
|
|
|
} |
169
|
10
|
|
|
|
|
33
|
$test->diag($path); |
170
|
|
|
|
|
|
|
} |
171
|
8
|
|
100
|
|
|
219
|
$test->ok($warn_only || $flag, 'All files listed in MANIFEST exist ' . |
172
|
|
|
|
|
|
|
'on disk'); |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
# Test for circular dependencies |
175
|
8
|
100
|
|
|
|
3017
|
$flag = (scalar @circular == 0) ? 1 : 0; |
176
|
8
|
100
|
|
|
|
33
|
if (not $flag) { |
177
|
2
|
|
|
|
|
11
|
$test->diag('MANIFEST and MANIFEST.SKIP have circular dependencies:'); |
178
|
2
|
|
|
|
|
180
|
foreach my $path (@circular) { |
179
|
2
|
|
|
|
|
12
|
$test->diag($path); |
180
|
|
|
|
|
|
|
} |
181
|
|
|
|
|
|
|
} |
182
|
8
|
|
|
|
|
180
|
$test->ok($flag, 'No files are in both MANIFEST and MANIFEST.SKIP'); |
183
|
|
|
|
|
|
|
|
184
|
8
|
|
|
|
|
3474
|
return; |
185
|
|
|
|
|
|
|
} |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
1; |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
__END__ |