I just ran into this myself and am coming up to speed on the issue. Is
there a reason why Module::Build can't use version.pm itself internally?
I've tried some quick hacks on 0.25_03 to add "use version" at the top
of Base.pm and then some modifications of the version_from_file()
routine to use version.pm to parse whatever it finds in the VERSION line
in the file under examination.
The major things that appear to break in the test scripts are the
distribution directory naming scheme and the metadata generation.
The former can be fixed by numifying the version object, though this
somewhat defeats the purpose of using version. It would be nice if
$VERSION=version->new("0.25_3") generated a distribution like
"module-0.250_003.tar.gz"
The latter seems to break because it uses "$build->VERSION" in the test
script (after version.pm replaces VERSION), but Base.pm always uses
"$Module::Build::VERSION" which isn't a version object. Having
Module::Build define its version with version.pm fixes that.
The major backward incompatibilities would appear to be in the
numification of versions for use in naming distribution
directories/tarfiles. (I.e. version->new(0.01) becomes "0.010") But
then, if the version numbering direction for perl 5.10 goes forward,
then this hurdle will have to be addressed sooner rather than later.
Perhaps a change could be made with a flag for backwards compatible
numbering of distributions.
The attached patch passes the current Module::Build test suite (with one
change to a single test) (at least on perl 5.8.3 on linux). This was
some quick and dirty hacking, so I don't suggest taking it verbatim, but
it suggests what few changes could be considered to utilize version.pm
without resorting to local UNIVERSAL::VERSION adjustments. It also
works for a module I'm working on that defines
$VERSION=version->new("0.2.1") and it correctly converts that to
0.002001 for creating a distribution name, etc.
Offered in the hope of stimulating discussion -- let me know if I can
help in some way to take this forward.
Index: t/Sample/META.yml
===================================================================
--- t/Sample/META.yml (revision 7)
+++ t/Sample/META.yml (revision 9)
@@ -13,4 +13,4 @@
version: 0.01
Sample::NoPod:
file: lib/Sample/NoPod.pm
-generated_by: Module::Build version 0.25_03
+generated_by: Module::Build version 0.250_030
Index: t/basic.t
===================================================================
--- t/basic.t (revision 7)
+++ t/basic.t (revision 9)
@@ -2,6 +2,7 @@
use strict;
use Test;
+use version;
BEGIN { plan tests => 37 }
use Module::Build;
ok(1);
@@ -64,7 +65,7 @@
# Make sure check_installed_status() works as a class method
my $info = Module::Build->check_installed_status('File::Spec', 0);
ok $info->{ok}, 1;
- ok $info->{have}, $File::Spec::VERSION;
+ ok $info->{have}, File::Spec->VERSION;
# Make sure check_installed_status() works with an advanced spec
$info = Module::Build->check_installed_status('File::Spec', '> 0');
Index: lib/Module/Build/Base.pm
===================================================================
--- lib/Module/Build/Base.pm (revision 7)
+++ lib/Module/Build/Base.pm (revision 9)
@@ -11,6 +11,7 @@
use File::Compare ();
use Data::Dumper ();
use IO::File ();
+use version ();
#################### Constructors ###########################
sub new {
@@ -42,7 +43,7 @@
" but we are now using '$perl'.\n");
}
- my $mb_version = $Module::Build::VERSION;
+ my $mb_version = Module::Build->VERSION;
die(" * ERROR: Configuration was initially created with Module::Build version '$self->{properties}{mb_version}',\n".
" but we are now using version '$mb_version'. Please re-run the Build.PL or Makefile.PL script.\n")
unless $mb_version eq $self->{properties}{mb_version};
@@ -89,7 +90,7 @@
recommends => {},
build_requires => {},
conflicts => {},
- mb_version => $Module::Build::VERSION,
+ mb_version => Module::Build->VERSION,
build_elements => [qw( PL support pm xs pod script )],
installdirs => 'site',
install_path => {},
@@ -463,7 +464,7 @@
my $version_from = File::Spec->catfile( split '/', $p->{dist_version_from} );
- return $p->{dist_version} = $self->version_from_file($version_from);
+ return $p->{dist_version} = 0 + $self->version_from_file($version_from)->numify;
}
sub dist_author { shift->_pod_parse('author') }
@@ -517,20 +518,11 @@
my $match = qr/([\$*])(([\w\:\']*)\bVERSION)\b.*\=/;
my ($v_line, $sigil, $var) = $self->_next_code_line($fh, $match) or return undef;
-
- my $eval = qq{q# Hide from _packages_inside()
- #; package Module::Build::Base::_version;
- no strict;
-
- local $sigil$var;
- \$$var=undef; do {
- $v_line
- }; \$$var
- };
local $^W;
- my $result = eval $eval;
- warn "Error evaling version line '$eval' in $file: $@\n" if $@;
- return $result;
+ my ($v_set) = $v_line =~ /VERSION\b.*?=(.*)/;
+ my $v_val = eval $v_set;
+ warn "Error getting version from '$v_val' in $file: $@\n" if $@;
+ return version->new( "$v_val" );
}
sub _persistent_hash_write {
@@ -733,16 +725,9 @@
# Check the current perl interpreter
# It's much more convenient to use $] here than $^V, but 'man
# perlvar' says I'm not supposed to. Bloody tyrant.
- return $^V ? $self->perl_version_to_float(sprintf "%vd", $^V) : $];
+ return version->new( "$]" );
}
-sub perl_version_to_float {
- my ($self, $version) = @_;
- $version =~ s/\./../;
- $version =~ s/\.(\d+)/sprintf '%03d', $1/eg;
- return $version;
-}
-
sub _parse_conditions {
my ($self, $spec) = @_;
@@ -760,7 +745,7 @@
if ($modname eq 'perl') {
$status{have} = $self->perl_version;
- } elsif (eval { no strict; $status{have} = ${"${modname}::VERSION"} }) {
+ } elsif (eval { no strict; $status{have} = $modname->VERSION }) {
# Don't try to load if it's already loaded
} else {
@@ -783,7 +768,7 @@
my ($op, $version) = /^\s* (<=?|>=?|==|!=) \s* ([\w.]+) \s*$/x
or die "Invalid prerequisite condition '$_' for $modname";
- $version = $self->perl_version_to_float($version)
+ $version = version->new("$version")
if $modname eq 'perl';
next if $op eq '>=' and !$version; # Module doesn't have to actually define a $VERSION
@@ -801,11 +786,7 @@
sub compare_versions {
my $self = shift;
my ($v1, $op, $v2) = @_;
-
- # for alpha versions - this doesn't cover all cases, but should work for most:
- $v1 =~ s/_(\d+)\z/$1/;
- $v2 =~ s/_(\d+)\z/$1/;
-
+ $_ = version->new($_) for ($v1, $v2);
my $eval_str = "\$v1 $op \$v2";
my $result = eval $eval_str;
warn "error comparing versions: '$eval_str' $@" if $@;
@@ -2044,7 +2025,7 @@
@{[ join "\n", map " - $_", @{$self->dist_author} ]}
abstract: @{[ $self->dist_abstract ]}
license: $p->{license}
-generated_by: Module::Build version $Module::Build::VERSION, without YAML.pm
+generated_by: Module::Build version $p->{mb_version}, without YAML.pm
END_OF_META
$fh->close();
@@ -2098,10 +2079,10 @@
$node->{dynamic_config} = $p->{dynamic_config} if exists $p->{dynamic_config};
$node->{provides} = $self->find_dist_packages;
- $node->{generated_by} = "Module::Build version $Module::Build::VERSION";
+ $node->{generated_by} = "Module::Build version $p->{mb_version}";
# YAML API changed after version 0.30
- my $yaml_sub = $YAML::VERSION le '0.30' ? \&YAML::StoreFile : \&YAML::DumpFile;
+ my $yaml_sub = YAML->VERSION le '0.30' ? \&YAML::StoreFile : \&YAML::DumpFile;
return $self->{wrote_metadata} = $yaml_sub->($self->{metafile}, $node );
}
@@ -2140,7 +2121,7 @@
foreach my $package ($self->_packages_inside($localfile)) {
$out{$package}{file} = $dist_files{$file};
- $out{$package}{version} = $version if defined $version;
+ $out{$package}{version} = 0+$version->numify if defined $version;
}
}
return \%out;
Index: lib/Module/Build.pm
===================================================================
--- lib/Module/Build.pm (revision 7)
+++ lib/Module/Build.pm (revision 9)
@@ -10,12 +10,12 @@
use File::Spec ();
use File::Path ();
use File::Basename ();
-
+use version;
use Module::Build::Base;
use vars qw($VERSION @ISA);
@ISA = qw(Module::Build::Base);
-$VERSION = '0.25_03';
+$VERSION = version->new('0.25_03');
# Okay, this is the brute-force method of finding out what kind of
# platform we're on. I don't know of a systematic way. These values