In this article I describe my approach to keeping my Perl installation in $HOME/perl5 current.
I use Git to track my Perl installation, so I can easily revert misbehaving modules and/or dependency chains, and keep track of which modules I have installed or upgraded over a period of time.
On a new machine, I install perl using App::perlbrew, and then use cpanm to quickly install modules.
My setup consists of two scripts: install-my-modules.pl and install-outdated.
This script takes a list of modules as argument, and for each of them tries to install them. If installed, it commits everything to the Git repository. If the install isn't successful, it dies.
#!/usr/bin/env perl use strict; use warnings; # List of previously installed modules was created with: # perldoc -o text perllocal | grep '"Module"' | cut -d'"' -f3 | cut -d' ' -f2 my $installed = shift; $installed = "$ENV{HOME}/perl-installed-20100908-1917.txt" unless defined $installed; print "Using modules list from $installed\n"; my @modules; { open my $f, '<', $installed or die "Cannot open $installed: $!"; @modules = <$f>; close $f; chomp @modules; } # preserving order my @unique_modules; { my %marker; for my $module ( @modules ) { push @unique_modules, $module if !defined $marker{$module}; $marker{$module}++; } } for my $modulename ( @unique_modules ) { print "Installing $modulename...\n"; my $rc = system("cpanm",$modulename); if ( $rc ) { print "Errors found while installing $modulename; aborting\n"; exit $rc } print "Installed $modulename\n"; system(qw/git add ./); system(qw/git commit -am/, "Installed $modulename"); print "Committed to Git repo\n"; }
The above is the script I use when installing a new Perl via perlbrew. Since it takes any module list as argument, it's perfectly able to install (or upgrade) any list of modules. The next program simply creates such list, and calls the previous one to upgrade them all.
This bash script asks the CPAN module which modules are considered outdated, and calls the above Perl script to upgrade them all.
#!/bin/bash TMPFILE=$(mktemp) perl -MCPAN -e 'CPAN::Shell->r' | \ perl -lne 'print if /Package namespace/ .. /installed modules have/' | \ grep -v 'Package namespace' | grep -v 'installed modules have' | \ grep -v 'Moose::Meta::Attribute::Native::MethodProvider::Array' | \ cut -d' ' -f1 > $TMPFILE echo Installing outdated modules: cat $TMPFILE perl install-my-modules.pl $TMPFILE rm $TMPFILE
That's it: every once in a while I simply launch the install-outdated script and all the Perl modules I use are upgraded to their latest version. Before beginning the upgrade, one could git tag the current revision, so that the branch could be reset there should the upgrade not go well.
blog comments powered by Disqus