703 lines
22 KiB
Perl
703 lines
22 KiB
Perl
# -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
|
|
# vim: ts=4 sts=4 sw=4:
|
|
package CPAN::Module;
|
|
use strict;
|
|
@CPAN::Module::ISA = qw(CPAN::InfoObj);
|
|
|
|
use vars qw(
|
|
$VERSION
|
|
);
|
|
$VERSION = "5.5003";
|
|
|
|
BEGIN {
|
|
# alarm() is not implemented in perl 5.6.x and earlier under Windows
|
|
*ALARM_IMPLEMENTED = sub () { $] >= 5.007 || $^O !~ /MSWin/ };
|
|
}
|
|
|
|
# Accessors
|
|
#-> sub CPAN::Module::userid
|
|
sub userid {
|
|
my $self = shift;
|
|
my $ro = $self->ro;
|
|
return unless $ro;
|
|
return $ro->{userid} || $ro->{CPAN_USERID};
|
|
}
|
|
#-> sub CPAN::Module::description
|
|
sub description {
|
|
my $self = shift;
|
|
my $ro = $self->ro or return "";
|
|
$ro->{description}
|
|
}
|
|
|
|
#-> sub CPAN::Module::distribution
|
|
sub distribution {
|
|
my($self) = @_;
|
|
CPAN::Shell->expand("Distribution",$self->cpan_file);
|
|
}
|
|
|
|
#-> sub CPAN::Module::_is_representative_module
|
|
sub _is_representative_module {
|
|
my($self) = @_;
|
|
return $self->{_is_representative_module} if defined $self->{_is_representative_module};
|
|
my $pm = $self->cpan_file or return $self->{_is_representative_module} = 0;
|
|
$pm =~ s|.+/||;
|
|
$pm =~ s{\.(?:tar\.(bz2|gz|Z)|t(?:gz|bz)|zip)$}{}i; # see base_id
|
|
$pm =~ s|-\d+\.\d+.+$||;
|
|
$pm =~ s|-[\d\.]+$||;
|
|
$pm =~ s/-/::/g;
|
|
$self->{_is_representative_module} = $pm eq $self->{ID} ? 1 : 0;
|
|
# warn "DEBUG: $pm eq $self->{ID} => $self->{_is_representative_module}";
|
|
$self->{_is_representative_module};
|
|
}
|
|
|
|
#-> sub CPAN::Module::undelay
|
|
sub undelay {
|
|
my $self = shift;
|
|
delete $self->{later};
|
|
if ( my $dist = CPAN::Shell->expand("Distribution", $self->cpan_file) ) {
|
|
$dist->undelay;
|
|
}
|
|
}
|
|
|
|
# mark as dirty/clean
|
|
#-> sub CPAN::Module::color_cmd_tmps ;
|
|
sub color_cmd_tmps {
|
|
my($self) = shift;
|
|
my($depth) = shift || 0;
|
|
my($color) = shift || 0;
|
|
my($ancestors) = shift || [];
|
|
# a module needs to recurse to its cpan_file
|
|
|
|
return if exists $self->{incommandcolor}
|
|
&& $color==1
|
|
&& $self->{incommandcolor}==$color;
|
|
return if $color==0 && !$self->{incommandcolor};
|
|
if ($color>=1) {
|
|
if ( $self->uptodate ) {
|
|
$self->{incommandcolor} = $color;
|
|
return;
|
|
} elsif (my $have_version = $self->available_version) {
|
|
# maybe what we have is good enough
|
|
if (@$ancestors) {
|
|
my $who_asked_for_me = $ancestors->[-1];
|
|
my $obj = CPAN::Shell->expandany($who_asked_for_me);
|
|
if (0) {
|
|
} elsif ($obj->isa("CPAN::Bundle")) {
|
|
# bundles cannot specify a minimum version
|
|
return;
|
|
} elsif ($obj->isa("CPAN::Distribution")) {
|
|
if (my $prereq_pm = $obj->prereq_pm) {
|
|
for my $k (keys %$prereq_pm) {
|
|
if (my $want_version = $prereq_pm->{$k}{$self->id}) {
|
|
if (CPAN::Version->vcmp($have_version,$want_version) >= 0) {
|
|
$self->{incommandcolor} = $color;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
$self->{incommandcolor} = $color; # set me before recursion,
|
|
# so we can break it
|
|
}
|
|
if ($depth>=$CPAN::MAX_RECURSION) {
|
|
my $e = CPAN::Exception::RecursiveDependency->new($ancestors);
|
|
if ($e->is_resolvable) {
|
|
return $self->{incommandcolor}=2;
|
|
} else {
|
|
die $e;
|
|
}
|
|
}
|
|
# warn "color_cmd_tmps $depth $color " . $self->id; # sleep 1;
|
|
|
|
if ( my $dist = CPAN::Shell->expand("Distribution", $self->cpan_file) ) {
|
|
$dist->color_cmd_tmps($depth+1,$color,[@$ancestors, $self->id]);
|
|
}
|
|
# unreached code?
|
|
# if ($color==0) {
|
|
# delete $self->{badtestcnt};
|
|
# }
|
|
$self->{incommandcolor} = $color;
|
|
}
|
|
|
|
#-> sub CPAN::Module::as_glimpse ;
|
|
sub as_glimpse {
|
|
my($self) = @_;
|
|
my(@m);
|
|
my $class = ref($self);
|
|
$class =~ s/^CPAN:://;
|
|
my $color_on = "";
|
|
my $color_off = "";
|
|
if (
|
|
$CPAN::Shell::COLOR_REGISTERED
|
|
&&
|
|
$CPAN::META->has_inst("Term::ANSIColor")
|
|
&&
|
|
$self->description
|
|
) {
|
|
$color_on = Term::ANSIColor::color("green");
|
|
$color_off = Term::ANSIColor::color("reset");
|
|
}
|
|
my $uptodateness = " ";
|
|
unless ($class eq "Bundle") {
|
|
my $u = $self->uptodate;
|
|
$uptodateness = $u ? "=" : "<" if defined $u;
|
|
};
|
|
my $id = do {
|
|
my $d = $self->distribution;
|
|
$d ? $d -> pretty_id : $self->cpan_userid;
|
|
};
|
|
push @m, sprintf("%-7s %1s %s%-22s%s (%s)\n",
|
|
$class,
|
|
$uptodateness,
|
|
$color_on,
|
|
$self->id,
|
|
$color_off,
|
|
$id,
|
|
);
|
|
join "", @m;
|
|
}
|
|
|
|
#-> sub CPAN::Module::dslip_status
|
|
sub dslip_status {
|
|
my($self) = @_;
|
|
my($stat);
|
|
# development status
|
|
@{$stat->{D}}{qw,i c a b R M S,} = qw,idea
|
|
pre-alpha alpha beta released
|
|
mature standard,;
|
|
# support level
|
|
@{$stat->{S}}{qw,m d u n a,} = qw,mailing-list
|
|
developer comp.lang.perl.*
|
|
none abandoned,;
|
|
# language
|
|
@{$stat->{L}}{qw,p c + o h,} = qw,perl C C++ other hybrid,;
|
|
# interface
|
|
@{$stat->{I}}{qw,f r O p h n,} = qw,functions
|
|
references+ties
|
|
object-oriented pragma
|
|
hybrid none,;
|
|
# public licence
|
|
@{$stat->{P}}{qw,p g l b a 2 o d r n,} = qw,Standard-Perl
|
|
GPL LGPL
|
|
BSD Artistic Artistic_2
|
|
open-source
|
|
distribution_allowed
|
|
restricted_distribution
|
|
no_licence,;
|
|
for my $x (qw(d s l i p)) {
|
|
$stat->{$x}{' '} = 'unknown';
|
|
$stat->{$x}{'?'} = 'unknown';
|
|
}
|
|
my $ro = $self->ro;
|
|
return +{} unless $ro && $ro->{statd};
|
|
return {
|
|
D => $ro->{statd},
|
|
S => $ro->{stats},
|
|
L => $ro->{statl},
|
|
I => $ro->{stati},
|
|
P => $ro->{statp},
|
|
DV => $stat->{D}{$ro->{statd}},
|
|
SV => $stat->{S}{$ro->{stats}},
|
|
LV => $stat->{L}{$ro->{statl}},
|
|
IV => $stat->{I}{$ro->{stati}},
|
|
PV => $stat->{P}{$ro->{statp}},
|
|
};
|
|
}
|
|
|
|
#-> sub CPAN::Module::as_string ;
|
|
sub as_string {
|
|
my($self) = @_;
|
|
my(@m);
|
|
CPAN->debug("$self entering as_string") if $CPAN::DEBUG;
|
|
my $class = ref($self);
|
|
$class =~ s/^CPAN:://;
|
|
local($^W) = 0;
|
|
push @m, $class, " id = $self->{ID}\n";
|
|
my $sprintf = " %-12s %s\n";
|
|
push @m, sprintf($sprintf, 'DESCRIPTION', $self->description)
|
|
if $self->description;
|
|
my $sprintf2 = " %-12s %s (%s)\n";
|
|
my($userid);
|
|
$userid = $self->userid;
|
|
if ( $userid ) {
|
|
my $author;
|
|
if ($author = CPAN::Shell->expand('Author',$userid)) {
|
|
my $email = "";
|
|
my $m; # old perls
|
|
if ($m = $author->email) {
|
|
$email = " <$m>";
|
|
}
|
|
push @m, sprintf(
|
|
$sprintf2,
|
|
'CPAN_USERID',
|
|
$userid,
|
|
$author->fullname . $email
|
|
);
|
|
}
|
|
}
|
|
push @m, sprintf($sprintf, 'CPAN_VERSION', $self->cpan_version)
|
|
if $self->cpan_version;
|
|
if (my $cpan_file = $self->cpan_file) {
|
|
push @m, sprintf($sprintf, 'CPAN_FILE', $cpan_file);
|
|
if (my $dist = CPAN::Shell->expand("Distribution",$cpan_file)) {
|
|
my $upload_date = $dist->upload_date;
|
|
if ($upload_date) {
|
|
push @m, sprintf($sprintf, 'UPLOAD_DATE', $upload_date);
|
|
}
|
|
}
|
|
}
|
|
my $sprintf3 = " %-12s %1s%1s%1s%1s%1s (%s,%s,%s,%s,%s)\n";
|
|
my $dslip = $self->dslip_status;
|
|
push @m, sprintf(
|
|
$sprintf3,
|
|
'DSLIP_STATUS',
|
|
@{$dslip}{qw(D S L I P DV SV LV IV PV)},
|
|
) if $dslip->{D};
|
|
my $local_file = $self->inst_file;
|
|
unless ($self->{MANPAGE}) {
|
|
my $manpage;
|
|
if ($local_file) {
|
|
$manpage = $self->manpage_headline($local_file);
|
|
} else {
|
|
# If we have already untarred it, we should look there
|
|
my $dist = $CPAN::META->instance('CPAN::Distribution',
|
|
$self->cpan_file);
|
|
# warn "dist[$dist]";
|
|
# mff=manifest file; mfh=manifest handle
|
|
my($mff,$mfh);
|
|
if (
|
|
$dist->{build_dir}
|
|
and
|
|
(-f ($mff = File::Spec->catfile($dist->{build_dir}, "MANIFEST")))
|
|
and
|
|
$mfh = FileHandle->new($mff)
|
|
) {
|
|
CPAN->debug("mff[$mff]") if $CPAN::DEBUG;
|
|
my $lfre = $self->id; # local file RE
|
|
$lfre =~ s/::/./g;
|
|
$lfre .= "\\.pm\$";
|
|
my($lfl); # local file file
|
|
local $/ = "\n";
|
|
my(@mflines) = <$mfh>;
|
|
for (@mflines) {
|
|
s/^\s+//;
|
|
s/\s.*//s;
|
|
}
|
|
while (length($lfre)>5 and !$lfl) {
|
|
($lfl) = grep /$lfre/, @mflines;
|
|
CPAN->debug("lfl[$lfl]lfre[$lfre]") if $CPAN::DEBUG;
|
|
$lfre =~ s/.+?\.//;
|
|
}
|
|
$lfl =~ s/\s.*//; # remove comments
|
|
$lfl =~ s/\s+//g; # chomp would maybe be too system-specific
|
|
my $lfl_abs = File::Spec->catfile($dist->{build_dir},$lfl);
|
|
# warn "lfl_abs[$lfl_abs]";
|
|
if (-f $lfl_abs) {
|
|
$manpage = $self->manpage_headline($lfl_abs);
|
|
}
|
|
}
|
|
}
|
|
$self->{MANPAGE} = $manpage if $manpage;
|
|
}
|
|
my($item);
|
|
for $item (qw/MANPAGE/) {
|
|
push @m, sprintf($sprintf, $item, $self->{$item})
|
|
if exists $self->{$item};
|
|
}
|
|
for $item (qw/CONTAINS/) {
|
|
push @m, sprintf($sprintf, $item, join(" ",@{$self->{$item}}))
|
|
if exists $self->{$item} && @{$self->{$item}};
|
|
}
|
|
push @m, sprintf($sprintf, 'INST_FILE',
|
|
$local_file || "(not installed)");
|
|
push @m, sprintf($sprintf, 'INST_VERSION',
|
|
$self->inst_version) if $local_file;
|
|
if (%{$CPAN::META->{is_tested}||{}}) { # XXX needs to be methodified somehow
|
|
my $available_file = $self->available_file;
|
|
if ($available_file && $available_file ne $local_file) {
|
|
push @m, sprintf($sprintf, 'AVAILABLE_FILE', $available_file);
|
|
push @m, sprintf($sprintf, 'AVAILABLE_VERSION', $self->available_version);
|
|
}
|
|
}
|
|
join "", @m, "\n";
|
|
}
|
|
|
|
#-> sub CPAN::Module::manpage_headline
|
|
sub manpage_headline {
|
|
my($self,$local_file) = @_;
|
|
my(@local_file) = $local_file;
|
|
$local_file =~ s/\.pm(?!\n)\Z/.pod/;
|
|
push @local_file, $local_file;
|
|
my(@result,$locf);
|
|
for $locf (@local_file) {
|
|
next unless -f $locf;
|
|
my $fh = FileHandle->new($locf)
|
|
or $Carp::Frontend->mydie("Couldn't open $locf: $!");
|
|
my $inpod = 0;
|
|
local $/ = "\n";
|
|
while (<$fh>) {
|
|
$inpod = m/^=(?!head1\s+NAME\s*$)/ ? 0 :
|
|
m/^=head1\s+NAME\s*$/ ? 1 : $inpod;
|
|
next unless $inpod;
|
|
next if /^=/;
|
|
next if /^\s+$/;
|
|
chomp;
|
|
push @result, $_;
|
|
}
|
|
close $fh;
|
|
last if @result;
|
|
}
|
|
for (@result) {
|
|
s/^\s+//;
|
|
s/\s+$//;
|
|
}
|
|
join " ", @result;
|
|
}
|
|
|
|
#-> sub CPAN::Module::cpan_file ;
|
|
# Note: also inherited by CPAN::Bundle
|
|
sub cpan_file {
|
|
my $self = shift;
|
|
# CPAN->debug(sprintf "id[%s]", $self->id) if $CPAN::DEBUG;
|
|
unless ($self->ro) {
|
|
CPAN::Index->reload;
|
|
}
|
|
my $ro = $self->ro;
|
|
if ($ro && defined $ro->{CPAN_FILE}) {
|
|
return $ro->{CPAN_FILE};
|
|
} else {
|
|
my $userid = $self->userid;
|
|
if ( $userid ) {
|
|
if ($CPAN::META->exists("CPAN::Author",$userid)) {
|
|
my $author = $CPAN::META->instance("CPAN::Author",
|
|
$userid);
|
|
my $fullname = $author->fullname;
|
|
my $email = $author->email;
|
|
unless (defined $fullname && defined $email) {
|
|
return sprintf("Contact Author %s",
|
|
$userid,
|
|
);
|
|
}
|
|
return "Contact Author $fullname <$email>";
|
|
} else {
|
|
return "Contact Author $userid (Email address not available)";
|
|
}
|
|
} else {
|
|
return "N/A";
|
|
}
|
|
}
|
|
}
|
|
|
|
#-> sub CPAN::Module::cpan_version ;
|
|
sub cpan_version {
|
|
my $self = shift;
|
|
|
|
my $ro = $self->ro;
|
|
unless ($ro) {
|
|
# Can happen with modules that are not on CPAN
|
|
$ro = {};
|
|
}
|
|
$ro->{CPAN_VERSION} = 'undef'
|
|
unless defined $ro->{CPAN_VERSION};
|
|
$ro->{CPAN_VERSION};
|
|
}
|
|
|
|
#-> sub CPAN::Module::force ;
|
|
sub force {
|
|
my($self) = @_;
|
|
$self->{force_update} = 1;
|
|
}
|
|
|
|
#-> sub CPAN::Module::fforce ;
|
|
sub fforce {
|
|
my($self) = @_;
|
|
$self->{force_update} = 2;
|
|
}
|
|
|
|
#-> sub CPAN::Module::notest ;
|
|
sub notest {
|
|
my($self) = @_;
|
|
# $CPAN::Frontend->mywarn("XDEBUG: set notest for Module");
|
|
$self->{notest}++;
|
|
}
|
|
|
|
#-> sub CPAN::Module::rematein ;
|
|
sub rematein {
|
|
my($self,$meth) = @_;
|
|
$CPAN::Frontend->myprint(sprintf("Running %s for module '%s'\n",
|
|
$meth,
|
|
$self->id));
|
|
my $cpan_file = $self->cpan_file;
|
|
if ($cpan_file eq "N/A" || $cpan_file =~ /^Contact Author/) {
|
|
$CPAN::Frontend->mywarn(sprintf qq{
|
|
The module %s isn\'t available on CPAN.
|
|
|
|
Either the module has not yet been uploaded to CPAN, or it is
|
|
temporary unavailable. Please contact the author to find out
|
|
more about the status. Try 'i %s'.
|
|
},
|
|
$self->id,
|
|
$self->id,
|
|
);
|
|
return;
|
|
}
|
|
my $pack = $CPAN::META->instance('CPAN::Distribution',$cpan_file);
|
|
$pack->called_for($self->id);
|
|
if (exists $self->{force_update}) {
|
|
if ($self->{force_update} == 2) {
|
|
$pack->fforce($meth);
|
|
} else {
|
|
$pack->force($meth);
|
|
}
|
|
}
|
|
$pack->notest($meth) if exists $self->{notest} && $self->{notest};
|
|
|
|
$pack->{reqtype} ||= "";
|
|
CPAN->debug("dist-reqtype[$pack->{reqtype}]".
|
|
"self-reqtype[$self->{reqtype}]") if $CPAN::DEBUG;
|
|
if ($pack->{reqtype}) {
|
|
if ($pack->{reqtype} eq "b" && $self->{reqtype} =~ /^[rc]$/) {
|
|
$pack->{reqtype} = $self->{reqtype};
|
|
if (
|
|
exists $pack->{install}
|
|
&&
|
|
(
|
|
UNIVERSAL::can($pack->{install},"failed") ?
|
|
$pack->{install}->failed :
|
|
$pack->{install} =~ /^NO/
|
|
)
|
|
) {
|
|
delete $pack->{install};
|
|
$CPAN::Frontend->mywarn
|
|
("Promoting $pack->{ID} from 'build_requires' to 'requires'");
|
|
}
|
|
}
|
|
} else {
|
|
$pack->{reqtype} = $self->{reqtype};
|
|
}
|
|
|
|
my $success = eval {
|
|
$pack->$meth();
|
|
};
|
|
my $err = $@;
|
|
$pack->unforce if $pack->can("unforce") && exists $self->{force_update};
|
|
$pack->unnotest if $pack->can("unnotest") && exists $self->{notest};
|
|
delete $self->{force_update};
|
|
delete $self->{notest};
|
|
if ($err) {
|
|
die $err;
|
|
}
|
|
return $success;
|
|
}
|
|
|
|
#-> sub CPAN::Module::perldoc ;
|
|
sub perldoc { shift->rematein('perldoc') }
|
|
#-> sub CPAN::Module::readme ;
|
|
sub readme { shift->rematein('readme') }
|
|
#-> sub CPAN::Module::look ;
|
|
sub look { shift->rematein('look') }
|
|
#-> sub CPAN::Module::cvs_import ;
|
|
sub cvs_import { shift->rematein('cvs_import') }
|
|
#-> sub CPAN::Module::get ;
|
|
sub get { shift->rematein('get',@_) }
|
|
#-> sub CPAN::Module::make ;
|
|
sub make { shift->rematein('make') }
|
|
#-> sub CPAN::Module::test ;
|
|
sub test {
|
|
my $self = shift;
|
|
# $self->{badtestcnt} ||= 0;
|
|
$self->rematein('test',@_);
|
|
}
|
|
|
|
#-> sub CPAN::Module::deprecated_in_core ;
|
|
sub deprecated_in_core {
|
|
my ($self) = @_;
|
|
return unless $CPAN::META->has_inst('Module::CoreList') && Module::CoreList->can('is_deprecated');
|
|
return Module::CoreList::is_deprecated($self->{ID});
|
|
}
|
|
|
|
#-> sub CPAN::Module::inst_deprecated;
|
|
# Indicates whether the *installed* version of the module is a deprecated *and*
|
|
# installed as part of the Perl core library path
|
|
sub inst_deprecated {
|
|
my ($self) = @_;
|
|
my $inst_file = $self->inst_file or return;
|
|
return $self->deprecated_in_core && $self->_in_priv_or_arch($inst_file);
|
|
}
|
|
|
|
#-> sub CPAN::Module::uptodate ;
|
|
sub uptodate {
|
|
my ($self) = @_;
|
|
local ($_);
|
|
my $inst = $self->inst_version or return 0;
|
|
my $cpan = $self->cpan_version;
|
|
return 0 if CPAN::Version->vgt($cpan,$inst) || $self->inst_deprecated;
|
|
CPAN->debug
|
|
(join
|
|
("",
|
|
"returning uptodate. ",
|
|
"cpan[$cpan]inst[$inst]",
|
|
)) if $CPAN::DEBUG;
|
|
return 1;
|
|
}
|
|
|
|
# returns true if installed in privlib or archlib
|
|
sub _in_priv_or_arch {
|
|
my($self,$inst_file) = @_;
|
|
foreach my $pair (
|
|
[qw(sitearchexp archlibexp)],
|
|
[qw(sitelibexp privlibexp)]
|
|
) {
|
|
my ($site, $priv) = @Config::Config{@$pair};
|
|
if ($^O eq 'VMS') {
|
|
for my $d ($site, $priv) { $d = VMS::Filespec::unixify($d) };
|
|
}
|
|
s!/*$!!g foreach $site, $priv;
|
|
next if $site eq $priv;
|
|
|
|
if ($priv eq substr($inst_file,0,length($priv))) {
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
#-> sub CPAN::Module::install ;
|
|
sub install {
|
|
my($self) = @_;
|
|
my($doit) = 0;
|
|
if ($self->uptodate
|
|
&&
|
|
not exists $self->{force_update}
|
|
) {
|
|
$CPAN::Frontend->myprint(sprintf("%s is up to date (%s).\n",
|
|
$self->id,
|
|
$self->inst_version,
|
|
));
|
|
} else {
|
|
$doit = 1;
|
|
}
|
|
my $ro = $self->ro;
|
|
if ($ro && $ro->{stats} && $ro->{stats} eq "a") {
|
|
$CPAN::Frontend->mywarn(qq{
|
|
\n\n\n ***WARNING***
|
|
The module $self->{ID} has no active maintainer (CPAN support level flag 'abandoned').\n\n\n
|
|
});
|
|
$CPAN::Frontend->mysleep(5);
|
|
}
|
|
return $doit ? $self->rematein('install') : 1;
|
|
}
|
|
#-> sub CPAN::Module::clean ;
|
|
sub clean { shift->rematein('clean') }
|
|
|
|
#-> sub CPAN::Module::inst_file ;
|
|
sub inst_file {
|
|
my($self) = @_;
|
|
$self->_file_in_path([@INC]);
|
|
}
|
|
|
|
#-> sub CPAN::Module::available_file ;
|
|
sub available_file {
|
|
my($self) = @_;
|
|
my $sep = $Config::Config{path_sep};
|
|
my $perllib = $ENV{PERL5LIB};
|
|
$perllib = $ENV{PERLLIB} unless defined $perllib;
|
|
my @perllib = split(/$sep/,$perllib) if defined $perllib;
|
|
my @cpan_perl5inc;
|
|
if ($CPAN::Perl5lib_tempfile) {
|
|
my $yaml = CPAN->_yaml_loadfile($CPAN::Perl5lib_tempfile);
|
|
@cpan_perl5inc = @{$yaml->[0]{inc} || []};
|
|
}
|
|
$self->_file_in_path([@cpan_perl5inc,@perllib,@INC]);
|
|
}
|
|
|
|
#-> sub CPAN::Module::file_in_path ;
|
|
sub _file_in_path {
|
|
my($self,$path) = @_;
|
|
my($dir,@packpath);
|
|
@packpath = split /::/, $self->{ID};
|
|
$packpath[-1] .= ".pm";
|
|
if (@packpath == 1 && $packpath[0] eq "readline.pm") {
|
|
unshift @packpath, "Term", "ReadLine"; # historical reasons
|
|
}
|
|
foreach $dir (@$path) {
|
|
my $pmfile = File::Spec->catfile($dir,@packpath);
|
|
if (-f $pmfile) {
|
|
return $pmfile;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
#-> sub CPAN::Module::xs_file ;
|
|
sub xs_file {
|
|
my($self) = @_;
|
|
my($dir,@packpath);
|
|
@packpath = split /::/, $self->{ID};
|
|
push @packpath, $packpath[-1];
|
|
$packpath[-1] .= "." . $Config::Config{'dlext'};
|
|
foreach $dir (@INC) {
|
|
my $xsfile = File::Spec->catfile($dir,'auto',@packpath);
|
|
if (-f $xsfile) {
|
|
return $xsfile;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
#-> sub CPAN::Module::inst_version ;
|
|
sub inst_version {
|
|
my($self) = @_;
|
|
my $parsefile = $self->inst_file or return;
|
|
my $have = $self->parse_version($parsefile);
|
|
$have;
|
|
}
|
|
|
|
#-> sub CPAN::Module::inst_version ;
|
|
sub available_version {
|
|
my($self) = @_;
|
|
my $parsefile = $self->available_file or return;
|
|
my $have = $self->parse_version($parsefile);
|
|
$have;
|
|
}
|
|
|
|
#-> sub CPAN::Module::parse_version ;
|
|
sub parse_version {
|
|
my($self,$parsefile) = @_;
|
|
if (ALARM_IMPLEMENTED) {
|
|
my $timeout = (exists($CPAN::Config{'version_timeout'}))
|
|
? $CPAN::Config{'version_timeout'}
|
|
: 15;
|
|
alarm($timeout);
|
|
}
|
|
my $have = eval {
|
|
local $SIG{ALRM} = sub { die "alarm\n" };
|
|
MM->parse_version($parsefile);
|
|
};
|
|
if ($@) {
|
|
$CPAN::Frontend->mywarn("Error while parsing version number in file '$parsefile'\n");
|
|
}
|
|
alarm(0) if ALARM_IMPLEMENTED;
|
|
my $leastsanity = eval { defined $have && length $have; };
|
|
$have = "undef" unless $leastsanity;
|
|
$have =~ s/^ //; # since the %vd hack these two lines here are needed
|
|
$have =~ s/ $//; # trailing whitespace happens all the time
|
|
|
|
$have = CPAN::Version->readable($have);
|
|
|
|
$have =~ s/\s*//g; # stringify to float around floating point issues
|
|
$have; # no stringify needed, \s* above matches always
|
|
}
|
|
|
|
#-> sub CPAN::Module::reports
|
|
sub reports {
|
|
my($self) = @_;
|
|
$self->distribution->reports;
|
|
}
|
|
|
|
1;
|