<?xml version="1.0" encoding="windows-1252"?>
<node id="1000256" title="Check the dependencies of modules you want to install" created="2012-10-21 23:50:01" updated="2012-10-21 23:50:01">
<type id="1042">
CUFP</type>
<author id="925806">
thomas895</author>
<data>
<field name="doctext">
&lt;p&gt;
Sometimes, when choosing between distributions to install, it helps to see what you need to install, before you actually install it. CPAN Dependencies is a great utility for this, but it's helpful to have something extra: to be able to see what you still need to install. This way, you can predict how long it will take for something to install.&lt;br /&gt;
That information is useful to me, because I hate waiting. If there's a distribution that can do the same or similar thing with less dependencies, then I'm more likely to use that.
&lt;p&gt;
Today, I decided to make a little solution for that. It's not very elabourate or perfect, but I hope it will be of use to whoever stumbles across it.
&lt;/p&gt;
&lt;readmore&gt;
&lt;code&gt;
#!/usr/bin/perl -w

use strict;
use warnings;
use Config;
use LWP::Simple;
use XML::LibXML;
use Text::Table;

#use Data::Dumper qw( Dumper );

use constant CPANDEPS_API_TEMPLATE =&gt;
    'http://deps.cpantesters.org/?xml=1;module=%s' . ';perl=%s;pureperl=0;os=%s';

#Get the module name
my $wanted_module = shift || die("No module name specified!");

#Get the archname
my $archname = "any+OS";
$archname = "Linux" if ( $Config{archname} =~ /linux/ );
$archname = 'Windows+%28Win32%29' if ( $Config{archname} =~ /^MSWin32/ );

#Get the XML for this module
print STDERR "Getting XML...\n";
my $xml_url =
    sprintf( CPANDEPS_API_TEMPLATE, $wanted_module, $Config{version},
    $archname );
my $xml_data = LWP::Simple::get($xml_url);

#Place that into LibXML
my $doc = XML::LibXML-&gt;new-&gt;load_xml( { string =&gt; $xml_data } );

#Get a list of all the required modules
print STDERR "Parsing XML...\n";
my @deps = $doc-&gt;getElementsByTagName("dependency");

#print Dumper \@deps;

#Try to require() each one
my %statuses = (
    installed =&gt; [],
    missing   =&gt; [] );
foreach (@deps) {

    #Get the module name
    my $required_module =
        [ $_-&gt;getElementsByTagName("module") ]-&gt;[0]-&gt;string_value();

    #print Dumper [ $_-&gt;getElementsByTagName("module") ]-&gt;[0];

    eval("require $required_module;");
    my $col = $@ ? "missing" : "installed";
    push( @{ $statuses{$col} }, $required_module );

}

#Now, we can show which ones we have and don't have
print STDERR "Making table...\n";
my $table = Text::Table-&gt;new(qw/ Installed Missing /);

#Create lines for the headers
$table-&gt;load( [ map { "-" x length($_) } qw/ Installed Missing / ] );

#Write table
my $i = 0;
while (1) {
    last unless ( $statuses{installed}-&gt;[$i] || $statuses{missing}-&gt;[$i] );
    $table-&gt;load(
        [ $statuses{installed}-&gt;[$i] || "", $statuses{missing}-&gt;[$i] || "" ] );
    $i++;
}

print "\n$table";
&lt;/code&gt;
&lt;p&gt;
You need [cpan://XML::LibXML], [cpan://LWP::Simple], and [cpan://Text::Table]. Yes, it could have been done with less, but those happened to be the first things that came to mind.
&lt;/p&gt;
&lt;/readmore&gt;

&lt;div class="pmsig"&gt;&lt;div class="pmsig-925806"&gt;
&lt;pre&gt;
~[node://thomas895|Thomas]~ &lt;br /&gt;
"Excuse me for butting in, but I'm interrupt-driven..."
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;</field>
</data>
</node>
