X-Git-Url: http://git.vpit.fr/?a=blobdiff_plain;f=lib%2FCPANPLUS%2FDist%2FGentoo.pm;h=d5a7b79dd375add110e358c90717d0217ad8268c;hb=5af07d69e53872ebe1bdea02e0e880141eacd862;hp=f44b124fee5a427b5f83afd764b1b98433fa3a5f;hpb=bc88694e8076ef23c06a64a23cbbbf1ed3687f08;p=perl%2Fmodules%2FCPANPLUS-Dist-Gentoo.git diff --git a/lib/CPANPLUS/Dist/Gentoo.pm b/lib/CPANPLUS/Dist/Gentoo.pm index f44b124..d5a7b79 100644 --- a/lib/CPANPLUS/Dist/Gentoo.pm +++ b/lib/CPANPLUS/Dist/Gentoo.pm @@ -3,13 +3,13 @@ package CPANPLUS::Dist::Gentoo; use strict; use warnings; -use Cwd qw/abs_path/; +use Cwd (); use List::Util qw/reduce/; use File::Copy (); use File::Path (); use File::Spec; -use IPC::Cmd qw/run can_run/; +use IPC::Cmd (); use Parse::CPAN::Meta (); use CPANPLUS::Error (); @@ -17,6 +17,7 @@ use CPANPLUS::Error (); use base qw/CPANPLUS::Dist::Base/; use CPANPLUS::Dist::Gentoo::Atom; +use CPANPLUS::Dist::Gentoo::Guard; use CPANPLUS::Dist::Gentoo::Maps; =head1 NAME @@ -25,11 +26,11 @@ CPANPLUS::Dist::Gentoo - CPANPLUS backend generating Gentoo ebuilds. =head1 VERSION -Version 0.08 +Version 0.10 =cut -our $VERSION = '0.08'; +our $VERSION = '0.10'; =head1 SYNOPSIS @@ -73,20 +74,20 @@ 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 + $ wget http://search.cpan.org/CPAN/authors/id/B/BI/BINGOS/CPANPLUS-0.9003.tar.gz + $ wget http://search.cpan.org/CPAN/authors/id/V/VP/VPIT/CPANPLUS-Dist-Gentoo-0.10.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 + # tar xzf /tmp/CPANPLUS-0.9003.tar.gz + # tar xzf /tmp/CPANPLUS-Dist-Gentoo-0.10.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 + # export PATH=/root/CPANPLUS-0.9003/bin:$PATH + # export PERL5LIB=/root/CPANPLUS-Dist-Gentoo-0.10/blib/lib:/root/CPANPLUS-0.9003/lib:/root/CPANPLUS-0.9003/inc/bundle Make sure you don't have an old C<.cpanplus> configuration visible : @@ -94,7 +95,7 @@ Make sure you don't have an old C<.cpanplus> configuration visible : Bootstrap L : - # cd /root/CPANPLUS-Dist-Gentoo-0.08 + # cd /root/CPANPLUS-Dist-Gentoo-0.10 # samples/g-cpanp CPANPLUS Reset the environment : @@ -116,7 +117,7 @@ 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 + # PERL5LIB=/root/CPANPLUS-Dist-Gentoo-0.10/blib/lib samples/g-cpanp CPANPLUS::Dist::Gentoo # emerge -tv CPANPLUS-Dist-Gentoo =back @@ -150,7 +151,7 @@ sub format_available { return $format_available if defined $format_available; for my $prog (qw/emerge ebuild/) { - unless (can_run($prog)) { + unless (IPC::Cmd::can_run($prog)) { __PACKAGE__->_abort("$prog is required to write ebuilds"); return $format_available = 0; } @@ -158,21 +159,23 @@ sub format_available { if (IPC::Cmd->can_capture_buffer) { my $buffers; - my ($success, $errmsg) = run command => [ qw/emerge --info/ ], - verbose => 0, - buffer => \$buffers; + my ($success, $errmsg) = IPC::Cmd::run( + command => [ qw/emerge --info/ ], + verbose => 0, + buffer => \$buffers, + ); if ($success) { if ($buffers =~ /^PORTDIR_OVERLAY=(.*)$/m) { - $overlays = [ map abs_path($_), split ' ', $unquote->($1) ]; + $overlays = [ map Cwd::abs_path($_), split ' ', $unquote->($1) ]; } if ($buffers =~ /^ACCEPT_KEYWORDS=(.*)$/m) { $default_keywords = [ split ' ', $unquote->($1) ]; } if ($buffers =~ /^DISTDIR=(.*)$/m) { - $default_distdir = abs_path($unquote->($1)); + $default_distdir = Cwd::abs_path($unquote->($1)); } if ($buffers =~ /^PORTDIR=(.*)$/m) { - $main_portdir = abs_path($unquote->($1)); + $main_portdir = Cwd::abs_path($unquote->($1)); } } else { __PACKAGE__->_abort($errmsg); @@ -191,7 +194,8 @@ sub init { my $conf = $self->parent->parent->configure_object; $stat->mk_accessors(qw/name version author distribution desc uri src license - fetched_arch requires + meta min_perl + fetched_arch requires configure_requires ebuild_name ebuild_version ebuild_dir ebuild_file portdir_overlay overlay distdir keywords do_manifest header footer @@ -203,6 +207,32 @@ sub init { return 1; } +my $filter_prereqs = sub { + my ($int, $prereqs) = @_; + + my @requires; + for my $prereq (sort keys %$prereqs) { + next if $prereq =~ /^perl(?:-|\z)/; + + my $obj = $int->module_tree($prereq); + next unless $obj; # Not in the module tree (e.g. Config) + next if $obj->package_is_perl_core; + + my $version; + if ($prereqs->{$prereq}) { + if ($obj->installed_version && $obj->installed_version < $obj->version) { + $version = $obj->installed_version; + } else { + $version = $obj->package_version; + } + } + + push @requires, [ $obj->package_name, $version ]; + } + + return \@requires; +}; + sub prepare { my $self = shift; my $mod = $self->parent; @@ -252,11 +282,11 @@ sub prepare { $stat->footer($footer); my $overlay = delete $opts{overlay}; - $overlay = (defined $overlay) ? abs_path $overlay : '/usr/local/portage'; + $overlay = (defined $overlay) ? Cwd::abs_path($overlay) : '/usr/local/portage'; $stat->overlay($overlay); my $distdir = delete $opts{distdir}; - $distdir = (defined $distdir) ? abs_path $distdir : $default_distdir; + $distdir = (defined $distdir) ? Cwd::abs_path($distdir) : $default_distdir; $stat->distdir($distdir); return $FAIL->("distdir isn't writable") if $stat->do_manifest && !-w $distdir; @@ -285,7 +315,7 @@ sub prepare { $stat->distribution($name . '-' . $version); - $stat->ebuild_version(CPANPLUS::Dist::Gentoo::Maps::version_c2g($version)); + $stat->ebuild_version(CPANPLUS::Dist::Gentoo::Maps::version_c2g($name, $version)); $stat->ebuild_name(CPANPLUS::Dist::Gentoo::Maps::name_c2g($name)); @@ -324,7 +354,7 @@ sub prepare { $stat->prepared(0); - $self->SUPER::prepare(%opts); + $self->SUPER::prepare(@_); return $FAIL->() unless $stat->prepared; @@ -339,28 +369,47 @@ sub prepare { $stat->license($self->intuit_license); - my $prereqs = $mod->status->requires; - my @requires; - for my $prereq (sort keys %$prereqs) { - next if $prereq =~ /^perl(?:-|\z)/; - my $obj = $int->module_tree($prereq); - next unless $obj; # Not in the module tree (e.g. Config) - next if $obj->package_is_perl_core; - { - my $version; - if ($prereqs->{$prereq}) { - if ($obj->installed_version && $obj->installed_version < $obj->version) { - $version = $obj->installed_version; - } else { - $version = $obj->package_version; - } - } - push @requires, [ $obj->package_name, $version ]; + my $mstat = $mod->status; + $stat->configure_requires($int->$filter_prereqs($mstat->configure_requires)); + $stat->requires($int->$filter_prereqs($mstat->requires)); + + my $meta = $self->meta; + $stat->min_perl(CPANPLUS::Dist::Gentoo::Maps::perl_version_c2g( + $meta->{requires}->{perl}, + )); + + return $OK->(); +} + +=head2 C + +Returns the contents of the F or F files as parsed by L. + +=cut + +sub meta { + my $self = shift; + my $mod = $self->parent; + my $stat = $self->status; + + my $meta = $stat->meta; + return $meta if defined $meta; + + my $extract_dir = $mod->status->extract; + + for my $name (qw/META.json META.yml/) { + my $meta_file = File::Spec->catdir($extract_dir, $name); + next unless -e $meta_file; + + local $@; + my $meta = eval { Parse::CPAN::Meta::LoadFile($meta_file) }; + if (defined $meta) { + $stat->meta($meta); + return $meta; } } - $stat->requires(\@requires); - return $OK->(); + return; } =head2 C @@ -388,20 +437,11 @@ sub intuit_license { return \@licenses if @licenses; } - my $extract_dir = $mod->status->extract; - - for my $meta_file (qw/META.json META.yml/) { - my $meta = eval { - Parse::CPAN::Meta::LoadFile(File::Spec->catdir( - $extract_dir, - $meta_file, - )); - } or next; - my $license = $meta->{license}; - if (defined $license) { - my @licenses = CPANPLUS::Dist::Gentoo::Maps::license_c2g($license); - return \@licenses if @licenses; - } + my $meta = $self->meta; + my $license = $meta->{license}; + if (defined $license) { + my @licenses = CPANPLUS::Dist::Gentoo::Maps::license_c2g($license); + return \@licenses if @licenses; } return [ CPANPLUS::Dist::Gentoo::Maps::license_c2g('perl') ]; @@ -413,7 +453,24 @@ sub create { my $file; + my $guard = CPANPLUS::Dist::Gentoo::Guard->new(sub { + if (defined $file and -e $file and -w _) { + 1 while unlink $file; + } + }); + + my $SIG_INT = $SIG{INT}; + local $SIG{INT} = sub { + if ($SIG_INT) { + local $@; + eval { $SIG_INT->() }; + die $@ if $@; + } + die 'Caught SIGINT'; + }; + my $OK = sub { + $guard->unarm; $stat->created(1); $stat->dist($file) if defined $file; 1; @@ -423,9 +480,6 @@ sub create { $stat->created(0); $stat->dist(undef); $self->_abort(@_) if @_; - if (defined $file and -f $file) { - 1 while unlink $file; - } 0; }; @@ -511,23 +565,37 @@ 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 @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( + my (@configure_requires, @requires); + + my @phases = ( + [ configure_requires => \@configure_requires ], + [ requires => \@requires ], + ); + + push @requires, CPANPLUS::Dist::Gentoo::Atom->new( category => 'dev-lang', name => 'perl', + version => $stat->min_perl, ); - @requires = CPANPLUS::Dist::Gentoo::Atom->fold($perl, @requires); + + for (@phases) { + my ($phase, $list) = @$_; + + for (@{ $stat->$phase }) { + my $atom = $self->_cpan2portage(@$_); + unless (defined $atom) { + $self->_abort( + "Couldn't find an appropriate ebuild for $_->[0] in the portage tree" + ); + return; + } + + push @$list, $atom; + } + + @$list = CPANPLUS::Dist::Gentoo::Atom->fold(@$list); + } my $d = $stat->header; $d .= "# Generated by CPANPLUS::Dist::Gentoo version $VERSION\n\n"; @@ -540,7 +608,7 @@ sub ebuild_source { $d .= 'LICENSE="|| ( ' . join(' ', sort @{$stat->license}) . " )\"\n"; $d .= 'KEYWORDS="' . join(' ', sort @{$stat->keywords}) . "\"\n"; $d .= 'RDEPEND="' . join("\n", sort @requires) . "\"\n"; - $d .= "DEPEND=\"\${RDEPEND}\"\n"; + $d .= 'DEPEND="' . join("\n", '${RDEPEND}', sort @configure_requires) . "\"\n"; $d .= "SRC_TEST=\"do\"\n"; $d .= $stat->footer; @@ -548,10 +616,10 @@ sub ebuild_source { } sub _cpan2portage { - my ($self, $name, $version) = @_; + my ($self, $dist_name, $dist_version) = @_; - $name = CPANPLUS::Dist::Gentoo::Maps::name_c2g($name); - $version = CPANPLUS::Dist::Gentoo::Maps::version_c2g($version); + my $name = CPANPLUS::Dist::Gentoo::Maps::name_c2g($dist_name); + my $version = CPANPLUS::Dist::Gentoo::Maps::version_c2g($dist_name, $dist_version); my @portdirs = ($main_portdir, @{$self->status->portdir_overlay}); @@ -566,20 +634,17 @@ sub _cpan2portage { "$name-*.ebuild", ) or next; - my @atoms = map CPANPLUS::Dist::Gentoo::Atom->new( - defined $version ? ( - ebuild => $_, - range => '>=', - ) : ( - category => $category, - name => $name, - ), - ), @ebuilds; - - my $atom = reduce { $a < $b ? $b : $a } @atoms; # handles overloading - next if defined $version and $atom < $version; + 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 $atom; + return CPANPLUS::Dist::Gentoo::Atom->new( + category => $last->category, + name => $last->name, + version => $version, + ebuild => $last->ebuild, + ); } } @@ -624,7 +689,10 @@ sub _run { my ($success, $errmsg, $output) = do { local $ENV{PORTDIR_OVERLAY} = join ' ', @{$stat->portdir_overlay}; local $ENV{PORTAGE_RO_DISTDIRS} = $stat->distdir; - run command => $cmd, verbose => $verbose; + IPC::Cmd::run( + command => $cmd, + verbose => $verbose, + ); }; unless ($success) { @@ -696,7 +764,7 @@ Kent Fredric, for testing and suggesting improvements. =head1 COPYRIGHT & LICENSE -Copyright 2008-2009 Vincent Pit, all rights reserved. +Copyright 2008,2009,2010 Vincent Pit, all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.