Alien-ROOT
view release on metacpan or search on metacpan
inc/inc_Module-Load-Conditional/Module/Load/Conditional.pm view on Meta::CPAN
### store the directory we found the file in
$href->{dir} = $dir;
### files need to be in unix format under vms,
### or they might be loaded twice
$href->{file} = ON_VMS
? VMS::Filespec::unixify( $filename )
: $filename;
### user wants us to find the version from files
if( $FIND_VERSION ) {
my $in_pod = 0;
while ( my $line = <$fh> ) {
### stolen from EU::MM_Unix->parse_version to address
### #24062: "Problem with CPANPLUS 0.076 misidentifying
### versions after installing Text::NSP 1.03" where a
### VERSION mentioned in the POD was found before
### the real $VERSION declaration.
$in_pod = $line =~ /^=(?!cut)/ ? 1 :
$line =~ /^=cut/ ? 0 :
$in_pod;
next if $in_pod;
### try to find a version declaration in this string.
my $ver = __PACKAGE__->_parse_version( $line );
if( defined $ver ) {
$href->{version} = $ver;
last DIR;
}
}
}
}
}
### if we couldn't find the file, return undef ###
return unless defined $href->{file};
### only complain if we're expected to find a version higher than 0.0 anyway
if( $FIND_VERSION and not defined $href->{version} ) {
{ ### don't warn about the 'not numeric' stuff ###
local $^W;
### if we got here, we didn't find the version
warn loc(q[Could not check version on '%1'], $args->{module} )
if $args->{verbose} and $args->{version} > 0;
}
$href->{uptodate} = 1;
} else {
### don't warn about the 'not numeric' stuff ###
local $^W;
### use qv(), as it will deal with developer release number
### ie ones containing _ as well. This addresses bug report
### #29348: Version compare logic doesn't handle alphas?
###
### Update from JPeacock: apparently qv() and version->new
### are different things, and we *must* use version->new
### here, or things like #30056 might start happening
### We have to wrap this in an eval as version-0.82 raises
### exceptions and not warnings now *sigh*
eval {
$href->{uptodate} =
version->new( $args->{version} ) <= version->new( $href->{version} )
? 1
: 0;
};
}
if ( $DEPRECATED and version->new($]) >= version->new('5.011') ) {
require Module::CoreList;
require Config;
$href->{uptodate} = 0 if
exists $Module::CoreList::version{ 0+$] }{ $args->{module} } and
Module::CoreList::is_deprecated( $args->{module} ) and
$Config::Config{privlibexp} eq $href->{dir};
}
return $href;
}
sub _parse_version {
my $self = shift;
my $str = shift or return;
my $verbose = shift or 0;
### skip lines which doesn't contain VERSION
return unless $str =~ /VERSION/;
### skip commented out lines, they won't eval to anything.
return if $str =~ /^\s*#/;
### the following regexp & eval statement comes from the
### ExtUtils::MakeMaker source (EU::MM_Unix->parse_version)
### Following #18892, which tells us the original
### regex breaks under -T, we must modifiy it so
### it captures the entire expression, and eval /that/
### rather than $_, which is insecure.
my $taint_safe_str = do { $str =~ /(^.*$)/sm; $1 };
if( $str =~ /(?<!\\)([\$*])(([\w\:\']*)\bVERSION)\b.*\=/ ) {
print "Evaluating: $str\n" if $verbose;
### this creates a string to be eval'd, like:
# package Module::Load::Conditional::_version;
# no strict;
#
# local $VERSION;
# $VERSION=undef; do {
# use version; $VERSION = qv('0.0.3');
# }; $VERSION
inc/inc_Module-Load-Conditional/Module/Load/Conditional.pm view on Meta::CPAN
=item verbose
This controls whether warnings should be printed if a module failed
to load.
The default is to use the value of $Module::Load::Conditional::VERBOSE.
=item nocache
C<can_load> keeps its results in a cache, so it will not load the
same module twice, nor will it attempt to load a module that has
already failed to load before. By default, C<can_load> will check its
cache, but you can override that by setting C<nocache> to true.
=cut
sub can_load {
my %hash = @_;
my $tmpl = {
modules => { default => {}, strict_type => 1 },
verbose => { default => $VERBOSE },
nocache => { default => 0 },
};
my $args;
unless( $args = check( $tmpl, \%hash, $VERBOSE ) ) {
$ERROR = loc(q[Problem validating arguments!]);
warn $ERROR if $VERBOSE;
return;
}
### layout of $CACHE:
### $CACHE = {
### $ module => {
### usable => BOOL,
### version => \d,
### file => /path/to/file,
### },
### };
$CACHE ||= {}; # in case it was undef'd
my $error;
BLOCK: {
my $href = $args->{modules};
my @load;
for my $mod ( keys %$href ) {
next if $CACHE->{$mod}->{usable} && !$args->{nocache};
### else, check if the hash key is defined already,
### meaning $mod => 0,
### indicating UNSUCCESSFUL prior attempt of usage
### use qv(), as it will deal with developer release number
### ie ones containing _ as well. This addresses bug report
### #29348: Version compare logic doesn't handle alphas?
###
### Update from JPeacock: apparently qv() and version->new
### are different things, and we *must* use version->new
### here, or things like #30056 might start happening
if ( !$args->{nocache}
&& defined $CACHE->{$mod}->{usable}
&& (version->new( $CACHE->{$mod}->{version}||0 )
>= version->new( $href->{$mod} ) )
) {
$error = loc( q[Already tried to use '%1', which was unsuccessful], $mod);
last BLOCK;
}
my $mod_data = check_install(
module => $mod,
version => $href->{$mod}
);
if( !$mod_data or !defined $mod_data->{file} ) {
$error = loc(q[Could not find or check module '%1'], $mod);
$CACHE->{$mod}->{usable} = 0;
last BLOCK;
}
map {
$CACHE->{$mod}->{$_} = $mod_data->{$_}
} qw[version file uptodate];
push @load, $mod;
}
for my $mod ( @load ) {
if ( $CACHE->{$mod}->{uptodate} ) {
eval { load $mod };
### in case anything goes wrong, log the error, the fact
### we tried to use this module and return 0;
if( $@ ) {
$error = $@;
$CACHE->{$mod}->{usable} = 0;
last BLOCK;
} else {
$CACHE->{$mod}->{usable} = 1;
}
### module not found in @INC, store the result in
### $CACHE and return 0
} else {
$error = loc(q[Module '%1' is not uptodate!], $mod);
$CACHE->{$mod}->{usable} = 0;
last BLOCK;
}
}
} # BLOCK
if( defined $error ) {
$ERROR = $error;
Carp::carp( loc(q|%1 [THIS MAY BE A PROBLEM!]|,$error) ) if $args->{verbose};
( run in 0.591 second using v1.01-cache-2.11-cpan-172d661cebc )