Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moving / cloning a perlbrew installed perl plus all the additional cpan modules

I am using perlbrew. I have installed lots of cpan modules under perlbrew perl-5.20.2.

Is there a way (or what is the best way) to do a tarball installation of my perl-5.20.2 plus all the CPAN modules that I have installed under perlbrew so that I can just clone it unto another machine?

I am aware of perlbrew download perl-5.20.2 but that only seems to tarball perl-5.20.2 and not all the CPAN modules that I have installed.

like image 230
Hamster Avatar asked Mar 12 '15 15:03

Hamster


People also ask

How do I use CPAN to install Perl?

To run cpan you can use the following command: If this is the first time you are using cpan you will need to proceed with the basic configuration by answering a few simple questions. To install the same Perl module we installed before you can use the following command: This will also ensure that all module dependencies will be properly installed.

How to get the list of modules in the current Perl installation?

You can easily get the list of modules in the current perl installation with list-modules command: That simply prints out module names that you can use latter. Since perlbrew 0.81, it is possible to use the clone-modules command to reinstall all the modules from a Perl instance to another.

Where is perlbrew installed on Linux?

If it is installed with cpan, the perlbrew executable should be installed as /usr/bin/perlbrew or /usr/local/bin/perlbrew. For all users who want to use perlbrew, a prior perlbrew init needs to be executed.

How do I install Perl on a Windows Server?

Use the manual method only if the server is not connected to the Internet. To install Perl modules using CPAN, make sure the cpan command is working. You should have the CPAN perl module installed before you can install any other Perl modules using CPAN.


1 Answers

With perlbrew you can use the lib command to create a local::lib to go with your perlbrew perl.

perlbrew lib create perl-5.20.2@app_reqs

Then, if all goes well, when you install modules you will find them in:

$HOME/.perlbrew/libs/perl-5.20.2@app_reqs

If you don't use the perbrew lib create approach to managing your modules, then they are installed to $HOME/perl5/perlbrew/perls/perl-5.20.1/lib/site_perl/5.20.2. Cloning either of those directories might work, but you are likely better off reinstalling all the modules using the techniques from the perlbrew.pl website since XS modules should be rebuilt etc.

If you want to reuse and track local sources the most reliable approach is to create a local CPAN mirror to work from using App::lcpan or minicpan. If you have already downloaded the source using cpanm a quick hackish approach is to find the source files (under $HOME/.cpanm/) and do something like this in your shell:

% mkdir  ~/cpansourcefiles  
% for source in ~/.cpanm/work/*/* ; do cp $source ~/cpansourcefiles ;done

Then you can get cpanm to install using those sources by passing the filename as the argument instead of the module name:

% cpanm ~/cpansourcefiles/List-MoreUtils-0.406.tar.gz

or even:

% cpanm ~/cpansourcefiles/*  

NB: YMMV since this is prone to breakage and might skip some of the version and dependency checking you normally get with cpanm but it is simpler than setting up a mirror when it works.


A few other high powered tools that make deploying Perl applications robust and reliable:

  • Carton
  • Pinto

EDIT:

Tools like perlbrew, pinto, carton, and cpanm are a vast improvement over a motley personal collection of scripts for doing similar things. Thanks to all the developers and contributors to these tools!

I'm not aware of any features in cpanm or perlbrew that allow you to reliably produce a list of installed files and their versions. Something like:

 cpanm --list_installed
 perlbrew list_installed_versions

or:

 cpanm --export-cpanfile
 perlbrew list_installed_as_cpanfile

might be a welcome feature.

As I noted in a comment to the OP above, you can garner useful information about your module installation from the install.json files that are installed by cpanm. Modules like CPAN::Meta, Module::Metadata and Distribution::Metadata can be helpful too.

The suggestion to use find and jq (which was from @Ilmari Karonen see Upgrade all modules installed by local::lib in this answer) led to the quick unfinished hack below. One challenge/issue is there's sometimes install.json files left lying around in multiple locations:

  • lib/perl5/$Config{archname}/.meta/Whatever-Mod-1.0050000/install.json
  • lib/perl5/$Config{archname}/.meta/Whatever-Mod-1.0090000/install.json
  • ... etc.

This is likely because these files are not always cleanly removed when upgrading, reinstalling or other mucking about PEBKAC errors. To work properly, the code below should be changed so that it notices when there are multiple name-version combinations of a module's install.json and then does a more thorough check that the module is installed and gets its version. The script should have options: $dir could come from @ARGV. TIMTOWTDI, "well volunteered", etc.

#!perl  
# list_installed_mods.pl 
# DOES NOT THOROUGHLY VERIFY CURRENT VERSION

use File::Find;                                       
use JSON;                                       
use v5.16;     
my $dir = "$ENV{HOME}/perl5/lib/perl5";      

for my $installed ( find_installed($dir) ) {     
  say parse_install_json( $installed );     
} 

sub find_installed {  
  my $libdir = shift;    
  my @files;   
  File::Find::find ({ wanted => 
    sub { push @files, $File::Find::name if /install\.json/i} },
    $libdir );
  return @files; 
} 

sub parse_install_json {
  my $filename = shift;
  my $json_text = do {   
   open(my $json_fh, "<:encoding(UTF-8)", $filename)                
      or die("Can't open \$filename\": $!\n");                          
   local $/;
   <$json_fh>                                                           
  }; 
  my $install = decode_json($json_text) ;   
  return ( $install->{name} ,"\@", $install->{version} ) ;
} 
like image 191
G. Cito Avatar answered Jan 22 '23 22:01

G. Cito