X-Git-Url: http://git.vpit.fr/?a=blobdiff_plain;f=lib%2FCPANPLUS%2FDist%2FGentoo.pm;h=307d802108c903dfda523ba9ce864ef69a7498f3;hb=4e0c9cad73c65d6c469d35afebbef746ab15ce89;hp=49de89288dce24c55a4f6dbf9b5da1eb899bd76e;hpb=c029d40b0c63792791c19dac415438772577816e;p=perl%2Fmodules%2FCPANPLUS-Dist-Gentoo.git diff --git a/lib/CPANPLUS/Dist/Gentoo.pm b/lib/CPANPLUS/Dist/Gentoo.pm index 49de892..307d802 100644 --- a/lib/CPANPLUS/Dist/Gentoo.pm +++ b/lib/CPANPLUS/Dist/Gentoo.pm @@ -4,6 +4,7 @@ use strict; use warnings; use Cwd qw/abs_path/; +use List::Util qw/reduce/; use File::Copy (); use File::Path (); use File::Spec; @@ -15,6 +16,7 @@ use CPANPLUS::Error (); use base qw/CPANPLUS::Dist::Base/; +use CPANPLUS::Dist::Gentoo::Atom; use CPANPLUS::Dist::Gentoo::Maps; =head1 NAME @@ -23,11 +25,11 @@ CPANPLUS::Dist::Gentoo - CPANPLUS backend generating Gentoo ebuilds. =head1 VERSION -Version 0.07 +Version 0.08 =cut -our $VERSION = '0.07'; +our $VERSION = '0.08'; =head1 SYNOPSIS @@ -51,7 +53,73 @@ They favour depending on a C, on C, C or C to your F file. +Before installing this module, you should append C to your F file. + +You have two ways for installing this module : + +=over 4 + +=item * + +Use the perl overlay located at L. +It contains an ebuild for L. + +=item * + +Bootstrap an ebuild for L using itself. +Note that if your Gentoo system C is C<5.8.x>, L and its dependencies are not installed and not even available in the main portage tree. +So you need to bootstrap them as well. + +First, fetch tarballs for L and L : + + $ cd /tmp + $ wget http://search.cpan.org/CPAN/authors/id/K/KA/KANE/CPANPLUS-0.88.tar.gz + $ wget http://search.cpan.org/CPAN/authors/id/V/VP/VPIT/CPANPLUS-Dist-Gentoo-0.08.tar.gz + +Log in as root and unpack them in e.g. your home directory : + + # cd + # tar xzf /tmp/CPANPLUS-0.88.tar.gz + # tar xzf /tmp/CPANPLUS-Dist-Gentoo-0.08.tar.gz + +Set up environment variables so that the toolchain is temporarily available : + + # export OLDPATH=$PATH + # export PATH=/root/CPANPLUS-0.88/bin:$PATH + # export PERL5LIB=/root/CPANPLUS-Dist-Gentoo-0.08/blib/lib:/root/CPANPLUS-0.88/lib:/root/CPANPLUS-0.88/inc/bundle + +Make sure you don't have an old C<.cpanplus> configuration visible : + + # [ -d /root/.cpanplus ] && mv /root/.cpanplus{,.bak} + +Bootstrap L : + + # cd /root/CPANPLUS-Dist-Gentoo-0.08 + # samples/g-cpanp CPANPLUS + +Reset the environment : + + # export PATH=$OLDPATH + # unset PERL5LIB OLDPATH + +Emerge L with the ebuilds you've just generated : + + # emerge -tv CPANPLUS + +As of september 2009, C and C may fail to emerge due to collisions. +You can work around this by disabling the C C for them : + + # FEATURES="-protect-owned" emerge podlators + # FEATURES="-protect-owned" emerge ExtUtils-MakeMaker + +You may need to run each of these commands two times for them to succeed. + +At this point, you can bootstrap L using the system L : + + # PERL5LIB=/root/CPANPLUS-Dist-Gentoo-0.08/blib/lib samples/g-cpanp CPANPLUS::Dist::Gentoo + # emerge -tv CPANPLUS-Dist-Gentoo + +=back =head1 METHODS @@ -123,7 +191,7 @@ sub init { my $conf = $self->parent->parent->configure_object; $stat->mk_accessors(qw/name version author distribution desc uri src license - fetched_arch deps + fetched_arch requires ebuild_name ebuild_version ebuild_dir ebuild_file portdir_overlay overlay distdir keywords do_manifest header footer @@ -146,6 +214,7 @@ sub prepare { my $OK = sub { $stat->prepared(1); 1 }; my $FAIL = sub { $stat->prepared(0); $self->_abort(@_) if @_; 0 }; + my $SKIP = sub { $stat->prepared(1); $stat->created(1); $self->_skip(@_) if @_; 1 }; my $keywords = delete $opts{keywords}; if (defined $keywords) { @@ -165,7 +234,12 @@ sub prepare { 1 while chomp $header; $header .= "\n\n"; } else { - $header = ''; + my $year = (localtime)[5] + 1900; + $header = <<" DEF_HEADER"; +# Copyright 1999-$year Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# \$Header: \$ + DEF_HEADER } $stat->header($header); @@ -227,24 +301,24 @@ sub prepare { ); $stat->ebuild_file($file); - if (-e $file) { - my $skip = 1; - if ($stat->force and not $forced{$file}) { - if (-w $file) { - 1 while unlink $file; - $forced{$file} = 1; - $skip = 0; - } else { - $self->_skip("Can't force rewriting of $file"); + if ($stat->force) { + # Always generate an ebuild in our category when forcing + if ($forced{$file}) { + $stat->dist($file); + return $SKIP->('Ebuild already forced for', $stat->distribution); + } + ++$forced{$file}; + if (-e $file) { + unless (-w $file) { + $stat->dist($file); + return $SKIP->("Can't force rewriting of $file"); } - } else { - $self->_skip('Ebuild already generated for', $stat->distribution); + 1 while unlink $file; } - if ($skip) { - $stat->prepared(1); - $stat->created(1); - $stat->dist($file); - return 1; + } else { + if (my $atom = $self->_cpan2portage($name, $version)) { + $stat->dist($atom->ebuild); + return $SKIP->('Ebuild already generated for', $stat->distribution); } } @@ -265,8 +339,8 @@ sub prepare { $stat->license($self->intuit_license); - my $prereqs = $mod->status->prereqs; - my @depends; + my $prereqs = $mod->status->requires; + my @requires; for my $prereq (sort keys %$prereqs) { next if $prereq =~ /^perl(?:-|\z)/; my $obj = $int->module_tree($prereq); @@ -281,10 +355,10 @@ sub prepare { $version = $obj->package_version; } } - push @depends, [ $obj->package_name, $version ]; + push @requires, [ $obj->package_name, $version ]; } } - $stat->deps(\@depends); + $stat->requires(\@requires); return $OK->(); } @@ -341,7 +415,7 @@ sub create { my $OK = sub { $stat->created(1); - $stat->dist($file); + $stat->dist($file) if defined $file; 1; }; @@ -349,7 +423,7 @@ sub create { $stat->created(0); $stat->dist(undef); $self->_abort(@_) if @_; - if ($file and -f $file) { + if (defined $file and -f $file) { 1 while unlink $file; } 0; @@ -363,6 +437,7 @@ sub create { if ($stat->created) { $self->_skip($stat->distribution, 'was already created'); + $file = $stat->dist; # Keep the existing one. return $OK->(); } @@ -389,7 +464,9 @@ sub create { { open my $eb, '>', $file or return $FAIL->("open($file): $!"); - print $eb $self->ebuild_source; + my $source = $self->ebuild_source; + return $FAIL->() unless defined $source; + print $eb $source; } return $FAIL->() if $stat->do_manifest and not $self->update_manifest; @@ -408,7 +485,7 @@ sub update_manifest { my $stat = $self->status; my $file = $stat->ebuild_file; - unless ($file and -e $file) { + unless (defined $file and -e $file) { return $self->_abort('The ebuild file is invalid or does not exist'); } @@ -418,12 +495,12 @@ sub update_manifest { $self->_notify('Adding Manifest entry for', $stat->distribution); - return $self->_run([ 'ebuild', $stat->ebuild_file, 'manifest' ], 0); + return $self->_run([ 'ebuild', $file, 'manifest' ], 0); } =head2 C -Returns the source of the ebuild for the current dist object. +Returns the source of the ebuild for the current dist object, or C when one of the dependencies couldn't be mapped to an existing ebuild. =cut @@ -434,11 +511,23 @@ sub ebuild_source { # We must resolve the deps now and not inside prepare because _cpan2portage # has to see the ebuilds already generated for the dependencies of the current # dist. - my @deps = do { - my %seen; - sort grep !$seen{$_}++, 'dev-lang/perl', - map $self->_cpan2portage(@$_), @{$stat->deps} - }; + my @requires; + for (@{$stat->requires}) { + my $atom = $self->_cpan2portage(@$_); + unless (defined $atom) { + $self->_abort( + "Couldn't find an appropriate ebuild for $_->[0] in the portage tree" + ); + return; + } + push @requires, $atom; + } + + my $perl = CPANPLUS::Dist::Gentoo::Atom->new( + category => 'dev-lang', + name => 'perl', + ); + @requires = CPANPLUS::Dist::Gentoo::Atom->fold($perl, @requires); my $d = $stat->header; $d .= "# Generated by CPANPLUS::Dist::Gentoo version $VERSION\n\n"; @@ -450,7 +539,8 @@ sub ebuild_source { $d .= "SLOT=\"0\"\n"; $d .= 'LICENSE="|| ( ' . join(' ', sort @{$stat->license}) . " )\"\n"; $d .= 'KEYWORDS="' . join(' ', sort @{$stat->keywords}) . "\"\n"; - $d .= 'DEPEND="' . join("\n", @deps) . "\"\n"; + $d .= 'RDEPEND="' . join("\n", sort @requires) . "\"\n"; + $d .= "DEPEND=\"\${RDEPEND}\"\n"; $d .= "SRC_TEST=\"do\"\n"; $d .= $stat->footer; @@ -460,43 +550,38 @@ sub ebuild_source { sub _cpan2portage { my ($self, $name, $version) = @_; - $name = CPANPLUS::Dist::Gentoo::Maps::name_c2g($name); - my $ver; - $ver = CPANPLUS::Dist::Gentoo::Maps::version_c2g($version) if defined $version; + $name = CPANPLUS::Dist::Gentoo::Maps::name_c2g($name); + $version = CPANPLUS::Dist::Gentoo::Maps::version_c2g($version); my @portdirs = ($main_portdir, @{$self->status->portdir_overlay}); for my $category (qw/virtual perl-core dev-perl perl-gcpan/, CATEGORY) { - my $atom = ($category eq 'virtual' ? 'perl-' : '') . $name; + my $name = ($category eq 'virtual' ? 'perl-' : '') . $name; for my $portdir (@portdirs) { my @ebuilds = glob File::Spec->catfile( $portdir, $category, - $atom, - "$atom-*.ebuild", + $name, + "$name-*.ebuild", ) or next; - if (defined $ver) { # implies that $version is defined - for (@ebuilds) { - 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"; - } - + my $last = reduce { $a < $b ? $b : $a } # handles overloading + map CPANPLUS::Dist::Gentoo::Atom->new_from_ebuild($_), + @ebuilds; + next if defined $version and $last < $version; + + return CPANPLUS::Dist::Gentoo::Atom->new( + category => $last->category, + name => $last->name, + (defined $version ? (version => $version, range => '>=') : ()), + ebuild => $last->ebuild, + ); } } - $self->_skip( - "Couldn't find an appropriate ebuild for $name in the portage tree" - ); - - return ''; + return; } sub install { @@ -575,7 +660,7 @@ Gentoo (L). L, L (core modules since 5.9.5), L (since 5.10.1). -L, L (since perl 5), L (5.001), L (5.002), L (5.00405). +L, L (since perl 5), L (5.001), L (5.002), L (5.00405), L (5.007003). =head1 SEE ALSO