Skip to content

Commit db72135

Browse files
move version extraction guts to its own file. NO FUNCTIONALITY CHANGES YET
1 parent 9fecda8 commit db72135

File tree

2 files changed

+107
-51
lines changed

2 files changed

+107
-51
lines changed

lib/Module/Metadata.pm

Lines changed: 23 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ package Module::Metadata;
1010
# perl modules (assuming this may be expanded in the distant
1111
# parrot future to look at other types of modules).
1212

13-
sub __clean_eval { eval $_[0] }
1413
use strict;
1514
use warnings;
1615

@@ -25,6 +24,9 @@ BEGIN {
2524
} or *SEEK_SET = sub { 0 }
2625
}
2726
use version 0.87;
27+
use Module::Metadata::ExtractVersion 'eval_version';
28+
29+
2830
BEGIN {
2931
if ($INC{'Log/Contextual.pm'}) {
3032
require "Log/Contextual/WarnLogger.pm"; # Hide from AutoPrereqs
@@ -600,13 +602,23 @@ sub _parse_fh {
600602
$need_vers = 0 if $version_package eq $package;
601603

602604
unless ( defined $vers_raw{$version_package}[0] && length $vers_raw{$version_package}[0] ) {
603-
$vers_raw{$version_package} = [ $self->_evaluate_version_line( $version_sigil, $version_fullname, $line ), $line ];
605+
$vers_raw{$version_package} = [ eval_version(
606+
sigil => $version_sigil,
607+
variable_name => $version_fullname,
608+
string => $line,
609+
filename => $self->{filename},
610+
), $line ];
604611
}
605612

606613
# first non-comment line in undeclared package main is VERSION
607614
} elsif ( $package eq 'main' && $version_fullname && !exists($vers_raw{main}[0]) ) {
608615
$need_vers = 0;
609-
my $v = $self->_evaluate_version_line( $version_sigil, $version_fullname, $line );
616+
my $v = eval_version(
617+
sigil => $version_sigil,
618+
variable_name => $version_fullname,
619+
string => $line,
620+
filename => $self->{filename},
621+
);
610622
$vers_raw{$package} = [ $v, $line ];
611623
push( @packages, 'main' );
612624

@@ -619,9 +631,14 @@ sub _parse_fh {
619631
# only keep if this is the first $VERSION seen
620632
} elsif ( $version_fullname && $need_vers ) {
621633
$need_vers = 0;
622-
my $v = $self->_evaluate_version_line( $version_sigil, $version_fullname, $line );
623-
624-
unless ( exists $vers_raw{$package}[0] && length $vers{$package}[0] ) {
634+
my $v = eval_version(
635+
sigil => $version_sigil,
636+
variable_name => $version_fullname,
637+
string => $line,
638+
filename => $self->{filename},
639+
);
640+
641+
unless ( exists $vers_raw{$package}[0] && length $vers_raw{$package}[0] ) {
625642
$vers_raw{$package} = [ $v, $line ];
626643
}
627644
}
@@ -652,51 +669,6 @@ sub _parse_fh {
652669
$self->{pod_headings} = \@pod;
653670
}
654671

655-
{
656-
my $pn = 0;
657-
sub _evaluate_version_line {
658-
my $self = shift;
659-
my( $sigil, $variable_name, $line ) = @_;
660-
661-
# We compile into a local sub because 'use version' would cause
662-
# compiletime/runtime issues with local()
663-
$pn++; # everybody gets their own package
664-
my $eval = qq{ my \$dummy = q# Hide from _packages_inside()
665-
#; package Module::Metadata::_version::p${pn};
666-
use version;
667-
sub {
668-
local $sigil$variable_name;
669-
$line;
670-
\$$variable_name
671-
};
672-
};
673-
674-
$eval = $1 if $eval =~ m{^(.+)}s;
675-
676-
local $^W;
677-
# Try to get the $VERSION
678-
my $vsub = __clean_eval($eval);
679-
# some modules say $VERSION <equal sign> $Foo::Bar::VERSION, but Foo::Bar isn't
680-
# installed, so we need to hunt in ./lib for it
681-
if ( $@ =~ /Can't locate/ && -d 'lib' ) {
682-
local @INC = ('lib',@INC);
683-
$vsub = __clean_eval($eval);
684-
}
685-
warn "Error evaling version line '$eval' in $self->{filename}: $@\n"
686-
if $@;
687-
688-
(ref($vsub) eq 'CODE') or
689-
croak "failed to build version sub for $self->{filename}";
690-
691-
my $result = eval { $vsub->() };
692-
# FIXME: $eval is not the right thing to print here
693-
croak "Could not get version from $self->{filename} by executing:\n$eval\n\nThe fatal error was: $@\n"
694-
if $@;
695-
696-
return $result;
697-
}
698-
}
699-
700672
# Try to DWIM when things fail the lax version test in obvious ways
701673
{
702674
my @version_prep = (

lib/Module/Metadata/ExtractVersion.pm

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package Module::Metadata::ExtractVersion;
2+
# ABSTRACT: Safe parsing of module $VERSION lines
3+
4+
sub __clean_eval { eval $_[0] }
5+
6+
use strict;
7+
use warnings;
8+
9+
our $VERSION = '1.000028';
10+
11+
use base 'Exporter';
12+
our @EXPORT_OK = qw/eval_version/;
13+
14+
use Carp qw/croak/;
15+
use version 0.87;
16+
17+
=func eval_version
18+
19+
Given a (decoded) string (usually a single line) that contains a C<$VERSION>
20+
declaration, this function will evaluate it in a L<Safe> compartment in a
21+
separate process. If the C<$VERSION> is a valid version string according to
22+
L<version>, it will return it as a string, otherwise, it will return undef.
23+
24+
=cut
25+
26+
sub eval_version
27+
{
28+
my (%args) = @_;
29+
30+
return _evaluate_version_line(
31+
$args{sigil},
32+
$args{variable_name},
33+
$args{string},
34+
$args{filename},
35+
);
36+
}
37+
38+
# transported directly from Module::Metadata
39+
40+
{
41+
my $pn = 0;
42+
sub _evaluate_version_line {
43+
my( $sigil, $variable_name, $line, $filename ) = @_;
44+
45+
# We compile into a local sub because 'use version' would cause
46+
# compiletime/runtime issues with local()
47+
$pn++; # everybody gets their own package
48+
my $eval = qq{ my \$dummy = q# Hide from _packages_inside()
49+
#; package Module::Metadata::_version::p${pn};
50+
use version;
51+
sub {
52+
local $sigil$variable_name;
53+
$line;
54+
\$$variable_name
55+
};
56+
};
57+
58+
$eval = $1 if $eval =~ m{^(.+)}s;
59+
60+
local $^W;
61+
# Try to get the $VERSION
62+
my $vsub = __clean_eval($eval);
63+
# some modules say $VERSION <equal sign> $Foo::Bar::VERSION, but Foo::Bar isn't
64+
# installed, so we need to hunt in ./lib for it
65+
if ( $@ =~ /Can't locate/ && -d 'lib' ) {
66+
local @INC = ('lib',@INC);
67+
$vsub = __clean_eval($eval);
68+
}
69+
warn "Error evaling version line '$eval' in $filename: $@\n"
70+
if $@;
71+
72+
(ref($vsub) eq 'CODE') or
73+
croak "failed to build version sub for $filename";
74+
75+
my $result = eval { $vsub->() };
76+
# FIXME: $eval is not the right thing to print here
77+
croak "Could not get version from $filename by executing:\n$eval\n\nThe fatal error was: $@\n"
78+
if $@;
79+
80+
return $result;
81+
}
82+
}
83+
84+
1;

0 commit comments

Comments
 (0)