(picture from elevate)
For various reasons, you might want to install CPAN modules from a git repository.
It can be because somehow a git repository is in advance against CPAN:
- A fix was merged in official git repository but never released to CPAN
- A branch or a fork contains some valuable changes (this very-little-but-absolutely-needed fix)
Or it can be because the modules are actually not in CPAN: not public and not in a alternative/private CPAN (see Addendum) or simply they are only "experiments"
But this post is not meant to discuss about the "why" but instead mainly share technically the "how" you could do that 😀
I tested various syntax and installers and will share now some working examples.
☝️ Before we continue, be sure to upgrade your installers (App::cpm
and App::cpanminus
) to their latest
Installing from command line with cpm
Installing with cpm
is straighforward:
$ cpm install https://github.com/plack/Plack.git --verbose
33257 DONE fetch (0.971sec) https://github.com/plack/Plack.git
33257 DONE configure (0.033sec) https://github.com/plack/Plack.git
33257 DONE resolve (0.031sec) Clone -> Clone-0.46 (from MetaDB)
...
33257 DONE install (0.364sec) URI-5.28
33257 DONE install (0.046sec) https://github.com/plack/Plack.git
31 distributions installed.
It can also work the same with ssh git@github.com:plack/Plack.git
:
$ cpm install git@github.com:plack/Plack.git --verbose
64383 DONE fetch (2.498sec) git@github.com:plack/Plack.git
64383 DONE configure (0.039sec) git@github.com:plack/Plack.git
...
64383 DONE install (0.045sec) git@github.com:plack/Plack.git
31 distributions installed.
Installing from command line with cpanminus
Installing with cpanm
is not harder:
$ cpanm https://github.com/plack/Plack.git
Cloning https://github.com/plack/Plack.git ... OK
--> Working on https://github.com/plack/Plack.git
...
Building and testing Plack-1.0051 ... OK
Successfully installed Plack-1.0051
45 distributions installed
Installing from cpanfile
The correct syntax is the following (thank you @haarg):
requires 'Plack', git => 'https://github.com/plack/Plack.git', ref => 'master';
(ref => 'master'
is optional)
And it would just work later with cpm
:
$ cpm install --verbose
Loading requirements from cpanfile...
33257 DONE fetch (0.971sec) https://github.com/plack/Plack.git
33257 DONE configure (0.033sec) https://github.com/plack/Plack.git
33257 DONE resolve (0.031sec) Clone -> Clone-0.46 (from MetaDB)
...
33257 DONE install (0.364sec) URI-5.28
33257 DONE install (0.046sec) https://github.com/plack/Plack.git
31 distributions installed.
⚠️ Despite being a cpanfile
, please note the use of cpm
Installing from cpmfile
Let's write our first cpmfile and save it as cpm.yml
:
prereqs:
runtime:
requires:
Plack:
git: https://github.com/plack/Plack.git
ref: master
And then it would just work with cpm
:
$ cpm install --verbose
Loading requirements from cpm.yml...
66419 DONE resolve (0.000sec) Plack -> https://github.com/plack/Plack.git@master (from Custom)
66419 DONE fetch (1.695sec) https://github.com/plack/Plack.git
66419 DONE configure (0.034sec) https://github.com/plack/Plack.git
...
66419 DONE install (0.023sec) https://github.com/plack/Plack.git
31 distributions installed.
Beware of "incomplete" repositories
Releases on CPAN are standardized and generally contain what is needed for installers, but distributions living in git repositories are more for development and very often not in a "ready to install" state.
(thank you @karenetheridge)
There's some limitations that you can encounter:
-
cpm
would refuse to install if no META file is found (butcpanm
would be OK with that) -
cpm
would refuse to install if noMakefile.PL
norBuild.PL
is found, except if x_static_install: 1 is declared in META (cpanm
would still refuse)
Should I mention the repositories with only a dist.ini
? (used by authors to generate everything else)
And you would get similar trouble with distributions using Module::Install
but having not versioned it.
Conclusion
You should probably not rely too much on "install from git" method but still, it can provide an handy way to install modules to test fixes or experiments.
And now with this post you should have good examples of “how” you can achieve that.
Addendum
Alternative CPAN
For alternative/private CPAN, several tools can come to your rescue:
What is not working (2024)
cpanm with cpanfile
Look at following cpanfile
:
requires 'Plack', git => 'https://github.com/plack/Plack.git', ref => 'master';
It is not well "honored" by cpanminus
.
Broken syntax
requires "MyExperimental::Module" => "git://github.com/lestrrat/p5-MyExperimental-Module.git";
Resources
(some of them are outdated)
Top comments (1)
Other reasons for not being able to install directly from git include things like the repo containing code to build a CPAN dist, as opposed to containing the dist itself. My Number::Phone is an example of this.
Did you know that perlbrew can build and install perl from a git checkout too? I have a little bash helper function that makes it a bit more convenient by automatically giving such perls a nice descriptive name: