Script to update some modules

I have some modules which I need to periodically install on a web server, and cannot use cpan or cpanm to do this. One of the problems with this is that the local copies I made of the modules sometimes get out of date with the CPAN version. The following script updates the local copies of the modules. This uses make_regex from Convert::Moji to make a matching regex for a list of modules, but you can use list2re from Data::Munge in place of that.

# Check whether there are newer versions of the modules on the web
# site.

use warnings;
use strict;
use utf8;
use FindBin '$Bin';
my $updatedir = '/some/dir/or/another';
# This just runs "system" and checks the return value.
use Deploy 'do_system';
use Convert::Moji 'make_regex';
use File::Slurper 'read_text';
use version;
my @modules = <$updatedir/*.tar.gz>;
my %mods;
for my $module (@modules) {
    $module =~ s!.*/!!;
    my $mod;
    my $version;

    my @mods;
    if ($module =~ /([\w-]+)-([0-9\.]+)\./) {
        $mod = $1;
        $version = $2;
    }
    else {
        warn "no version in $module";
        next;
    }
    $mod =~ s/-/::/g;
    $version = version->declare ($version)->numify ();
    $mods{$mod} = $version;
}
my $re = make_regex (keys %mods);
my $file = '02packages.details.txt';
if (! -f $file || -M $file > 1) {
    do_system ("wget http://www.cpan.org/modules/$file.gz;gzip -d $file.gz");
}
my $cpan = read_text ($file);
my @cpan = split /\n/, $cpan;
for (@cpan) {
    if (/^$re\s+([0-9\._-]+)\s+(\S+)/) {
        my $match = $1;
        my $cpanv = $2;
        my $download = $3;
        $cpanv = version->declare ($cpanv)->numify ();
        print "Found $match version $cpanv\n";
        if ($cpanv > $mods{$match}) {
            print "UPDATE THIS ONE $_.\n";
            chdir $updatedir or die $!;
            do_system ("wget https://cpan.metacpan.org/authors/id/$download");
            chdir $Bin or die $!;
        }
    }    
}

Leave a comment

About Ben Bullock

user-pic I blog about Perl.