Commit | Line | Data |
---|---|---|
c8aeb9c6 A |
1 | #!./perl -w |
2 | ||
3 | # | |
4 | # Compare the current Perl source tree and a given tag for modules that | |
5 | # have identical version numbers but different contents. | |
6 | # | |
7 | # Original by slaven@rezic.de, modified by jhi and matt.w.johnson@gmail.com | |
8 | # | |
9 | # Adapted from Porting/cmpVERSION.pl by Abigail | |
10 | # | |
11 | ||
12 | BEGIN { | |
13 | chdir '..' unless -d 't'; | |
14 | unshift @INC, 'lib', 'Porting'; | |
15 | } | |
16 | ||
17 | use strict; | |
18 | use warnings; | |
19 | use version; | |
20 | use ExtUtils::MakeMaker; | |
21 | use File::Compare; | |
22 | use File::Find; | |
23 | use File::Spec::Functions qw(rel2abs abs2rel catfile catdir curdir); | |
24 | use Getopt::Std; | |
25 | use Maintainers; | |
26 | ||
27 | if (! -d '.git' ) { | |
28 | print "1..0 # SKIP: not being run from a git checkout\n"; | |
29 | exit 0; | |
30 | } | |
31 | ||
32 | # | |
3d92e8b1 | 33 | # Thanks to David Golden for this suggestion. |
c8aeb9c6 | 34 | # |
3d92e8b1 A |
35 | my $tag_to_compare = `git describe --abbrev=0`; |
36 | chomp $tag_to_compare; | |
c8aeb9c6 A |
37 | my $source_dir = '.'; |
38 | ||
39 | my $null = $^O eq 'MSWin32' ? 'nul' : '/dev/null'; | |
40 | ||
41 | my $tag_exists = `git --no-pager tag -l $tag_to_compare 2>$null`; | |
42 | chomp $tag_exists; | |
43 | ||
44 | ||
45 | if ($tag_exists ne $tag_to_compare) { | |
46 | print "1..0 # SKIP: '$tag_to_compare' is not a known Git tag\n"; | |
47 | exit 0; | |
48 | } | |
49 | ||
50 | ||
51 | my %dual_files; | |
52 | for my $m (grep $Maintainers::Modules {$_} {CPAN}, keys %Maintainers::Modules) { | |
53 | $dual_files{$_} = 1 for Maintainers::get_module_files ($m); | |
54 | } | |
55 | ||
56 | ||
57 | # Files to skip from the check for one reason or another, | |
58 | # usually because they pull in their version from some other file. | |
59 | my %skip; | |
60 | @skip{ | |
61 | 'lib/Carp/Heavy.pm', | |
62 | 'lib/Config.pm', # no version number but contents will vary | |
63 | 'lib/Exporter/Heavy.pm', | |
64 | 'win32/FindExt.pm', | |
65 | } = (); | |
b722085f | 66 | my $skip_dirs = qr{^(?:t/lib|cpan)}; |
c8aeb9c6 A |
67 | |
68 | my @all_diffs = `git --no-pager diff --name-only $tag_to_compare`; | |
69 | chomp @all_diffs; | |
70 | ||
0e75e33f | 71 | my @tmp_diffs = grep { |
c8aeb9c6 A |
72 | my $this_dir; |
73 | $this_dir = $1 if m/^(.*)\//; | |
74 | /\.pm$/ && | |
75 | (!defined($this_dir) || ($this_dir !~ $skip_dirs)) && | |
0e75e33f | 76 | !exists $skip{$_}; |
c8aeb9c6 | 77 | } @all_diffs; |
0e75e33f A |
78 | my @module_diffs = grep {!exists $dual_files {$_}} @tmp_diffs; |
79 | push @module_diffs => grep { exists $dual_files {$_}} @tmp_diffs; | |
c8aeb9c6 A |
80 | |
81 | unless (@module_diffs) { | |
82 | print "1..1\n"; | |
83 | print "ok 1 - No difference found\n"; | |
84 | exit; | |
85 | } | |
86 | ||
87 | my (@output_files, @output_diffs); | |
88 | ||
89 | printf "1..%d\n" => scalar @module_diffs; | |
90 | ||
91 | my $count = 0; | |
92 | my @diff; | |
93 | foreach my $pm_file (@module_diffs) { | |
94 | @diff = (); | |
95 | (my $xs_file = $pm_file) =~ s/\.pm$/.xs/; | |
96 | my $pm_eq = compare_git_file($pm_file, $tag_to_compare); | |
97 | next unless defined $pm_eq; | |
98 | my $xs_eq = 1; | |
99 | if (-e $xs_file) { | |
100 | $xs_eq = compare_git_file($xs_file, $tag_to_compare); | |
101 | next unless defined $xs_eq; | |
102 | } | |
103 | next if ($pm_eq && $xs_eq); | |
104 | my $pm_version = eval {MM->parse_version($pm_file)}; | |
105 | my $orig_pm_content = get_file_from_git($pm_file, $tag_to_compare); | |
106 | my $orig_pm_version = eval {MM->parse_version(\$orig_pm_content)}; | |
107 | next if ( ! defined $pm_version || ! defined $orig_pm_version ); | |
108 | next if ( $pm_version eq 'undef' || $orig_pm_version eq 'undef' ); # sigh | |
109 | next if $pm_version ne $orig_pm_version; | |
110 | push @diff => $pm_file unless $pm_eq; | |
111 | push @diff => $xs_file unless $xs_eq; | |
112 | } | |
113 | continue { | |
114 | if (@diff) { | |
115 | foreach my $diff (@diff) { | |
116 | print "# $_" for `git --no-pager diff $tag_to_compare '$diff'`; | |
117 | } | |
118 | printf "not ok %d - %s\n" => ++ $count, $pm_file; | |
119 | } | |
120 | else { | |
121 | printf "ok %d - %s\n" => ++ $count, $pm_file; | |
122 | } | |
123 | } | |
124 | ||
125 | exit; | |
126 | ||
127 | sub compare_git_file { | |
128 | my ($file, $tag) = @_; | |
129 | open(my $orig_fh, "-|", "git --no-pager show $tag:$file 2>$null"); | |
130 | return undef if eof($orig_fh); | |
131 | my $is_eq = compare($file, $orig_fh) == 0; | |
132 | close($orig_fh); | |
133 | return $is_eq; | |
134 | } | |
135 | ||
136 | sub get_file_from_git { | |
137 | my ($file, $tag) = @_; | |
138 | local $/ = undef; | |
139 | my $file_content = `git --no-pager show $tag:$file 2>$null`; | |
140 | return $file_content; | |
141 | } |