App::cpanminus (cpanm)

repository·devel·Indexed 21 days ago

https://github.com/miyagawa/cpanminus

A tool for getting, unpacking, building, and installing Perl modules from CPAN. The project consists of the App-cpanminus frontend and the Menlo backend, which provides a scriptable API and modular interface for cpanm 2.0. It supports installation to system Perl, local Perl (via perlbrew or plenv), and local::lib.

Tokens
2.8K
Snippets
10
Records
20
Agent score
72%

What's inside cpanminus

  1. Overview of App::cpanminus distributions

    devel

    The miyagawa/cpanminus repository is a monorepo containing two distinct distributions:

    1. App-cpanminus: The fatpacked cpanm frontend used for interacting with CPAN.
    2. Menlo: The backend modules and libraries that power the functionality.

    Developers can use this repository to access both the frontend tool and the underlying logic used to get, unpack, build, and install modules from CPAN.

  2. Overview of Menlo

    devel
    Menlo is a backend for cpanm 2.0 designed to be a more flexible, extensible, and easier-to-use replacement for the internals of the original cpanm. Unlike the original cpanm, which is implemented as a single script with a 'God class' and packaged via fatpacker, Menlo is implemented as a standard set of Perl modules. This allows developers to extend its behavior through modular interfaces or by writing plugins, rather than relying on shell wrappers or parsing stdout/logs.
  3. Understand where cpanm installs modules

    devel

    Modules are installed based on the configuration of ExtUtils::MakeMaker and Module::Build (via PERL_MM_OPT and PERL_MB_OPT).

    • System Perl: Usually installs to the site_perl directory (e.g., /opt/local/perl/...). Requires root or --sudo.
    • Local Perl (perlbrew/plenv): Installs to your home directory's Perl library path.
    • local::lib: If local::lib is configured in your shell, cpanm respects those settings and installs to your local perl5 directory.
    • Automatic fallback: If you are using system Perl without root access and without local::lib configured, cpanm will automatically set up a local::lib compatible installation path in a perl5 directory under your home directory.
  4. How Menlo differs from cpanm

    devel

    While cpanm is a lightweight, dependency-free, and configuration-free tool, its monolithic implementation makes it difficult to modify at runtime without forking or monkeypatching.

    Menlo maintains the core benefits of cpanm (lightweight, fast, dependency-free installation) but provides a scriptable API and hook points. It is available as a standard Perl module on CPAN, enabling programmatic integration and extensibility that the original cpanm lacks.

  5. Download the standalone cpanm executable

    devel

    You can download the standalone cpanm executable directly to a specific location. Note that if you use this method, the --self-upgrade command might not work, so you will need to manually download a new version when upgrading.

    cd ~/bin
    curl -L https://cpanmin.us/ -o cpanm
    chmod +x cpanm
  6. Install cpanm to local perl (perlbrew, plenv, etc.)

    devel

    If you are using a Perl installation located in your home directory (such as those managed by perlbrew or plenv), you can install cpanm without sudo because you have write permissions to the library path. This will install the executable to your Perl's bin path.

    curl -L https://cpanmin.us | perl - App::cpanminus
  7. Install Menlo::Legacy for cpanm compatibility

    devel

    Install Menlo::Legacy to provide the Menlo::CLI::Compat library. This library implements the classic version of cpanm internals and behaviors, ensuring stability for downstream clients that rely on specific cpanm logic.

    Use Menlo::Legacy if you are using API clients such as:

    • Carton
    • Carmel
    • App::cpm

    By using this compatibility layer, these tools can continue to rely on stable cpanm features even as the underlying Menlo platform evolves or undergoes refactoring.

  8. Install cpanm to system perl

    devel

    To install the latest version of cpanm directly into your system's Perl installation (e.g., /usr/local/bin), use the following command. Note that you will likely need --sudo to write to system directories unless you have configured local::lib via INSTALL_BASE.

    curl -L https://cpanmin.us | perl - --sudo App::cpanminus
  9. Use Hash::MultiValue to store multiple values per key

    devel

    Hash::MultiValue is an object (and a blessed hash reference) designed to handle cases where a single key may have multiple associated values, such as web request parameters. It allows you to treat the object like a standard hash for single-value access while providing an explicit API to retrieve all values for a key.

    Key Behaviors

    • Single Value Access: When accessing a key via $hash->{key} or $hash->get($key), the last value entered for that key is returned. This mimics standard Perl behavior (e.g., merging hashes or taking a scalar from a list).
    • Multi-Value Access: Use $hash->get_all($key) to retrieve all values associated with a key as a list.
    • Key Iteration:
      • keys %$hash returns only unique keys (standard hash behavior).
      • $hash->keys returns all keys, including duplicates, in the order they were added.

    Basic Usage

    use Hash::MultiValue;
    
    my $hash = Hash::MultiValue->new(
              foo => 'a',
              foo => 'b',
              bar => 'baz',
          );
    
    my $foo = $hash->{foo};         # 'b' (the last entry)
    my $foo = $hash->get('foo');    # 'b'
    my @foo = $hash->get_all('foo'); # ('a', 'b')
    
    keys %$hash; # ('foo', 'bar')
    $hash->keys; # ('foo', 'foo', 'bar')
  10. Update Hash::MultiValue contents correctly

    devel

    When modifying a Hash::MultiValue object, do not use the standard hash reference interface (e.g., $hash->{key} = $val or delete $hash->{key}). Doing so will update the underlying hash but will not update the internal tracking object used to manage multiple values.

    Instead, use the provided mutation methods:

    • add($key, $value, ...): Appends new values to a key.
    • set($key, $value, ...): Replaces existing values for a key with the new set.
    • remove($key): Removes the key and all its associated values.
    • clear: Empties the hash.

    Correct vs Incorrect Updates

    my $hash = Hash::MultiValue->new();
    
    # WRONG: This bypasses the multi-value tracker
    $hash->{foo} = 'bar';
    delete $hash->{foo};
    
    # Correct: This updates the tracker correctly
    $hash->add(foo => 'bar');
    $hash->remove('foo');
    # WRONG
    $hash->{foo} = 'bar';
    delete $hash->{foo};
    
    # Correct
    $hash->add(foo => 'bar');
    $hash->remove('foo');