9c0a47ea1d62f44f1f817d7b1bb9bdd352de5980
5 our $VERSION = "1.02-20110904";
11 use List
::Util
qw( first );
12 use Encode
qw( encode decode );
13 use Test
::YAML
::Meta
::Version
;
14 use Test
::MinimumVersion
;
15 use Parse
::CPAN
::Meta
;
25 return bless { @_ }, $package;
30 my ($self, $src) = @_;
33 if (open my $mh, "<", "Makefile.PL") {
34 my $mf = do { local $/; <$mh> };
36 if ($mf =~ m{\b NAME \s*=>\s* ["'] (\S+) ['"]}x) {
40 if ($mf =~ m{\b VERSION_FROM \s*=>\s* ["'] (\S+) ['"]}x) {
42 -f
$from or die "Makefile wants version from nonexisten $from\n";
43 $self->{from
} //= $from;
44 $from eq $self->{from
} or die "VERSION_FROM mismatch Makefile.PL / YAML\n";
47 if ($mf =~ m
[\b PREREQ_PM \s
*=>\s
* \
{ ( [^}]+ ) \
}]x
) {
48 my @pr = split m/\n/ => $1;
49 $self->{mfpr
} = { map { (m{ \b ["']? (\S+?) ['"]? \s*=>\s* ["']? ([-0-9._]+) ['"]? }x) } grep !m/^\s*#/ => @pr };
53 $src //= $self->{from
} or croak
"No file to extract version from";
56 open my $pm, "<", $src or croak
"Cannot read $src";
58 m/^(?:our\s+)? \$VERSION \s*=\s* "? ([-0-9._]+) "? \s*;\s*$/x or next;
63 $version or croak
"Cannot extract VERSION from $src\n";
64 $self->{version
} = $version;
70 my ($self, @data) = @_;
71 $self->{version
} or $self->version_from ();
72 s/VERSION/$self->{version}/g for @data;
73 $self->{yml
} = \
@data;
81 my @tf = grep m{^(?: change | readme | .*\.pod )}ix => glob "*";
82 (my $tf = join ", " => @tf) =~ s/.*\K, / and /;
84 print "Check if $tf are still valid UTF8 ...\n";
85 foreach my $tf (@tf) {
86 open my $fh, "<", $tf or croak
"$tf: $!\n";
88 my $c = join "" => @c;
90 my $s = decode
("utf-8", $c, sub { push @e, shift; });
96 eval { decode
("utf-8", $_, 1) };
98 $@
=~ s{ at /\S+ line \d+.*}{};
99 print "$tf:$n\t$_\t$@";
101 croak
"$tf is not valid UTF-8\n";
103 my $u = encode
("utf-8", $s);
107 $n = 1; $c =~ s/^/$n++ . "\t"/gem;
108 $n = 1; $u =~ s/^/$n++ . "\t"/gem;
109 croak
"$tf: recode makes content differ\n". diff \
$c, \
$u;
117 my $yml = $self->{h
} or croak
"No YAML to check";
119 print STDERR
"Check required and recommended module versions ...\n";
120 BEGIN { $V::NO_EXIT
= $V::NO_EXIT
= 1 } require V
;
121 my %req = map { %{$yml->{$_}} } grep m/requires/ => keys %{$yml};
122 my %rec = map { %{$yml->{$_}} } grep m/recommends/ => keys %{$yml};
123 if (my $of = $yml->{optional_features
}) {
124 foreach my $f (values %{$of}) {
125 my %q = map { %{$f->{$_}} } grep m/requires/ => keys %{$f};
126 my %c = map { %{$f->{$_}} } grep m/recommends/ => keys %{$f};
127 @req{keys %q} = values %q;
128 @rec{keys %c} = values %c;
131 my %vsn = ( %req, %rec );
132 delete @vsn{qw( perl version )};
133 for (sort keys %vsn) {
134 if (my $mfv = delete $self->{mfpr
}{$_}) {
136 die "PREREQ mismatch for $_ Makefile.PL ($mfv) / YAML ($req{$_})\n";
138 $vsn{$_} eq "0" and next;
139 my $v = V
::get_version
($_);
140 $v eq $vsn{$_} and next;
141 printf STDERR
"%-35s %-6s => %s\n", $_, $vsn{$_}, $v;
143 if (my @mfpr = sort keys %{$self->{mfpr
}}) {
144 die "Makefile.PL requires @mfpr, YAML does not\n";
148 $File::Find
::dir
=~ m{^blib\b} and return;
149 $File::Find
::name
=~ m{(?:^|/)Bundle/.*\.pm} or return;
150 if (open my $bh, "<", $_) {
151 print STDERR
"Check bundle module versions $File::Find::name ...\n";
153 my ($m, $dv) = m/^([A-Za-z_:]+)\s+([0-9.]+)\s*$/ or next;
154 my $v = $m eq $self->{name
} ?
$self->{version
} : V
::get_version
($m);
156 printf STDERR
"%-35s %-6s => %s\n", $m, $dv, $v;
161 if (ref $self->{h
}{provides
}) {
162 print "Check distribution module versions ...\n";
163 foreach my $m (sort keys %{$self->{h
}{provides
}}) {
164 $m eq $self->{name
} and next;
165 my $ev = $self->{h
}{provides
}{$m}{version
};
166 printf " Expect %5s for %-32s ", $ev, $m;
167 my $fn = $self->{h
}{provides
}{$m}{file
};
168 if (open my $fh, "<", $fn) {
171 m/\bVERSION\s*=\s*["']?([-0-9.]+)/ or next;
173 print $fv eq $ev ?
"ok\n" : " mismatch, module has $1\n";
176 defined $fv or print " .. no version defined\n";
179 print " .. cannot open $fn: $!\n";
189 my @yml = @
{$self->{yml
}} or croak
"No YAML to check";
191 print STDERR
"Checking generated YAML ...\n";
193 my $yml = join "", @yml;
194 eval { $h = Load
($yml) };
196 $self->{name
} //= $h->{name
};
197 $self->{name
} eq $h->{name
} or die "NAME mismatch Makefile.PL / YAML\n";
198 $self->{name
} =~ s/-/::/g;
199 print STDERR
"Checking for $self->{name}-$self->{version}\n";
201 $self->{verbose
} and print Dump
$h;
203 my $t = Test
::YAML
::Meta
::Version
->new (yaml
=> $h);
205 croak
join "\n", "Test::YAML::Meta reported failure:", $t->errors, "";
207 eval { Parse
::CPAN
::Meta
::Load
($yml) };
211 $self->{yaml
} = $yml;
217 my $reqv = $self->{h
}{requires
}{perl
};
221 if (ref $_ eq "ARRAY") {
222 $locs = { paths
=> $_ };
224 elsif (ref $_ eq "HASH") {
231 my $paths = (join ", " => @
{($locs // {})->{paths
} // []}) || "default paths";
233 $reqv or croak
"No minimal required version for perl";
234 print "Checking if $reqv is still OK as minimal version for $paths\n";
235 # All other minimum version checks done in xt
236 all_minimum_version_ok
($reqv, $locs);
242 print @
{$self->{yml
}};
249 my @my = glob <*/META
.yml
> or croak
"No META files";
252 @my == 1 && open my $my, ">", $yf or croak
"Cannot update $yf\n";
253 print $my @
{$self->{yml
}};
257 my $jsn = $self->{h
};
258 $jsn->{"meta-spec"} = {
260 url
=> "https://metacpan.org/module/CPAN::Meta::Spec?#meta-spec",
262 open $my, ">", $yf or croak
"Cannot update $yf\n";
263 print $my JSON
->new->utf8 (1)->pretty (1)->encode ($jsn);
265 chmod 0644, glob "*/META.*";