V
view release on metacpan or search on metacpan
my $pkg = shift;
print "$pkg\n";
@_ or print "\tNot found\n";
foreach my $module (@_) {
my ($versions) = $module->version;
if (@$versions > 1) {
printf "\t%s:\n", $module->file;
printf "\t %s: %s\n", $_->{pkg}, $_->{version} || '' for @$versions;
}
else {
printf "\t%s: %s\n", $module->file, $versions->[0]{version} || '?';
}
}
} # report_pkg
sub import {
shift;
@_ or push @_ => 'V';
for my $pkg (@_) {
my @modules = V::Module::Info->all_installed ($pkg);
report_pkg $pkg, @modules;
}
$NO_EXIT or exit ();
} # import
sub get_version {
my ($pkg) = @_;
my ($first) = V::Module::Info->all_installed ($pkg);
return $first ? $first->version : undef;
} # get_version
caller or V->import (@ARGV);
1;
# Okay I did the AUTOLOAD bit, but this is a Copy 'n Paste job.
# Thank you Michael Schwern for Module::Info! This one is mostly that!
package V::Module::Info;
require File::Spec;
sub new_from_file {
my ($proto, $file) = @_;
my $class = ref $proto || $proto;
-r $file and return bless {
file => File::Spec->rel2abs ($file),
dir => "",
name => "",
} => $class;
} # new_from_file
sub all_installed {
my ($proto, $name, @inc) = @_;
my $class = ref $proto || $proto;
@inc or @inc = @INC;
my $file = File::Spec->catfile (split m/::/ => $name) . ".pm";
my @modules;
foreach my $dir (@inc) {
# Skip the new code ref in @INC feature.
ref $dir and next;
my $filename = File::Spec->catfile ($dir, $file);
-r $filename or next;
my $module = $class->new_from_file ($filename);
$module->{dir} = File::Spec->rel2abs ($dir);
$module->{name} = $name;
push @modules => $module;
}
$V::DEBUG and do { print {*STDERR} "# $file: @{[scalar $_->version]}\n" for @modules };
return @modules;
} # all_installed
# Once thieved from ExtUtils::MM_Unix 1.12603
# Stealing from Module::Extract::VERSION is an option for the future
sub version {
my $self = shift;
my $parsefile = $self->file;
open my $mod, "<", $parsefile or die "open $parsefile: $!";
my $inpod = 0;
local $_;
my %eval;
my ($cur_pkg, $cur_ord) = ("main", 0);
$eval{$cur_pkg} = { ord => $cur_ord };
while (<$mod>) {
$inpod = m/^=(?!cut)/ ? 1 : m/^=cut/ ? 0 : $inpod;
$inpod || m/^\s*#/ and next;
chomp;
if (m/^\s* (?:package|class) \s+ (\w+(?:::\w+)*) /x) {
$cur_pkg = $1;
exists $eval{$cur_pkg} or
$eval{$cur_pkg} = { ord => ++$cur_ord };
}
$cur_pkg =~ m{^V::Module::Info} and next;
if (m/(?:our)?\s*([\$*])(([\w\:\']*)\bVERSION)\s*\=(?![=~])/) {
{ local ($1, $2); ($_ = $_) = m/(.*)/; } # untaint
my ($sigil, $name) = ($1, $2);
m/\$$name\s*=\s*eval.+\$$name/ and next;
m/my\s*\$VERSION\s*=/ and next;
m/^[^']*'[^']*\$$name[^']*'/ and next;
$eval{$cur_pkg}{prg} = qq{
package V::Module::Info::_version_var;
# $cur_pkg
no strict;
local $sigil$name;
\$$name = undef;
do { $_
# Closing brace needs to be on next line
( run in 1.678 second using v1.01-cache-2.11-cpan-71847e10f99 )