.\" -*- mode: troff; coding: utf-8 -*- .\" Automatically generated by Pod::Man v6.0.2 (Pod::Simple 3.48) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>. .ie n \{\ . ds C` "" . ds C' "" 'br\} .el\{\ . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Required to disable full justification in groff 1.23.0. .if n .ds AD l .\" ======================================================================== .\" .IX Title "App::cpm::Tutorial 3pm" .TH App::cpm::Tutorial 3pm 2026-10-22 "perl v5.44.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH NAME App::cpm::Tutorial \- How to use cpm .SH SYNOPSIS .IX Header "SYNOPSIS" .Vb 1 \& $ cpm install Module .Ve .SH DESCRIPTION .IX Header "DESCRIPTION" cpm is yet another CPAN client (like cpan, cpanp, and cpanm), which is fast! .SS "How to install cpm" .IX Subsection "How to install cpm" Download the latest self\-contained cpm and run it directly: .PP .Vb 3 \& curl \-fsSL \-o cpm https://github.com/skaji/cpm/releases/latest/download/cpm && \& chmod +x cpm && \& ./cpm \-\-version .Ve .PP To verify its artifact attestation before running it, use this sequence instead. It requires the GitHub CLI (\f(CW\*(C`gh\*(C'\fR) and stops if downloading or verification fails: .PP .Vb 4 \& curl \-fsSL \-o cpm https://github.com/skaji/cpm/releases/latest/download/cpm && \& gh attestation verify cpm \-\-repo skaji/cpm && \& chmod +x cpm && \& ./cpm \-\-version .Ve .PP You can use \f(CW\*(C`./cpm\*(C'\fR as is, or place it in a directory on your \f(CW\*(C`PATH\*(C'\fR. .SS "First step" .IX Subsection "First step" .Vb 1 \& $ cpm install Plack .Ve .PP This command installs Plack into \f(CW\*(C`./local\*(C'\fR, and you can use it by .PP .Vb 1 \& $ perl \-I$PWD/local/lib/perl5 \-MPlack \-E \*(Aqsay Plack\->VERSION\*(Aq .Ve .PP By default, cpm installs the requested distributions and their runtime dependency closure. .PP If you want to install modules into current INC instead of \f(CW\*(C`./local\*(C'\fR, then use \f(CW\*(C`\-\-global/\-g\*(C'\fR option. .PP .Vb 1 \& $ cpm install \-\-global Plack .Ve .PP By default, cpm chooses a progress mode automatically. On interactive terminals, it usually shows the terminal progress UI. Otherwise, it uses plain line\-by\-line output. .PP If you want plain output explicitly, use \f(CW\*(C`\-\-progress=plain\*(C'\fR. If you want more verbose messages, use \f(CW\*(C`\-\-verbose/\-v\*(C'\fR option. .PP .Vb 2 \& $ cpm install \-\-progress=plain Plack \& $ cpm install \-\-verbose Plack .Ve .SS "Second step" .IX Subsection "Second step" cpm can handle version range notation like cpanm. Let\*(Aqs see some examples. .PP .Vb 3 \& $ cpm install Plack~\*(Aq> 1.000, <= 2.000\*(Aq \& $ cpm install Plack~\*(Aq== 1.0030\*(Aq \& $ cpm install Plack@1.0030 # this is an alias of ~\*(Aq== 1.0030\*(Aq .Ve .PP cpm can install dev releases (TRIAL releases). .PP .Vb 1 \& $ cpm install Moose@dev \& \& # if you prefer dev releases for not only Moose, \& # but also its dependencies, then use global \-\-dev option \& $ cpm install \-\-dev Moose .Ve .PP And cpm can install modules from git repositories directly. .PP .Vb 1 \& $ cpm install https://github.com/skaji/Carl.git .Ve .SS "cpanfile and dist/url/mirror/git syntax" .IX Subsection "cpanfile and dist/url/mirror/git syntax" If you omit arguments, and there exists one of .IP "cpm.yml " 4 .IX Item "cpm.yml " .PD 0 .IP "cpanfile " 4 .IX Item "cpanfile " .IP "META.json (with dynamic_config false)" 4 .IX Item "META.json (with dynamic_config false)" .ie n .IP """Build.PL""" 4 .el .IP \f(CWBuild.PL\fR 4 .IX Item "Build.PL" .ie n .IP """Makefile.PL""" 4 .el .IP \f(CWMakefile.PL\fR 4 .IX Item "Makefile.PL" .PD .PP in the current directory, then cpm loads modules from the file, and install them .PP .Vb 4 \& $ cat cpanfile \& requires \*(AqMoose\*(Aq, \*(Aq2.000\*(Aq; \& requires \*(AqPlack\*(Aq, \*(Aq> 1.000, <= 2.000\*(Aq; \& $ cpm install .Ve .PP By default, cpm reads the \f(CW\*(C`configure\*(C'\fR, \f(CW\*(C`build\*(C'\fR, \f(CW\*(C`test\*(C'\fR, \f(CW\*(C`runtime\*(C'\fR, and \f(CW\*(C`develop\*(C'\fR phases from the top\-level dependency file. .PP If you want to select phases or relationships explicitly, use \&\f(CW\*(C`\-\-top\-level\-phase\*(C'\fR and \f(CW\*(C`\-\-top\-level\-relationship\*(C'\fR. .PP .Vb 2 \& $ cpm install \-\-top\-level\-phase runtime \& $ cpm install \-\-top\-level\-relationship requires,recommends .Ve .PP If you have \f(CW\*(C`cpanfile.snapshot\*(C'\fR, then cpm tries to resolve distribution names from it .PP .Vb 3 \& $ cpm install \-v \& 30186 DONE resolve (0.001sec) Plack \-> Plack\-1.0030 (from Snapshot) \& ... .Ve .PP cpm supports dist/url/mirror syntax in cpanfile just like cpanminus: .PP .Vb 2 \& requires \*(AqPath::Class\*(Aq, 0.26, \& dist => "KWILLIAMS/Path\-Class\-0.26.tar.gz"; \& \& # use dist + mirror \& requires \*(AqCookie::Baker\*(Aq, \& dist => "KAZEBURO/Cookie\-Baker\-0.08.tar.gz", \& mirror => "http://cpan.cpantesters.org/"; \& \& # use the full URL \& requires \*(AqTry::Tiny\*(Aq, 0.28, \& url => "http://backpan.perl.org/authors/id/E/ET/ETHER/Try\-Tiny\-0.28.tar.gz"; .Ve .PP cpm also supports git syntax in cpanfile: .PP .Vb 5 \& requires \*(AqCarl\*(Aq, git => \*(Aqhttps://github.com/skaji/Carl.git\*(Aq; \& requires \*(AqApp::cpm\*(Aq, git => \*(Aqhttps://login:password@github.com/skaji/cpm.git\*(Aq; \& requires \*(AqPerl::PrereqDistributionGatherer\*(Aq, \& git => \*(Aqhttps://github.com/skaji/Perl\-PrereqDistributionGatherer\*(Aq, \& ref => \*(Aq3850305\*(Aq; # ref can be revision/branch/tag .Ve .PP Please note that to support git syntax in cpanfile wholly, there are several TODOs. .SS "Darkpan integration" .IX Subsection "Darkpan integration" There are CPAN modules that create \fIdarkpans\fR (minicpan, CPAN mirror) such as CPAN::Mini, OrePAN2, Pinto. .PP Such darkpans store distribution tarballs in .PP .Vb 1 \& DARKPAN/authors/id/A/AU/AUTHOR/Module\-0.01.tar.gz .Ve .PP and create the \fIde facto standard\fR index file \f(CW\*(C`02packages.details.txt.gz\*(C'\fR in .PP .Vb 1 \& DARKPAN/modules/02packages.details.txt.gz .Ve .PP If you want to use cpm against such darkpans, change the cpm resolver by \f(CW\*(C`\-\-resolver/\-r\*(C'\fR option: .PP .Vb 2 \& $ cpm install \-\-resolver 02packages,http://example.com/darkpan Module \& $ cpm install \-\-resolver 02packages,file::///path/to/darkpan Module .Ve .PP If you host your own metadb for your own darkpan, you can use it too: .PP .Vb 3 \& $ cpm install \e \& \-\-resolver metadb,http://example.com/darkmetadb,http://example.com/darkpan \e \& Module .Ve