Tatsuhiko Miyagawa's Blog

cpanm towards 2.0 (Menlo)

April 21, 2015

First, little bit of background:

I was working on cpan-common-index branch for cpanm and the branch adds CPAN::Common::Index and its all subdeps, which might make fatpacking on 5.8 difficult because of the amount of its non-core dependencies, some of which are dual XS/PP. To clarify: it’s not impossible, but just harder and more stuff to add to be able to bootstrap on 5.8.

Also, at this point I’d deadly need an extension point so that external programs can at least be notified for newly installed modules, so that you don’t need to mess with installations (ala cpanminus-reporter, plenv-rehash, Carton and Carmel).

And cpanm has grown a little too far and some of the options and features do not make sense to belong to the base installer.

cpanm has been always distributed as a fatpack script, even to CPAN (as a fatscript.pm alternative, which is used by Carton and Carmel to avoid loading cpanm from a wrong directory), and it makes debugging difficult and updating its dependencies difficult on the end user machine if they desire to. However, that’s an opposite side of the same coin — there’s an added benefit that fatpacked dependencies aren’t accidentally upgraded. Bootstrapping is also easier because cpanm is a single file executable.

Plan for 2.0

All of the above considered, here’s a quick plan for cpanm 2.0:

Base Installer

So that fatpacking is still easy and bootstrappable, cpanm should be available as a fatpacked script to bootstrap itself. It should work on perl back to 5.8.1 without any non-core modules installed. User can choose to use the fatpacked script to install newer cpanm, as a start point.

Modular and Extensible

cpanm 2 will be maintained and released as a regular perl module with all of its dependencies vendored. This should provide developers to upgrade dependencies without me releasing a new vendor’ed cpanm script.

Remove Features From Base

Some of the features available in cpanm does not make sense in the “base” script to bootstrap, for example:

  • — info command
  • — look command
  • -L local::lib self-contained support
  • MetaCPAN query support
  • — dev search
  • — mirror-index , — cascade-search (basically added as an interface for Carton)
  • Changing cpanmetadb endpoint
  • — uninstall command
  • install from git support
  • features support
  • — scandeps command
  • — format option
  • — save-dists option (although still useful for caching)
  • — skip-installed, — skip-satisfied (they can just be default)
  • — no-man-pages Well, there’s a lot :)

I’m not saying I’d delete these features; users will get pissed off and their scripts get broken if they upgrade cpanm and these features were gone. These features should still be available as a built-in features of the next-gen client, which can be a drop-in replacement for cpanm, but the base installer can be shipped without these features, as long as you can upgrade to the next-gen in one command.

Namewise, I haven’t decided whether it should be cpanm (base) vs something-else (2.0), or just cpanm-base vs cpanm-2.0 where the single cpanm executable can be upgraded to the fully featured 2.0 from the fatpacked image. I think the latter is neater and creates less confusions since most of the commands will still available as long as you install to the latest, but I can see corner cases where this could be tricky. (“Oh your cpanm is in a weird state — try upgrading to 2.x with the following command.”)

Alternatively, cpanm can be shipped as a base fatpack script like today, but installing another package will be able to overwrite the cpanm executable with the updated features.

There might be many ways to do this (as always), and I can see pros/cons for each approach.


Speaking of the naming, I see this as an opportunity to make an alternative name to cpanminus — because frankly, cpanminus has started as an internal joke with CPANPLUS as an elephant in the room. For people outside the Perl community, the name “minus” just sounds weird.

Luckily people remember the command by its executable, “cpanm”, and we can be creative and give a name that gives the “m” initial.

Just a thought, I think it’s a great time to change the name if we ever want to do so. As of this writing, cpanm 2.0 is developed under the code name Menlo.

Plugin Architecture

Basically some of these options linked above are backdoors to implement things like reporter or Carton/Carmel. All of these can be implemented as a proper plugin if we provide a hook point. Too bad I killed the plugins idea in early days of pre-1.0 due to some criticism of making cpanm bloat despite the name — which wasn’t really true, compared to the current bloat!

Plugins should be able to be configured globally under ~/.cpanm but also should provide a modular interface to disable/enable per run, so tools like plenv/cpanminus-reporter/Carmel/Carton can hook in properly.

Legacy Support

Here’re some of the things I need to figure out for legacy support:

  • Many people use cpanmin.us but also github raw URL (cpanm in master branch) with curl. The file should be kept as a fatpacked boot script (aka “base” above)
  • Tools like plenv and perlbrew install the fatpack into its own bin, which makes upgrading difficult. Maybe, the new cpanm fatpack will detect the upgraded executable in the perl bin path and prefers them.