use File::Spec::Functions qw/catdir catfile/;
use IPC::Cmd qw/run can_run/;
-use version;
use CPANPLUS::Error;
$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));
}
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});
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";
Gentoo (L<http://gentoo.org>).
-L<CPANPLUS>, L<IPC::Cmd> (core modules since 5.9.5), L<version> (since 5.009).
+L<CPANPLUS>, L<IPC::Cmd> (core modules since 5.9.5).
-L<Cwd> (since perl 5) L<File::Path> (5.001), L<File::Copy> (5.002), L<File::Spec::Functions> (5.00504).
+L<Cwd>, L<Carp> (since perl 5), L<File::Path> (5.001), L<File::Copy> (5.002), L<File::Spec::Functions> (5.00504).
=head1 SEE ALSO
return $gentooisms{$name} || $name;
}
+=head2 C<version_c2g $version>
+
+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<version_gcmp $va, $vb>
+
+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<CPANPLUS::Dist::Gentoo>.
--- /dev/null
+#!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')";