Commit | Line | Data |
bd645f0f |
1 | #!/usr/bin/env perl |
2 | |
3 | use warnings; |
4 | use strict; |
5 | |
6 | =head1 DESCRIPTION |
7 | |
8 | Makes sure that all of the modules that are 'use'd are listed in the |
f4b6b4d0 |
9 | Makefile.PL as dependencies. Also as long as we are source filtering, |
10 | make sure there are no $DB::single statements in the code. |
bd645f0f |
11 | |
12 | =cut |
13 | |
14 | use Test::More; |
15 | use File::Find; |
16 | eval 'use Module::CoreList'; |
17 | if ($@) { plan skip_all => 'Module::CoreList not installed' } |
18 | |
19 | plan 'no_plan'; |
20 | |
a44aaf2a |
21 | my %skipped; |
22 | if( -f 'MANIFEST.SKIP' ) { |
23 | # We don't want these |
24 | open( SKIP, 'MANIFEST.SKIP' ) or die "Could not open manifest skip file"; |
25 | while(<SKIP>) { |
26 | chomp; |
27 | $skipped{$_} = 1; |
28 | } |
29 | close SKIP; |
30 | } |
bd645f0f |
31 | my %used; |
32 | find( \&wanted, qw/ lib t / ); |
33 | |
34 | sub wanted { |
35 | return unless -f $_; |
36 | return if $File::Find::dir =~ m!/.git($|/)!; |
37 | return if $File::Find::name =~ /~$/; |
38 | return if $File::Find::name =~ /\.(pod|html)$/; |
a44aaf2a |
39 | return if $skipped{$File::Find::name}; |
bd645f0f |
40 | |
41 | # read in the file from disk |
42 | my $filename = $_; |
43 | local $/; |
44 | open( FILE, $filename ) or return; |
45 | my $data = <FILE>; |
46 | close(FILE); |
47 | |
48 | # strip pod, in a really idiotic way. Good enough though |
f4b6b4d0 |
49 | $data =~ s/^=(begin|head).+?(^=cut|\Z)//gms; |
bd645f0f |
50 | |
51 | # look for use and use base statements |
52 | $used{$1}{$File::Find::name}++ while $data =~ /^\s*use\s+([\w:]+)/gm; |
53 | while ( $data =~ m|^\s*use base qw.([\w\s:]+)|gm ) { |
54 | $used{$_}{$File::Find::name}++ for split ' ', $1; |
55 | } |
f4b6b4d0 |
56 | # look for DB statements while we are here |
57 | while( $data =~ /^\s*\$DB::single/gm ) { |
58 | fail( "DB::single statement present in source " . $File::Find::name ); |
59 | } |
bd645f0f |
60 | } |
61 | |
62 | my %required; |
63 | { |
64 | local $/; |
65 | ok( open( MAKEFILE, "Makefile.PL" ), "Opened Makefile" ); |
66 | my $data = <MAKEFILE>; |
67 | close(FILE); |
68 | while ( $data =~ /^\s*?(?:requires|recommends|).*?([\w:]+)'(?:\s*=>\s*['"]?([\d\.]+)['"]?)?.*?(?:#(.*))?$/gm ) { |
69 | $required{$1} = $2; |
70 | if ( defined $3 and length $3 ) { |
71 | $required{$_} = undef for split ' ', $3; |
72 | } |
73 | } |
74 | } |
75 | |
76 | for ( sort keys %used ) { |
77 | my $first_in = Module::CoreList->first_release($_); |
78 | next if defined $first_in and $first_in <= 5.00803; |
0ce8c0cf |
79 | next if /^(Text::Tradition|inc|t|feature|parent)(::|$)/; |
bd645f0f |
80 | |
81 | #warn $_; |
82 | ok( exists $required{$_}, "$_ in Makefile.PL" ) |
83 | or diag( "used in ", join ", ", sort keys %{ $used{$_} } ); |
84 | delete $used{$_}; |
85 | delete $required{$_}; |
86 | } |
87 | |
88 | for ( sort keys %required ) { |
89 | my $first_in = Module::CoreList->first_release( $_, $required{$_} ); |
90 | fail("Required module $_ (v. $required{$_}) is in core since $first_in") |
91 | if defined $first_in and $first_in <= 5.008003; |
92 | } |
93 | |
94 | 1; |
95 | |