Wednesday, October 28, 2009

Versioned site_lib

Today I wanted to install a simple module on a production machine. I used the CPAN utility, as usual. Unfortunately that also pulled in an upgraded dependency which was not backwards compatible, breaking the application.

I hate yak shaving.

But not nearly as much as I hate surprise yak shaving.

I want to fix compatibility problems in my development environment on my own time, not hastily on a live server.

I wrote a small module to address this problem. To set it up run git site-perl-init. This will initialize the .git directory and configure CPAN to wrap make install and ./Build install with a helper script.

The wrapper will invoke the installation command normally, and then commit any changes to installsitelib with the distribution name as the commit message. This will happen automatically every time CPAN tells a module to install itself.

The approach is very simplistic; it does not version manpages or the bin directory, nor does it work with local::lib or CPANPLUS (at least not yet).

It is just enough to let me run git reset --hard "master@{1 hour ago}" to instantly go back to a working setup.


brian d foy said...

This is something that I've wanted to add as a feature to my cpan script for awhile, but I've been too lazy to do that. :)

Johan Lindstrom said...

I call mine gitpan.

nothingmuch said...

Note that I do think this is a bad implementation, a real solution would involve adding some sort of proper hook mechanism to, i suppose. But it works =)

JohanL - is that publicly available? google did not help much

Johan Lindstrom said...

Eh, it's not really and application, or even a script even. It's a bash function :)

I run this from inside my ~/local_cpan (which is a git workspace) to install modules:

function gitpan { cpan "$1" && git add . >/dev/null && git commit -m "$1" >/dev/null }

miyagawa said...

> a real solution would involve adding some sort of proper hook mechanism to, i suppose.

Another solution is to write a new CPAN client, which shamelessly I did, and added a plugin to exactly this. Works well with local::lib configuration as well.