Anyenv + Plenv + Carton
Recently I started breaking out of my Perl-only isolation bubble and dabbling with other languages. I was surprised how easy and comfortable other languages are. I think its because these days good ideas spread from one language to the next incredibly fast. Even in a new language when I reach for a tool I can usually find some Perl technology analogue.
For example, I’ve been a perlbrew person for a long time and it has served me well. Ruby has its own version of perlbrew called rbenv which is pretty great. But actually it seems every language has a clone of rbenv.
- Python has pyenv.
- PHP has phpenv.
- Node has ndenv.
- Java has jenv.
- Perl has plenv.
So I thought, what the heck – lets try that out. The nice thing is all the envs have pretty much the same command line options and the same approach to managing dependencies. I thought it might be calming and soothing for my brain to have one way of doing things.
I found Anyenv just a second ago as I was writing this. It claims it will manage all my envs. Looks like brilliant stuff. Fortune favors the bold. (I eat danger for breakfast.) I’ll try it.
git clone https://github.com/riywo/anyenv ~/.anyenv
echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.my_profile
echo 'eval "$(anyenv init -)"' >> ~/.my_profile
exec bash -l
anyenv install rbenv # ruby
anyenv install plenv # perl
anyenv install pyenv # python
anyenv install phpenv # php
anyenv install ndenv # nodejs
anyenv install denv # dunno
anyenv install jenv # java
exec bash -l # <-- useful trick btw
anyenv versions
Ok now I have all the envs. But I want to actually do some work with plenv. Lets see if I can do that.
plenv install --list # list all the potential perl versions you can use
plenv install 5.19.6 # install perl v5.19.6
plenv rehash # reload the shell environment with the new perl
plenv global 5.19.6 # use v5.19.6 everywhere by default
plenv local 5.19.6 # use v5.19.6 in this directory for this project
plenv install-cpanm # install cpanm for this version of perl
plenv rehash #
plenv which cpanm # see where cpanm is installed. should be ~/.anyenv
Now I will install the dependencies for my project. I will manage them with Carton.
cpanm Carton # install carton for this version of perl
plenv list-modules
At this point I need to create a cpanfile
. There are all kinds of cool
things you can do in this file, but with your permision I will begin with baby
steps. Here is mine cpanfile for now:
requires "Catalyst";
requires "Plack";
requires "DBD::SQLite";
And then I run carton to install these modules locally into local/lib/perl5.
carton # install all the dependencies from the cpanfile
ls local/lib/perl5/ # see all the new modules installed here
plenv list-modules # see mountains of installed stuff
cd /tmp
plenv list-modules # see nothing installed except Carton
Notice that a carton.snapshot file was created. If I look inside, I can see a list of all my project dependencies, and all their dependencies, etc all the way down to the first turtle – AND there are version numbers for everything.
# carton snapshot format: version 1.0
DISTRIBUTIONS
Apache-LogFormat-Compiler-0.13
pathname: K/KA/KAZEBURO/Apache-LogFormat-Compiler-0.13.tar.gz
provides:
Apache::LogFormat::Compiler 0.13
requirements:
CPAN::Meta 0
CPAN::Meta::Prereqs 0
Module::Build 0.38
...blah biddee blah etc...
I can add cpanfile
and cpanfile.snapshot
to my git repo. Now when I deploy
or share the code, the user at the destination can run Carton and they will end
up with the exact dependencies with the exact same version numbers I had. This
way I can be sure my code will run as successfully for them as it did for me.