On 4/28/05, Chip Turner <cturner(a)pattern.net> wrote:
>> Downloading from CPAN is, unfortunately, not an entirely
clean
>> operation.
>
> What does CPAN.pm do to accomplish this?
Lots. Remember the first time you installed CPAN.pm and it found
mirrors, used about six differnt modules to download from, prompted
you for lots of info, etc? It left its droppings in ~/.cpan of all
the decisions it made. In essence, basically you have to download an
index of cpan and inspect it to find what the latest version of a
module is, and then find the path to it. There seems to be no API to
do this cleanly against, say,
search.cpan.org. I've submitted a
nebulous feature request to s.c.o, but no telling how/when/if that
will work.
You can use CPAN to do this, here is some code I wrote to try and make
cpan2rpm recursively get modules from cpan, rpmbuild and the install
the rpm. It works fine on modules but did not work for distributions,
I believe this failure may be due to me having a mixed
threaded/non-threaded perl install <shiver>. Hopefully this may help
you.
This assumes you have CPAN setup, I ran the cpan shell and set it up,
no modules where installed using CPAN though. Also requires a few CPAN
modules, like CPAN::Dependency.
--snip cpan2rpm code ---
my $name = $info->{dist};
my $obj;
if($CPAN::META->exists('CPAN::Module',$name)){
cpan_get_deps($info, $name);
}
elsif($obj = CPAN::Shell->expand("Distribution",
"\/$name\/")){
die("Distributions not handled yet: $name\n"); # may
work on proper perl installs
}
elsif($obj = CPAN::Shell->expand("Bundle", "\/$name\/")){
die("Bundles not handled yet: $name\n");
}
else{
die("Unknow type for $name\n");
}
--end snip cpan2rpm code ---
# Get the dependencies for a module
sub cpan_get_deps {
my $info = shift;
my $name = shift || die("cpan_get_mod needs a name!\n");
use CPAN::Dependency;
my $cpandeps = CPAN::Dependency->new(process => $name);
$cpandeps->run; # this may take some time..
foreach my $modl ($cpandeps->deps_by_dists())
{
foreach my $parent (keys(%$modl)){
foreach my $name (keys(%{$modl->{$parent}->{prereqs}}))
{
$name =~ s/-/::/g;
$name =~ s/.pm//;
eval("use $name");
if($@){
cpan_get_mod($info, $name);
}
}
}
}
}
# Fetch a module
sub cpan_get_mod {
my $info = shift;
my $name = shift || die("cpan_get_mod needs a name!\n");
my $module = CPAN::Shell->expand("Module", $name) ||
die("Could not handle $name\n");
my $version = $module->cpan_version;
$module->get;
my $auth = CPAN::Shell->expand('Author', $module->userid);
my $author = $auth->fullname;
my @args=("cpan2rpm");
if($info{install}){
push(@args, "-i");
}
@args = (@args, "--author '$author'", "--version
'$version'",
$CPAN::Config->{cpan_home} . '/sources/authors/id/'
. $module->cpan_file);
my $cmd = join(" ", @args);
if(system($cmd) != 0){die("Could not process module: $name");}
chdir $info->{evaldir} || die "get_meta(): $!";
return(0);
}
Jeff Fearn