From: Vincent Pit Date: Sun, 1 Feb 2009 00:04:39 +0000 (+0100) Subject: Refine the versioning logic X-Git-Tag: v0.06~4 X-Git-Url: http://git.vpit.fr/?p=perl%2Fmodules%2FCPANPLUS-Dist-Gentoo.git;a=commitdiff_plain;h=39dcc4f5ffa5f01ec7854c63fba5c70e7b963fd8 Refine the versioning logic Roll our own parsing and comparing version routines, and test them in t/12-maps-version.t. version is no longer required, but Carp now is. --- diff --git a/MANIFEST b/MANIFEST index 2cd9e88..d3119b9 100644 --- a/MANIFEST +++ b/MANIFEST @@ -8,6 +8,7 @@ samples/g-cpanp samples/gengentooisms t/00-load.t t/11-maps-name.t +t/12-maps-version.t t/90-boilerplate.t t/91-pod.t t/92-pod-coverage.t diff --git a/Makefile.PL b/Makefile.PL index e0f3ad6..8cfa41c 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -27,13 +27,13 @@ WriteMakefile( ABSTRACT_FROM => 'lib/CPANPLUS/Dist/Gentoo.pm', PL_FILES => {}, PREREQ_PM => { + 'Carp' => 0, 'CPANPLUS' => 0, 'Cwd' => 0, 'File::Copy' => 0, 'File::Path' => 0, 'File::Spec::Functions' => 0, 'IPC::Cmd' => 0, - 'version' => 0, }, dist => { PREOP => 'pod2text lib/CPANPLUS/Dist/Gentoo.pm > $(DISTVNAME)/README; ' diff --git a/lib/CPANPLUS/Dist/Gentoo.pm b/lib/CPANPLUS/Dist/Gentoo.pm index 84ed792..dc35d0b 100644 --- a/lib/CPANPLUS/Dist/Gentoo.pm +++ b/lib/CPANPLUS/Dist/Gentoo.pm @@ -9,7 +9,6 @@ use File::Path qw/mkpath/; use File::Spec::Functions qw/catdir catfile/; use IPC::Cmd qw/run can_run/; -use version; use CPANPLUS::Error; @@ -207,16 +206,7 @@ sub prepare { $stat->distribution($name . '-' . $version); - $version =~ s/[^\d._]+//g; - $version =~ s/^[._]*//; - $version =~ s/[._]*$//; - $version =~ s/[._]*_[._]*/_/g; - { - ($version, my $patch, my @rest) = split /_/, $version; - $version .= '_p' . $patch if defined $patch; - $version .= join('.', '', @rest) if @rest; - } - $stat->eb_version($version); + $stat->eb_version(CPANPLUS::Dist::Gentoo::Maps::version_c2g($version)); $stat->eb_name(CPANPLUS::Dist::Gentoo::Maps::name_c2g($name)); @@ -375,11 +365,10 @@ sub create { } sub _cpan2portage { - my ($self, $name, $version) = @_; + my ($self, $name, $ver) = @_; $name = CPANPLUS::Dist::Gentoo::Maps::name_c2g($name); - my $ver; - $ver = eval { version->new($version) } if defined $version; + $ver = CPANPLUS::Dist::Gentoo::Maps::version_c2g($ver); my @portdirs = ($main_portdir, @{$self->status->portdir_overlay}); @@ -392,10 +381,10 @@ sub _cpan2portage { if (defined $ver) { # implies that $version is defined for (@ebuilds) { - next unless /\Q$atom\E-v?([\d._]+).*?\.ebuild$/; - my $eb_ver = eval { version->new($1) }; - next unless defined $eb_ver and $eb_ver >= $ver; - return ">=$category/$atom-$version"; + my ($eb_ver) = /\Q$atom\E-v?([\d._pr-]+).*?\.ebuild$/; + return ">=$category/$atom-$ver" + if defined $eb_ver + and CPANPLUS::Dist::Gentoo::Maps::version_gcmp($eb_ver, $ver) > 0; } } else { return "$category/$atom"; @@ -465,9 +454,9 @@ sub _run { Gentoo (L). -L, L (core modules since 5.9.5), L (since 5.009). +L, L (core modules since 5.9.5). -L (since perl 5) L (5.001), L (5.002), L (5.00504). +L, L (since perl 5), L (5.001), L (5.002), L (5.00504). =head1 SEE ALSO diff --git a/lib/CPANPLUS/Dist/Gentoo/Maps.pm b/lib/CPANPLUS/Dist/Gentoo/Maps.pm index d118edc..ea136b0 100644 --- a/lib/CPANPLUS/Dist/Gentoo/Maps.pm +++ b/lib/CPANPLUS/Dist/Gentoo/Maps.pm @@ -40,6 +40,67 @@ sub name_c2g { return $gentooisms{$name} || $name; } +=head2 C + +Converts a CPAN version to a Gentoo version. + +=cut + +sub version_c2g { + my ($v) = @_; + + $v =~ y/-/_/; + $v =~ y/0-9._//cd; + + $v =~ s/^[._]*//; + $v =~ s/[._]*$//; + $v =~ s/([._])[._]*/$1/g; + + ($v, my $patch, my @rest) = split /_/, $v; + $v .= '_p' . $patch if defined $patch; + $v .= join('.', '', @rest) if @rest; + + return $v; +} + +=head2 C + +Compares two Gentoo versions. + +=cut + +sub version_gcmp { + my ($a, $b) = map { defined() ? $_ : 0 } @_; + + for ($a, $b) { + s/^[._]+//g; + s/[._]+$//g; + if (/^([\d.]*\d)\.*(?:_p\.*(\d[\d.]*))?\.*(?:-r(\d+))?$/) { + $_ = { + v => [ split /\.+/, $1 ], + p => [ split /\.+/, $2 || 0 ], + r => [ $3 || 0 ], + }; + } else { + require Carp; + Carp::croak("Couldn't parse version string '$_'"); + } + } + + for my $k (qw/v p r/) { + my $xa = $a->{$k}; + my $xb = $b->{$k}; + while (@$xa or @$xb) { + my $na = shift(@$xa) || 0; + my $nb = shift(@$xb) || 0; + my $c = $na <=> $nb; + return $c if $c; + } + } + + return 0; +} + =head1 SEE ALSO L. diff --git a/t/12-maps-version.t b/t/12-maps-version.t new file mode 100644 index 0000000..80a4baa --- /dev/null +++ b/t/12-maps-version.t @@ -0,0 +1,55 @@ +#!perl -T + +use strict; +use warnings; + +use Test::More tests => 10 + 24; + +use CPANPLUS::Dist::Gentoo::Maps; + +*vc2g = \&CPANPLUS::Dist::Gentoo::Maps::version_c2g; + +is vc2g('1'), '1', "version_c2g('1')"; +is vc2g('a1b'), '1', "version_c2g('a1b')"; +is vc2g('..1'), '1', "version_c2g('..1')"; +is vc2g('1.0'), '1.0', "version_c2g('1.0')"; +is vc2g('1._0'), '1.0', "version_c2g('1._0')"; +is vc2g('1_1'), '1_p1', "version_c2g('1_1')"; +is vc2g('1_.1'), '1_p1', "version_c2g('1_.1')"; +is vc2g('1_.1._2'), '1_p1.2', "version_c2g('1_.1._2')"; +is vc2g('1_.1_2'), '1_p1.2', "version_c2g('1_.1_2')"; +is vc2g('1_.1_.2'), '1_p1.2', "version_c2g('1_.1_.2')"; + +*vgcmp = \&CPANPLUS::Dist::Gentoo::Maps::version_gcmp; + +eval { vgcmp('dongs', 1) }; +like $@, qr/Couldn't\s+parse\s+version\s+string/, "version_gcmp('dongs', 1)"; + +eval { vgcmp(1, 'dongs') }; +like $@, qr/Couldn't\s+parse\s+version\s+string/, "version_gcmp(1, 'dongs')"; + +is vgcmp(undef, 0), 0, 'version_gcmp(undef, 0)'; +is vgcmp(0, 0), 0, 'version_gcmp(0, 0)'; +is vgcmp(1, 0), 1, 'version_gcmp(1, 0)'; +is vgcmp(0, 1), -1, 'version_gcmp(0, 1)'; +is vgcmp(1, 1), 0, 'version_gcmp(1, 1)'; + +is vgcmp('1.0', 1), 0, "version_gcmp('1.0', 1)"; +is vgcmp('1.1', 1), 1, "version_gcmp('1.1', 1)"; +is vgcmp('1.1', '1.0'), 1, "version_gcmp('1.1', '1.0')"; +is vgcmp(1, '1.0'), 0, "version_gcmp(1, '1.0')"; +is vgcmp(1, '1.1'), -1, "version_gcmp(1, '1.1')"; +is vgcmp('1.0', '1.1'), -1, "version_gcmp('1.0', '1.1')"; + +is vgcmp('1.0_p0', '1.0_p0'), 0, "version_gcmp('1.0_p0', '1.0_p0')"; +is vgcmp('1.0_p0', '1.0_p1'), -1, "version_gcmp('1.0_p0', '1.0_p1')"; +is vgcmp('1.1_p0', '1.0_p1'), 1, "version_gcmp('1.1_p0', '1.0_p1')"; +is vgcmp('1.1_p0', '1.1_p0.1'), -1, "version_gcmp('1.1_p0', '1.1_p0.1')"; +is vgcmp('1.1_p0.1', '1.1_p0.1'), 0, "version_gcmp('1.1_p0.1', '1.1_p0.1')"; + +is vgcmp('1.2_p0-r0', '1.2_p0'), 0, "version_gcmp('1.2_p0-r0', '1.2_p0')"; +is vgcmp('1.2_p0-r1', '1.2_p0'), 1, "version_gcmp('1.2_p0-r1', '1.2_p0')"; +is vgcmp('1.2-r0', '1.2_p0'), 0, "version_gcmp('1.2-r0', '1.2_p0')"; +is vgcmp('1.2-r1', '1.2_p0'), 1, "version_gcmp('1.2-r1', '1.2_p0')"; +is vgcmp('1.2-r1', '1.2_p1'), -1, "version_gcmp('1.2-r1', '1.2_p1')"; +is vgcmp('1.2-r2', '1.2_p1'), -1, "version_gcmp('1.2-r2', '1.2_p1')";