App-DocKnot
view release on metacpan or search on metacpan
t/lib/Test/RRA/ModuleVersion.pm view on Meta::CPAN
our $REGEX_VERSION_PACKAGE = qr{
( # prefix ($1)
\A \s* # whitespace
package \s+ # package keyword
[\w\:\']+ \s+ # package name
)
( v? [\d._]+ ) # the version number itself ($2)
( # suffix ($3)
\s* ;
)
}xms;
# Find all the Perl modules shipped in this package, if any, and returns the
# list of file names.
#
# $dir - The root directory to search
#
# Returns: List of file names
sub _module_files {
my ($dir) = @_;
return if !-d $dir;
my @files;
my %ignore = map { $_ => 1 } @MODULE_VERSION_IGNORE;
my $wanted = sub {
if ($_ eq 'blib') {
$File::Find::prune = 1;
return;
}
if (m{ [.] pm \z }xms && !$ignore{$File::Find::name}) {
push(@files, $File::Find::name);
}
return;
};
find($wanted, $dir);
return @files;
}
# Given a module file, read it for the version value and return the value.
#
# $file - File to check, which should be a Perl module
#
# Returns: The version of the module
# Throws: Text exception on I/O failure or inability to find version
sub _module_version {
my ($file) = @_;
open(my $data, q{<}, $file);
while (defined(my $line = <$data>)) {
if ($line =~ $REGEX_VERSION_PACKAGE) {
my ($prefix, $version, $suffix) = ($1, $2, $3);
close($data);
return $version;
}
}
close($data);
die "$0: cannot find version number in $file\n";
}
# Given a module file and the new version for that module, update the version
# in that module to the new one.
#
# $file - Perl module file whose version should be updated
# $version - The new version number
#
# Returns: undef
# Throws: Text exception on I/O failure or inability to find version
sub _update_module_version {
my ($file, $version) = @_;
# Scan for the version and replace it.
open(my $in, q{<}, $file);
open(my $out, q{>}, "$file.new");
SCAN:
while (defined(my $line = <$in>)) {
if ($line =~ s{ $REGEX_VERSION_PACKAGE }{$1$version$3}xms) {
print {$out} $line or die "$0: cannot write to $file.new: $!\n";
last SCAN;
}
print {$out} $line or die "$0: cannot write to $file.new: $!\n";
}
# Copy the rest of the input file to the output file.
print {$out} <$in> or die "$0: cannot write to $file.new: $!\n";
close($out);
close($in);
# All done. Rename the new file over top of the old file.
rename("$file.new", $file);
return;
}
# Act as a test suite. Find all of the Perl modules under the provided root,
# if any, and check that the version for each module matches the version.
# Reports results with Test::More and sets up a plan based on the number of
# modules found.
#
# $root - Directory under which to look for Perl modules
# $version - The version all those modules should have
#
# Returns: undef
# Throws: Text exception on fatal errors
sub test_module_versions {
my ($root, $version) = @_;
my @modules = _module_files($root);
# Output the plan. Skip the test if there were no modules found.
if (@modules) {
plan tests => scalar(@modules);
} else {
plan skip_all => 'No Perl modules found';
return;
}
# For each module, get the module version and compare.
for my $module (@modules) {
my $module_version = _module_version($module);
is($module_version, $version, "Version for $module");
}
return;
}
# Update the versions of all modules to the current distribution version.
( run in 1.012 second using v1.01-cache-2.11-cpan-39bf76dae61 )