The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

CPAN::Dependency - Analyzes CPAN modules and generates their dependency tree

VERSION

Version 0.16

SYNOPSIS

Find and print the 10 most required CPAN distributions by stand-alone processing.

    use CPAN::Dependency;

    my $cpandep = CPAN::Dependency->new(process => ALL_CPAN);
    $cpandep->run;  # this may take some time..
    $cpandep->calculate_score;

    my %score = $cpandep->score_by_dists;
    my @dists = sort { $score{$b} <=> $score{$a} } keys %score;
    print "Top 10 modules\n";
    for my $dist (@dists[0..9]) {
        printf "%5d %s\n", $score{$dist}, $dist;
    }

Same thing, but this time by loading the prerequisites information from the CPANTS database.

    use CPAN::Dependency;
    my $cpandep = new CPAN::Dependency;
    $cpandep->load_cpants_db(file => 'cpants.db');
    $cpandep->calculate_score;

    my %score = $cpandep->score_by_dists;
    my @dists = sort { $score{$b} <=> $score{$a} } keys %score;
    print "Top 10 modules\n";
    for my $dist (@dists[0..9]) {
        printf "%5d %s\n", $score{$dist}, $dist;
    }

DESCRIPTION

Please note that this module is no longer maintained. Check "See ALSO" for similar, more recent modules.

This module can process a set of distributions, up to the whole CPAN, and extract the dependency relations between these distributions. Alternatively, it can load the prerequisites information from a CPANTS database.

It also calculates a score for each distribution based on the number of times it appears in the prerequisites of other distributions. The algorithm is described in more details in "SCORE CALCULATION".

CPAN::Dependency stores the data in an internal structure which can be saved and loaded using save_deps_tree() and load_deps_tree(). The structure looks like this:

    DEPS_TREE = {
        DIST => {
            author => STRING, 
            cpanid => STRING, 
            score  => NUMBER, 
            prereqs => {
                DIST => BOOLEAN, 
                ...
            }, 
            used_by => {
                DIST => BOOLEAN, 
                ...
            }, 
        }, 
        ....
    }

With each distribution name DIST are associated the following fields:

  • author is a string which contains the name of the author who wrote (or last released) this distribution;

  • cpanid is a string which contains the CPAN ID of the author who wrote (or last released) this distribution;

  • score is a number which represents the score of the distribution;

  • prereqs is a hashref which represents the prerequisites of the distribution; each key is a prerequisite name and its value is a boolean which is true when the distribution and the prerequisite are not from the same author;

  • used_by is a hashref which represents the distributions which use this particular distribution; each key is a distribution name and its value is a boolean which is true when both distributions are not from the same author;

METHODS

new()

Creates and returns a new object.

Options

  • process - adds modules or distributions to the list of packages to process.

  • skip - adds modules or distributions you don't want to process.

  • clean_build_dir - control whether to delete the CPANPLUS directory during the process or not.

  • color - use colors (when verbose is also set).

  • debug - sets debug level.

  • prefer_bin - tells CPANPLUS to prefer binaries programs.

  • verbose - sets the verbose mode.

Examples

Creates a new CPAN::Dependency object with verbose mode enabled and adds a few "big" modules to the process list:

    my $cpandep = new CPAN::Dependency verbose => 1, 
            process => [qw(WWW::Mechanize Maypole Template CPAN::Search::Lite)]

Creates a new CPAN::Dependency object with verbose mode enabled and adds all the distributions from the CPAN to the process list:

    my $cpandep = new CPAN::Dependency verbose => 1, process => ALL_CPAN;
process()

Adds given distribution or module names to the list of packages to process. The special argument ALL_CPAN can be used to specify that you want to process all packages in the CPAN.

Examples

Add distributions and modules to the process list, passing as a list:

    $cpandep->process('WWW::Mechanize', 'Maypole', 'CPAN-Search-Lite');

Add distributions and modules to the process list, passing as an arrayref:

    $cpandep->process(['WWW-Mechanize', 'Maypole::Application', 'CPAN::Search::Lite']);
skip()

Adds given distribution or module names to the list of packages that you don't want to process.

Examples

Add distributions and modules to the skip list, passing as a list:

    $cpandep->skip('LWP::UserAgent', 'Net_SSLeay.pm', 'CGI');

Add distributions and modules to the skip list, passing as an arrayref:

    $cpandep->skip(['libwww-perl', 'Net::SSLeay', 'CGI.pm']);
run()

Launches the execution of the CPAN::Dependency object.

calculate_score()

Calculate the score of each distribution by walking through the dependency tree.

deps_by_dists()

Return the hashref of the object that contains the dependency tree indexed by distribution names.

score_by_dists()

Returns a new hash that contains the score of the processed distributions, indexed by the distribution names.

save_deps_tree()

Saves the dependency tree of the object to a YAML stream. Expect one of the following options.

Options

  • file - saves to the given YAML file.

Examples

    $cpandep->save_deps_tree(file => 'deps.yml');
load_deps_tree()

Loads a YAML stream that contains a dependency tree into the current object. Expect one of the following options.

Options

  • file - loads from the given YAML file.

Examples

    $cpandep->load_deps_tree(file => 'deps.yml');
load_cpants_db()

CPANTS support is currently broken.

Loads the prerequisites information from the given CPANTS database. Expects one of the following options.

Options

  • file - loads from the given file.

Examples

    $cpandep->load_cpants_db(file => 'cpants.db');

Internal Methods

_tree_walk()

Walks through the dependency tree and updates the score of each distribution. See "SCORE CALCULATION".

_vprint()

Like print() but prints only when option verbose is set.

_vprintf()

Like printf() but prints only when option verbose is set.

OPTIONS

clean_build_dir()

Control whether to delete the CPANPLUS build directory during the processing of the selected modules or not. This is a quite aggressive method to clean up things, but it's needed when processing the whole CPAN because some distributions are badly made, and some may be just too big for a ramdisk. Default to false (0).

color()

Selects whether to use ANSI colors or not when verbose is enabled. Defaults to yes (1).

debug()

Set debug level. Defaults to 0.

prefer_bin()

Tells CPANPLUS to use binary programs instead of Perl modules when there is the choice (i.e. use tar(1) instead of Archive::Tar).

verbose()

Sets verbose mode to on (1) or off (0). Defaults to off.

SCORE CALCULATION

Once the prerequisites for each distribution have been found, the score of each distribution is calculated using the following algorithm:

  1. for each distribution D

  2. for each prerequisite P of this distribution

  3. if both D and P are not made by the same author, update the score of P by adding it the current dependency depth

  4. recurse step 1 using P

The aim of this algorithm is to increase the score of distributions that are depended upon by many other distributions, while avoiding the cases where one author releases a horde of modules which depend upon each others.

PROCESSING NOTES

CPAN::Dependency uses CPANPLUS when processing CPAN distributions, which means that you need to configure CPANPLUS for the account that will run the CPAN::Dependency based scripts. Simply execute the cpanp(1) for this. If the account is not supposed to have access to the Internet, use a mini-CPAN mirror. See also "Local mirror".

SPEED TIPS

Here are a few tips to speed up the processing when you want to process many modules (or the whole CPAN).

Local mirror

If it's not the case yet, you should use CPAN::Mini to create your own mini-CPAN local mirror. Then you just need to configure CPANPLUS to use your mini-CPAN instead of a network mirror. A mini-CPAN can also be shared using a web server but if you want speed, you should keep one on your local filesystem.

Note that you can also add your own private distributions into your mini-CPAN using CPAN::Mini::Inject. This is useful if you want to use CPAN::Dependency on modules that are not publicly shared on the CPAN.

For more information see CPAN::Mini and CPAN::Mini::Inject.

Ramdisk

If your system supports this feature (most modern systems do), you should create a ramdisk and move the CPANPLUS build directory onto the ramdisk. Here are the instructions for Linux. Other systems are left as an exercise for the reader :-)

Ramdisk for Linux

The following commands must be executed as root. cpanplus is assumed to be the user that will executes this module.

  • Create a ramdisk of 32 MB:

        dd if=/dev/zero of=/dev/ram0 bs=1M count=32
  • Format it and creates an Ext2 filesystem:

        mke2fs -L ramdisk0 /dev/ram0
  • Now mount it:

        mkdir /mnt/ramdisk
        mount /dev/ram0 /mnt/ramdisk/
        mkdir /mnt/ramdisk/cpanplus
        chown cpanplus /mnt/ramdisk/cpanplus/
  • Now, as the user cpanplus, move the build directory onto the ramdisk and symlink it:

        mv .cpanplus/5.8.5 /mnt/ramdisk/cpanplus/
        ln -s /mnt/ramdisk/cpanplus/5.8.5 .cpanplus/5.8.5

Note that we are explicitly avoiding to move the whole .cpanplus/ directory because it will grow really big during the processing: some CPANPLUS cache files are already big, and the sub-directory author/ will contain a copy of each processed archive. When processing the whole CPAN, it means that you'll have here a complete copy of your mini-CPAN, so be sure that you have enough disk space (or symlink this directory as well to another volume when you have enough space).

Ramdisk for Mac OS X

Here is a small shell script that creates, format and mount a ramdisk of 64 MB. Its size can be changed by changing the number of blocks, where one block is 512 bytes. This is a version for OS X.5 and newer:

    #!/bin/sh
    BLOCK=128000
    diskutil erasevolume HFS+ "ramdisk" `hdiutil attach -nomount ram://$BLOCKS`

and here is a version for OS X.4 and previous:

    #!/bin/sh
    BLOCK=128000
    dev=`hdid -nomount ram://$BLOCKS`
    newfs_hfs -v RAMDisk $dev
    mkdir /Volumes/RAMDisk
    chmod 777 /Volumes/RAMDisk
    mount -t hfs $dev /Volumes/RAMDisk

Then follow the same instructions for moving the build/ directory as given for Linux.

Ramdisk for Solaris

Beginning with Solaris 9 12/03, Solaris includes a ramdiskadm(1M) command for managing ramdisks. Below are the links for the documentation of that command.

Ramdisks can also be created in previous versions of Solaris using a pseudo-device. Below are the links for the corresponding documentation.

Ramdisk for FreeBSD

Based on http://freebsdwiki.net/index.php/RAMdisks,_creating_under_FreeBSD_5.x, the following commands should create a 256 megabytes ramdisk under FreeBSD 5.x.

    /sbin/mdconfig -a -t malloc -s 256M -u 10
    /sbin/newfs -U /dev/md10
    /sbin/mount /dev/md10 /mnt/ramdisk

The equivalent script using vnconfig(8) for FreeBSD 4.x is left as an exercise for the reader.

Ramdisk for Windows

It seems there is no built-in mechanism or tool for creating a ramdisk under Windows, but the following links give a few ways to do so.

DIAGNOSTICS

Can't create CPANPLUS::Backend object

(F) CPANPLUS::Backend was unable to create and return a new object.

Can't find file '%s'

(F) The file given in argument could not be found.

Can't read SQLite database: %s

(F) The SQLite database could not be read by the DBI driver. Details follow. The message "file is encrypted or is not a database(1)" usually means that the is not an SQLite database or not in a version handled by the available DBD::SQLite module.

No argument given to attribute %s

(W) As the message implies, you didn't supply the expected argument to the attribute.

No argument given to function %s

(W) As the message implies, you didn't supply the expected arguments to the function.

Unknown option '%s': ignoring

(W) You gave to new() an unknown attribute name.

SEE ALSO

Similar modules

CPAN::dependency was more a experiment at a given time (in 2005, for the CPAN Phalanx project), and there are now more recent modules on the CPAN in the same field, but with more features:

CPAN::FindDependencies - Find dependencies for modules on the CPAN

The CPANTS modules: Module::CPANTS::Analyse, Module::CPANTS::ProcessCPAN (see also http://cpants.perl.org/)

Module::Dependency - Find generic dependencies for Perl programs and modules (not restricted to the CPAN)

Graph::Dependency - Generate dependency graphs and reports

CPANPLUS::Backend

CPAN::Mini

CPAN::Mini::Inject

AUTHOR

Sébastien Aperghis-Tramoni, <sebastien@aperghis.net>

BUGS

Please report any bugs or feature requests to bug-cpan-dependency@rt.cpan.org, or through the web interface at https://rt.cpan.org/NoAuth/Bugs.html?Dist=CPAN-Dependency. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

COPYRIGHT & LICENSE

Copyright 2005 Sébastien Aperghis-Tramoni, All Rights Reserved.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.