Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Internal CPAN - what module

Tags:

perl

cpan

I want to setup in-house CPAN for distributing our internal code.

So I was looking at CPAN::Mini as recommended here. But it looks there are other options as CPAN::Site, CPAN::Dark, Dist::Zilla ...

I'm little bit overwhelmed with all these options. What do people mostly use/ recommend?

What I need is a way to push internal modules to repository which can be accesses from several machines.

like image 334
jira Avatar asked Jul 11 '11 10:07

jira


People also ask

What is CPAN module in Perl?

The Comprehensive Perl Archive Network (CPAN) is a repository of over 250,000 software modules and accompanying documentation for 39,000 distributions, written in the Perl programming language by over 12,000 contributors.

Where does CPAN install to?

CPAN doesn't actually install files. It runs the install script embedded in each distribution, which then performs the actual install. For distributions using ExtUtils::MakeMaker, the defaults are documented here: https://metacpan.org/pod/ExtUtils::MakeMaker#make-install (and the default value of INSTALLDIRS is site ).

What is the difference between CPAN and Cpanm?

The main difference between the two is that if you have Perl you should already have the cpan command. Whereas you won't have cpanm unless/until you install it.


3 Answers

The quick answer is that you want to use CPAN::Mini to create a local mirror of all that is current on the CPAN, and then CPAN::Mini::Inject to add your own distributions to it.

The long answer is that it helps to understand how a CPAN mirror is constructed. Broadly speaking, it is simply a directory that contains two sub-directories.

The 'modules' directory contains in turn two files, 03modlist.data.gz, whose contents is ignored by modern CPAN clients but there's legacy code that assumes this file exists, so just copy it from an existing mirror. The other is 02packages.details.txt.gz, which I shall describe later.

The 'authors' directory contains a file '01mailrc.txt.gz' which is another relic of the past whose contents can be ignored, so just copy it from another mirror, and it contains the 'id' directory. This in turn contains sub-directories and distributions, whose names follow a pattern. For example, my PAUSE id is DCANTRELL, and one of my distributions is XML-Tiny-2.06.tar.gz, so that file lives at .../authors/id/D/DC/DCANTRELL/XML-Tiny-2.06.tar.gz.

The 02packages.details.txt.gz file is the index that maps module names to distributions, and this must be up to date for your mirror to work properly. It consists of a few header lines, which must be present and correct, followed by a blank line, followed by one line for each module. Those lines are three fields separated by spaces:

  • module name
  • module version
  • distribution filename

eg

  XML::Tiny 2.06 D/DC/DCANTRELL/XML-Tiny-2.06.tar.gz

(you may also see .tgz, .zip, and a coupla others)

A distribution may appear in several lines, once for each module it contains. eg

  XML::Tiny::DOM 1.1 D/DC/DCANTRELL/XML-Tiny-DOM-1.1.tar.gz
  XML::Tiny::DOM::Element 1.1 D/DC/DCANTRELL/XML-Tiny-DOM-1.1.tar.gz

In a normal CPAN mirror, there may be several versions of a distribution, and several versions of a module - for example, the current version and a few older ones, or the current stable one and a dev one. The index file contains the most recent stable version. You can tell dev versions of distributions because they have an underscore in their version, or contain the string '-TRIAL'.

So, knowing all that, you can construct a CPAN-a-like that contains only your code. But using CPAN::Mini and CPAN::Mini::Inject to add your stuff to a "real" CPAN is less work.

Once you've created your CPAN-a-like, you can either expose it on HTTP and access it using any client as normal, or you could just have it in the filesystem and configure the CPAN client to access it using a file:/// URL.

like image 94
DrHyde Avatar answered Sep 21 '22 23:09

DrHyde


You might also consider Pinto. Pinto allows you to curate your own stable CPAN repository, which can contain any number of both public and private distributions. Pinto also helps you to manage change as your dependencies evolve over time.

like image 39
Jeffrey Ryan Thalhammer Avatar answered Sep 22 '22 23:09

Jeffrey Ryan Thalhammer


DrHyde gave a very nice answer to the question. But if you don't want to maintain a CPAN mirror, you can use MyCPAN::App::DPAN together with MyCPAN::Indexer.

Cave: Both distributions are under development. Not all combinations will work. What I use is the latest version of MyCPAN::App::DPAN on github (1.28_11) and MyCPAN::Indexer version 1.28_10 (later versions don't work with MyCPAN::App::DPAN).

MyCPAN::App::DPAN will create a CPAN-like directory structure on your local disk from the distributions you feed it. You will need to create a config file for it (say, .dpanrc):

# contents of .dpanrc
indexer_id  Edward Baudrez <[email protected]>
dpan_dir    /home/ebaudrez/rsync.net/dpan
merge_dirs  /home/ebaudrez/rsync.net/dpan/dists
report_dir  /home/ebaudrez/rsync.net/dpan/indexer_reports

Put your distribution tarballs in the directory merge_dirs (I think there's no reason that directory should reside under dpan_dir, but I'm too lazy to figure it out right now). Then call dpan:

dpan -f $HOME/.dpanrc

dpan will create a CPAN-like structure in dpan_dir (containing, in particular, authors and modules). This directory can then be used with cpanm (for instance):

cpanm --mirror $HOME/rsync.net/dpan --mirror http://search.cpan.org/CPAN

Note that I use real CPAN as fallback, because the DarkPAN is by definition incomplete. If you also happen to have a mini CPAN mirror, you can also use it here:

cpanm --mirror $HOME/rsync.net/dpan --mirror $HOME/mirrors/minicpan --mirror-only

Do note that, for this scheme to work, you will need to create distribution tarballs from your source code. I like and use Dist::Zilla, but note that you can also generate tarballs from Makefile.PL, so you definitely don't need to use Dist::Zilla. But it takes care of a lot of the details.

Creating a real distribution from your source code may seem like a lot of work, but Dist::Zilla helps lift the burden, and the transition to a real CPAN module, some day in the future ;-), is also simplified a lot when you already have a distribution.

like image 44
Edward Avatar answered Sep 23 '22 23:09

Edward