Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

If I had a list of module files, how could I find out the latest version numbers of those modules on cpan? I want to do this from a (non-command line) program. And I want to skip any pragmas that may be in the list. Thanks.

Replies are listed 'Best First'.
Re: Grabbing info from cpan
by Anonymous Monk on Jul 23, 2008 at 04:58 UTC
Re: Grabbing info from cpan
by Khen1950fx (Canon) on Jul 23, 2008 at 05:00 UTC
      Nope, pmvers doesn't fetch the list of latest modules from CPAN
Re: Grabbing info from cpan
by Anonymous Monk on Jul 23, 2008 at 04:53 UTC
    pragmas are named all lower-case, so just grep those out

    command line is irrelevant.

Re: Grabbing info from cpan
by leocharre (Priest) on Jul 23, 2008 at 05:11 UTC

    What did you mean by non-command line? As in .. Did you mean you want a perl API ish way to go about this? If you're on posix/unixy variants, why would you want to avoid systemy calls? "Purity"? One philosophy of *ix is many small programs working together to do wonderful things. I forget that a lot myself.

    Maybe you are trying to keep some modules current?
    If so, what makes you so sure that just because a module has been updated on cpan- you should upgrade? Just a thought..

    I would imagine checking the test results *and* version numbers might be useful. If the current version on your machine shows 9/10 pass, and the new version shows 0/23- maybe upgrading is iffy.

    (Maybe it's time for a auto perl module /cpan thingie update? Might be out there.)

    Just throwing some thoughts out there..

Re: Grabbing info from cpan
by broomduster (Priest) on Jul 23, 2008 at 08:53 UTC
    Somewhere in my collection of unfinished Perl code, is a script that does something similar. My approach was to download http://www.cpan.org/modules/01modules.index.html, then use HTML::Parser to extract the good stuff. As I recall, some "creative" parsing of the module names is required because the formats vary slightly. Comparing the versions from the list to the versions installed is also challenging, as different authors use different approaches to version bumping.
Re: Grabbing info from cpan
by leocharre (Priest) on Jul 28, 2008 at 17:49 UTC

    WWW:CPAN is insteresting.. the deps are daunting.. well.. it just seems like a *lot* just to get a freaking version number from cpan..

    Ok.. here's some scripting I have for myself.. Consists of 3 parts, one that checks version installed, one that checks version on cpan, and one that compares versions and optionally ass or/or installs new versions..

    CAVEAT, these work and are cute.. and they are hacks.

    pmver

    #!/usr/bin/perl use strict; use base 'LEOCHARRE::CLI'; my $o = gopts('r'); scalar @ARGV or die('missing modules args'); my $manymods = scalar @ARGV > 1 ? 1 : 0; map { do_one($_) } @ARGV; sub usage { return qq{ $0 - what version of a perl module is installed DESCRIPTION If the moduoe version cannot be determined it returns 0, if the module is not present, returns undef. OPTION FLAGS -r round off things like 2.15, 0.345, and v5.4.4 to 2, 0, and 5 -d debug h- help USAGE EXAMPLES $0 CPAN $0 Cwd SEE ALSO LEOCHARRE::Dev }; } sub do_one { my $modname = shift; debug("modname $modname"); my $ver; no strict 'refs'; if ( eval "require $modname" ){ debug($modname); #require $modname; $ver = ${"$modname\:\:VERSION"}; defined $ver or debug("$modname is installed but can't set versi +on via module."); } #`perl -M$mod -e "print \$$mod::VERSION" else { debug("$modname not installed on this system."); $ver = ''; } if ($o->{r} and $ver){ $ver=~s/^v//; $ver=~s/\..+$//; } defined $ver or $ver =0; if ( $manymods ){ print "$modname $ver\n"; } else { print $ver } }

    pmvercpan

    #!/usr/bin/perl use strict; use base 'LEOCHARRE::CLI'; use WWW::CPAN; use Smart::Comments '###'; my $o = gopts('V'); @ARGV or die('missing arg'); my $cpan = WWW::CPAN->new; my @v = map { get_cpan_version($_) } @ARGV; print join("\n",@v); sub usage { return qq{$0 - get module versions from cpan OPTION FLAGS -V verbose, print meta info to stdout SEE ALSO LEOCHARRE::Dev }; } sub get_cpan_version { my $dist = shift; $dist or die('missing arg'); my $distname = _arg2distname($dist) or die; my $meta = $cpan->fetch_distmeta({ dist => $distname}) or print STDERR "cant fetch dist meta for $distname\n" and return ''; if( $o->{V} ){ ### $meta } my $version = $meta->{version} or print STDERR "cant get version number for $distname\n" and return ''; return $version; } sub _arg2distname { my $arg = shift; my $namechars = qr/[a-zA-Z0-9]/; my $distchars = qr/[a-zA-Z0-9\:\-\.]/; $arg=~/^$distchars+$/ or die("argument $arg doesn't look like a dis +tro name"); $arg=~s/\:\:/\-/g; return $arg; }

    pmverstatus

    #!/usr/bin/perl use strict; use base 'LEOCHARRE::CLI'; use vars qw(@MODULES); my $o = gopts('m:uaV'); @MODULES = @ARGV; (push @MODULES, $o->{m}) if $o->{m}; if ($o->{a}){ print join( "\n", @INC); } if ($o->{a}){ for my $inc (@INC){ print STDERR "looking in $inc ..\n"; my @got = find_modules_in($inc) or print STDERR "none found.\n"; printf STDERR "found %s modules.\n", scalar @got; push @MODULES, @got; } } scalar @MODULES or die("no modules arg"); printf STDERR "Testing for %s module total.. \n", scalar @MODULES; sub find_modules_in { my $dir = shift; my @modnames; for my $path ( split( /\n/, `find '$dir' -type f -name "*.pm"`) ){ $path=~s/^$dir\/+//; $path=~s/\//\:\:/g; $path=~s/\.pm$//; push @modnames, $path; } return @modnames; } for my $modname ( @MODULES ){ my($vold, $vnew); unless( ($vold, $vnew) = is_update_available($modname) ){ print STDERR "$modname, no update found.\n" if DEBUG; print STDERR "." if $o->{V}; next; } print STDERR "$modname $vold, update $vnew found.\n"; $o->{u} or next; unless( $o->{f} ){ # no force? yn("Would you like to update?") or next; } system('cpan', $modname) ==0 or warn("could not update $modname") and next; } sub is_update_available { my $modname = shift; my $v_installed = `pmver $modname 2>/dev/null`; $v_installed=~s/^\s+|\s+$//g; unless( defined $v_installed ){ print STDERR "$modname installed, missing version\n"; return; } my $v_cpan = `pmvercpan $modname 2>/dev/null`; $v_cpan=~s/^\s+|\s+$//g; unless( defined $v_cpan ){ print STDERR "$modname on cpan, missing version\n"; return; } if ( $v_installed < $v_cpan ){ return ($v_installed, $v_cpan); } return; } sub usage { return qq{ $0 - check status of perl modules installed against versions on cpan OPTION FLAGS -a all modules -u auto update modules -V verbose ARGUMENTS -m module name to check -b base dir to check modules from SEE ALSO LEOCHARRE::Dev USAGE $0 -ua }; }

    Tested these out adn it's very cute. It's running through every one of my installed modules and propmting me to update if it finds a newer ver on cpan. :-)