perl-cpan-ecosystem

SKILL.md

CPAN Ecosystem Guide

Comprehensive guide for managing Perl modules using cpanm, cpanfile, Carton, and local::lib.

cpanm (cpanminus)

The recommended tool for installing CPAN modules.

Installation

# Using curl
curl -L https://cpanmin.us | perl - --self-upgrade

# Using system package manager
# Debian/Ubuntu
sudo apt install cpanminus

# macOS
brew install cpanminus

# From CPAN
cpan App::cpanminus

Basic Usage

# Install a module
cpanm Module::Name

# Install specific version
cpanm Module::Name@1.23

# Install with dependencies only (for testing)
cpanm --installdeps .

# Quiet installation
cpanm --quiet --notest Module::Name

# Install to local directory
cpanm --local-lib=~/perl5 Module::Name

Common Flags

Flag Purpose
--notest Skip tests (faster, less safe)
--quiet Minimal output
--verbose Detailed output
--force Install despite test failures
--installdeps Install dependencies only
--local-lib=DIR Install to specific directory
--self-upgrade Update cpanm itself
--mirror URL Use specific CPAN mirror
--skip-satisfied Skip already installed

Mirror Configuration

# Use a specific mirror
cpanm --mirror https://cpan.metacpan.org Module::Name

# Use mirror only (no fallback)
cpanm --mirror https://cpan.metacpan.org --mirror-only Module::Name

cpanfile

Declare dependencies in a cpanfile for reproducible installations.

Basic cpanfile

# cpanfile
requires 'Moo';
requires 'Path::Tiny';
requires 'Try::Tiny';

# Version constraints
requires 'DBI', '1.643';           # Exact version
requires 'JSON::XS', '>= 4.0';     # Minimum version
requires 'Plack', '< 2.0';         # Maximum version
requires 'Moose', '>= 2.0, < 3.0'; # Range

# Development dependencies
on 'develop' => sub {
    requires 'Perl::Critic';
    requires 'Perl::Tidy';
};

# Test dependencies
on 'test' => sub {
    requires 'Test::More', '0.98';
    requires 'Test::Exception';
    requires 'Test::Deep';
};

# Build dependencies
on 'build' => sub {
    requires 'Module::Build';
};

# Recommended (not required)
recommends 'JSON::XS';
suggests 'IO::Socket::SSL';

Feature Phases

Phase Purpose When Installed
runtime Production deps Always (default)
test Testing deps --with-test
develop Dev tools --with-develop
build Build tools During build

Install from cpanfile

# Install all runtime dependencies
cpanm --installdeps .

# Include test dependencies
cpanm --installdeps --with-test .

# Include all phases
cpanm --installdeps --with-develop --with-test .

Carton

Lock dependencies to exact versions for reproducible deployments.

Installation

cpanm Carton

Basic Workflow

# Create cpanfile.snapshot from cpanfile
carton install

# Install to local/ directory
carton install --deployment

# Update dependencies
carton update

# Run script with locked dependencies
carton exec perl script.pl

# Run with specific local path
carton exec --path local perl app.pl

Generated Files

File Purpose Git
cpanfile Dependency declaration Commit
cpanfile.snapshot Locked versions Commit
local/ Installed modules Ignore

.gitignore for Carton

/local/
/.carton/

Deployment Pattern

# Development machine
carton install
git add cpanfile cpanfile.snapshot
git commit -m "Update dependencies"

# Production machine
git pull
carton install --deployment --without develop,test
carton exec perl app.pl

local::lib

Install modules in user directory without root access.

Setup

# Install local::lib
cpanm local::lib

# Initialize (add to shell profile)
eval $(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib)

# Add to ~/.bashrc or ~/.zshrc
echo 'eval $(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib)' >> ~/.bashrc

Environment Variables

local::lib sets these variables:

PERL5LIB=$HOME/perl5/lib/perl5
PERL_LOCAL_LIB_ROOT=$HOME/perl5
PERL_MB_OPT="--install_base $HOME/perl5"
PERL_MM_OPT="INSTALL_BASE=$HOME/perl5"
PATH=$HOME/perl5/bin:$PATH

Custom Installation Path

# Use different directory
eval $(perl -Mlocal::lib=$HOME/myperllib)

# Project-specific
eval $(perl -Mlocal::lib=./local)

Module Resolution Order

Perl searches for modules in this order:

  1. Directories in @INC
  2. PERL5LIB paths
  3. Site lib (system-wide)
  4. Core modules

Check current @INC:

perl -V  # Full config including @INC
perl -e 'print join("\n", @INC)'

Finding Modules

Search MetaCPAN

# Using mccpan (if installed)
cpanm App::cpanminus::reporter
cpan-outdated

# Or use web: https://metacpan.org/

Check Installed Modules

# List all installed
perldoc perllocal

# Check specific module
perl -MModule::Name -e 'print $Module::Name::VERSION'

# Using cpan
cpan -l

# Using pmvers (from pmtools)
pmvers Module::Name

Troubleshooting

Common Issues

Module not found after install:

# Check PERL5LIB
echo $PERL5LIB

# Verify module location
perl -MModule::Name -e 'print $INC{"Module/Name.pm"}'

Permission denied:

# Use local::lib instead of sudo
eval $(perl -Mlocal::lib)
cpanm Module::Name

Build failures:

# Install build tools
# Debian/Ubuntu
sudo apt install build-essential

# Check build log
less ~/.cpanm/build.log

XS module compilation:

# Install development headers
sudo apt install libssl-dev  # For SSL modules
sudo apt install libxml2-dev # For XML modules

Project Setup Example

Initialize a new Perl project with proper dependency management:

# Create project structure
mkdir -p myapp/{lib,t,bin}
cd myapp

# Create cpanfile
cat > cpanfile << 'EOF'
requires 'Moo';
requires 'Path::Tiny';
requires 'Try::Tiny';

on 'test' => sub {
    requires 'Test::More', '0.98';
};
EOF

# Install with Carton
carton install

# Add to .gitignore
echo '/local/' >> .gitignore
echo '/.carton/' >> .gitignore

# Commit dependency spec
git add cpanfile cpanfile.snapshot

Additional Resources

For Perl version management with perlbrew, see the perl-environment-setup skill.

Weekly Installs
1
GitHub Stars
26
First Seen
14 days ago
Installed on
mcpjam1
claude-code1
junie1
windsurf1
zencoder1
crush1