How I manage the distribution of Perl5 projects

If you are working like me (which is unlikely) distributing and deploying your Perl5 projects poses a significant challenge. Managing self-contained projects has become vastly easier since the advent of local::lib, Dist::Zilla and App::cpanminus but the ever changing (and sometimes incompatible) nature of CPAN has bitten me more than once in my life as a coder. Here is how I try to solve this, judge for yourself if this approach has any merit and encourage me to go further down this path if you think it does.

App::cpanminus included the --save-dists option for the first time in version 1.4 that was released this month. It might not seem like a big deal at first, but it got me thinking. I was always looking for a nice and hassle-free way to manage a mini-cpan that is localized to a project and could easily be managed by source control. Using a full mini-cpan for this simply couldn't be done due to size constraints. A gig here and a gig there amounts to real space requirements when needed in dozens of projects. Not to mention the pain of uploading and syncing this stuff.

Why would I want to do this? Its simple: most of my work is done for a smallish web-shop with a grown infrastructure and tons of freelancers. Every Ubuntu version from 8.04 to 11.04 beta can be found on our development machines and servers, you can never be sure which packages are installed (especially on the dev machines) and if you are working with a 32-bit or a 64-bit variant of the OS, nor which perl version is installed (although I would kick any of our freelancers that couldn't manage to get hold of at least 5.10.1). Dist::Zilla and local::lib brought some improvements to this non-existing process, but you are still at the whims of CPAN when installing from scratch. Not to mention that local libs are not portable between different versions of perl and different host environments.

Don't get me wrong, I don't want to lay any blame here. In fact In am more than impressed how stable and glitch-free the installation of modules like Catalyst and DBIx::Class is, given that they have zillions of dependencies they don't control. But being on the road, having only your netbook available and getting a call to urgently fix something in a project you haven't touched for months (and thus no dev environment ready to dive into) sucks. The last thing you need right then is the fun of working around a temporarily broken toolchain or framework of choice that makes installing from CPAN a nightmare.

Even more fun, if the bug you are hunting is caused by a bug in a dependency that has since be fixed and the version of this library you are using in production has vanished from CPAN (you know, some people clean up their authors directory) ...

Maybe I am trying to solve problems no one but me has. Or there is any solution to this that I have missed that is not as complicated as Shipwright seems to be. The usual recommendations (fixed dev environment with company wide mini-cpan, custom apt-repositories, you name it) just don't cut it for me.

...

I've exhausted my blogging tuits (and probably your patience) for today, but the good news is that I've managed to weave local::lib, Dist::Zilla, App::cpanminus and some fragments of mini-cpan style repository management into a nice small package that allows for easy tarball or VCS distribution of projects with no more requirements than a working perl and the theoretical ability to install from CPAN (cpanm is fat-packed into the deployment script) on the target machine.

Without further ado, if you are interested in a distribution management package that can do this for you, without requiring more than writing the usual dist.ini for Dist::Zilla, check out the github repository for App::Mist and especially the workflow document and tell me what you think.

Cheers & have fun,

  Sebastian

P.S. Prepending distributions needed by others that fail to list those dependencies (I'm looking at you, DBD::mysql) or simply fail some unimportant tests (Test::WWW::Mechanize, anyone?) is fully supported. Writing some checks to ensure the environment confirms to your expectations (pkg-config, C compiler, whatever ..) also is.

3 Comments

For one of my projects which require quite a lot of Perl distributions (>50 + their dependencies), I check in perl5 directory created by local::lib (from 2 build machines of different architectures). I maintain the list of required Perl modules manually, and feed them to cpanm whenever I need to update.

Considerably less hassle than the previous method of creating .rpm/.deb files for the dependencies.

At $work, we have a src/ directory for every project and we check in the tar.gz files directly from CPAN into that directory. Each project has a build script which builds those modules and installs them into $project/lib dir. This was done before local::lib, so it could probably be rewritten to work with that and be cleaner.

There are a lot of advantages to this system. Each svn version has the exact modules and the exact versions of those modules that it needs to work. Setting up a new dev environment is as easy as svn checkout and make build.

There are some pains which include having to hunt down distributions and their dependencies to put into your src/ directory. But that's pretty manageable with tools like Module::Depends.

Leave a comment

About Sebastian Willert

user-pic Programming Perl 5 in Emacs for over a decade, blogging since a few minutes. Expect tidbits about both technologies here (if at all, I'm not too sure I can develop a blogging habit).