Brief Notes on Managing Perl Dependencies with Carton

Miyagawa's Carton dependency tracking system for CPAN modules is about to reach its 1.0 release, so I've been exploring it for a client project.

The example project has five or six developers, all working remotely. We collaborate from a single Git repository. We have one testing server, one live server, and one mail server, though we're going to add at least one separate database server in the very near future. Our deployment strategy is minimal; we've automated part of it so that we can roll back commits that have problems, but we haven't automated database changes or system administration changes (adding an SSL certificate, changing the IP address of the database, installing a necessary Debian package, et cetera).

We do have a semi-structured list of deltas for CPAN module installations, but the process of keeping things up to date still requires manual intervention. Because tracking new dependencies and updated dependencies requires manual intervention (for example, a change to JSON rendering in Mojolicious 4 necessitated upgrading Mojolicious everywhere), Carton seemed like a good fit.

Carton does a couple of things. It keeps track of the dependencies of a project and their version numbers, given a list of dependencies, and lets you install those specific dependencies on any machine which has Carton.

In other words, if I somehow tell Carton that my project depends on Test::Most and Math::BaseConvert, Carton will write out a file it knows how to understand such that anyone who checks out the repository can use carton install to install the exact version of those modules I have installed.

(Carton can also bundle dependencies into a cache directory and install them from that cache, but that's not what we're doing.)

To start using Carton, install it. Then create a cpanfile with your dependencies:

require 'Test::Most';
require 'Math::BaseConvert';

With this file in place, run carton install. This will install those modules, if necessary, and write a file called cpanfile.snapshot with dependency information. (See Module::CPANfile for more information about cpanfile.)

Because Carton intends to manage dependencies for an application, it wants to install its modules to local/lib/perl5/ beneath the current directory. This may not work with your application; you may prefer to set the PERL_CARTON_PATH environment variable to point elsewhere. Keep in mind that wherever you have Carton install these dependencies, your application needs to have that directory in its include path somehow. (See Carton::Environment for more information.)

You can safely exclude that directory from your source control, but you should include both cpanfile and cpanfile.snapshot so that other people can work with Carton from your VCS checkout.

Adding a dependency is as easy as editing cpanfile and running carton install. Similarly, satisfying dependencies on a new checkout is as easy as running carton install.

For various reasons, our client project has a Makefile, so it's likely we'll add a simple target to add dependencies (and stage them for the next git commit) and to update dependencies. This, in fact, is one of the benefits of the design of Carton. Even though I only found an environment variable for customizing the library installation path, it's almost trivial to use the modules which make up Carton to build an application-specific installer—whereby we can keep our cpanfile and cpanfile.snapshot files in a directory of our choosing.

There's not much else to Carton I need beyond what I've described here. It doesn't intend to produce a full CPAN repository as tools like DarkPAN or Pinto do, which is fine. All we need is a little more discipline on how we manage dependencies, and Carton gives us an effective way to do that.

Modern Perl: The Book

cover image for Modern Perl: the book

The best Perl Programmers read Modern Perl: The Book.

sponsored by the How to Make a Smoothie guide



About this Entry

This page contains a single entry by chromatic published on July 27, 2013 6:00 AM.

Good Tests Hate Ambiguity was the previous entry in this blog.

Practicality and TPF Grants is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.

Powered by the Perl programming language

what is programming?