From: Vincent Pit Date: Sun, 29 Jun 2008 15:33:34 +0000 (+0200) Subject: Importing CPANPLUS-Dist-Gentoo-0.01.tar.gz X-Git-Tag: v0.01^0 X-Git-Url: http://git.vpit.fr/?p=perl%2Fmodules%2FCPANPLUS-Dist-Gentoo.git;a=commitdiff_plain;h=012a8ae10e8fc6e70ff1b0f90c470196417c0bf1 Importing CPANPLUS-Dist-Gentoo-0.01.tar.gz --- 012a8ae10e8fc6e70ff1b0f90c470196417c0bf1 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3d0f058 --- /dev/null +++ b/.gitignore @@ -0,0 +1,16 @@ +blib* +pm_to_blib* + +Makefile{,.old} +Build +_build* + +*.tar.gz +CPANPLUS-Dist-Gentoo-* + +core.* +*.{c,o,so,bs,out,def,exp} + +cover_db +*.{gcda,gcov,gcno} + diff --git a/Changes b/Changes new file mode 100644 index 0000000..58c766a --- /dev/null +++ b/Changes @@ -0,0 +1,5 @@ +Revision history for CPANPLUS-Dist-Gentoo + +0.01 2008-05-20 18:10 UTC + First version, released on an unsuspecting world. + diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..39051ee --- /dev/null +++ b/MANIFEST @@ -0,0 +1,12 @@ +Changes +MANIFEST +Makefile.PL +README +lib/CPANPLUS/Dist/Gentoo.pm +t/00-load.t +t/90-boilerplate.t +t/91-pod.t +t/92-pod-coverage.t +t/95-portability-files.t +t/99-kwalitee.t +META.yml Module meta-data (added by MakeMaker) diff --git a/META.yml b/META.yml new file mode 100644 index 0000000..ba2e566 --- /dev/null +++ b/META.yml @@ -0,0 +1,21 @@ +--- #YAML:1.0 +name: CPANPLUS-Dist-Gentoo +version: 0.01 +abstract: CPANPLUS backend generating Gentoo ebuilds. +license: perl +author: + - Vincent Pit +generated_by: ExtUtils::MakeMaker version 6.42 +distribution_type: module +requires: + CPANPLUS: 0 + File::Copy: 0 + File::Path: 0 + File::Spec::Functions: 0 + IPC::Cmd: 0 +meta-spec: + url: http://module-build.sourceforge.net/META-spec-v1.3.html + version: 1.3 +build_requires: + ExtUtils::MakeMaker: 0 + Test::More: 0 diff --git a/Makefile.PL b/Makefile.PL new file mode 100644 index 0000000..f58f0ca --- /dev/null +++ b/Makefile.PL @@ -0,0 +1,42 @@ +use 5.006; + +use strict; +use warnings; +use ExtUtils::MakeMaker; + +my $BUILD_REQUIRES = { + 'ExtUtils::MakeMaker' => 0, + 'Test::More' => 0, +}; + +sub build_req { + my $tometa = ' >> $(DISTVNAME)/META.yml;'; + my $build_req = 'echo "build_requires:" ' . $tometa; + foreach my $mod ( sort { lc $a cmp lc $b } keys %$BUILD_REQUIRES ) { + my $ver = $BUILD_REQUIRES->{$mod}; + $build_req .= sprintf 'echo " %-30s %s" %s', "$mod:", $ver, $tometa; + } + return $build_req; +} + +WriteMakefile( + NAME => 'CPANPLUS::Dist::Gentoo', + AUTHOR => 'Vincent Pit ', + LICENSE => 'perl', + VERSION_FROM => 'lib/CPANPLUS/Dist/Gentoo.pm', + ABSTRACT_FROM => 'lib/CPANPLUS/Dist/Gentoo.pm', + PL_FILES => {}, + PREREQ_PM => { + 'CPANPLUS' => 0, + 'File::Copy' => 0, + 'File::Path' => 0, + 'File::Spec::Functions' => 0, + 'IPC::Cmd' => 0 + }, + dist => { + PREOP => 'pod2text lib/CPANPLUS/Dist/Gentoo.pm > $(DISTVNAME)/README; ' + . build_req, + COMPRESS => 'gzip -9f', SUFFIX => 'gz' + }, + clean => { FILES => 'CPANPLUS-Dist-Gentoo-* *.gcov *.gcda *.gcno cover_db' }, +); diff --git a/README b/README new file mode 100644 index 0000000..05c6e8d --- /dev/null +++ b/README @@ -0,0 +1,66 @@ +NAME + CPANPLUS::Dist::Gentoo - CPANPLUS backend generating Gentoo ebuilds. + +VERSION + Version 0.01 + +SYNOPSIS + cpan2dist --format=CPANPLUS::Dist::Gentoo \ + --dist-opts overlay=/usr/local/portage \ + --dist-opts distdir=/usr/portage/distfiles \ + --dist-opts manifest=yes \ + Any::Module You::Like + +DESCRPITON + This module is a CPANPLUS backend that recursively generates Gentoo + ebuilds for a given package in the specified overlay (defaults to + "/usr/local/portage"), update the manifest, and even emerge it (together + with its dependencies) if the user requires it. You need write + permissions on the directory where Gentoo fetches its source files + (usually "/usr/portage/distfiles"). + + The generated ebuilds are placed into the section "perl-cpanp". They + favour depending on "perl-core" or "dev-perl" rather than "perl-cpanp". + +METHODS + All the methods are inherited from CPANPLUS::Dist::Base. Please refer to + its perldoc for precise information on what's done at each step. + +DEPENDENCIES + Gentoo (). + + CPANPLUS, IPC::Cmd (core modules since 5.9.5). + + File::Path (since 5.001), File::Copy (5.002), File::Spec::Functions + (5.00504). + +SEE ALSO + cpan2dist. + + CPANPLUS::Dist::Base, CPANPLUS::Dist::Deb, CPANPLUS::Dist::Mdv. + +AUTHOR + Vincent Pit, "", . + +BUGS + Please report any bugs or feature requests to "bug-cpanplus-dist-gentoo + at rt.cpan.org", or through the web interface at + . I + will be notified, and then you'll automatically be notified of progress + on your bug as I make changes. + +SUPPORT + You can find documentation for this module with the perldoc command. + + perldoc CPANPLUS::Dist::Gentoo + +ACKNOWLEDGEMENTS + The module is to some extend cargo-culted from CPANPLUS::Dist::Deb and + CPANPLUS::Dist::Mdv. + +COPYRIGHT & LICENSE + Copyright 2008 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. + diff --git a/lib/CPANPLUS/Dist/Gentoo.pm b/lib/CPANPLUS/Dist/Gentoo.pm new file mode 100644 index 0000000..9450954 --- /dev/null +++ b/lib/CPANPLUS/Dist/Gentoo.pm @@ -0,0 +1,308 @@ +package CPANPLUS::Dist::Gentoo; + +use strict; +use warnings; + +use File::Copy qw/copy/; +use File::Path qw/mkpath/; +use File::Spec::Functions qw/catdir catfile/; + +use IPC::Cmd qw/run can_run/; + +use CPANPLUS::Error; + +use base qw/CPANPLUS::Dist::Base/; + +=head1 NAME + +CPANPLUS::Dist::Gentoo - CPANPLUS backend generating Gentoo ebuilds. + +=head1 VERSION + +Version 0.01 + +=cut + +our $VERSION = '0.01'; + +=head1 SYNOPSIS + + cpan2dist --format=CPANPLUS::Dist::Gentoo \ + --dist-opts overlay=/usr/local/portage \ + --dist-opts distdir=/usr/portage/distfiles \ + --dist-opts manifest=yes \ + Any::Module You::Like + +=head1 DESCRPITON + +This module is a CPANPLUS backend that recursively generates Gentoo ebuilds for a given package in the specified overlay (defaults to C), update the manifest, and even emerge it (together with its dependencies) if the user requires it. You need write permissions on the directory where Gentoo fetches its source files (usually C). + +The generated ebuilds are placed into the section C. They favour depending on C or C rather than C. + +=head1 METHODS + +All the methods are inherited from L. Please refer to its perldoc for precise information on what's done at each step. + +=cut + +sub format_available { + for my $prog (qw/emerge ebuild/) { + unless (can_run($prog)) { + error "$prog is required to write ebuilds -- aborting"; + return 0; + } + } + return 1; +} + +my $overlay; + +sub init { + my ($self) = @_; + my $stat = $self->status; + $stat->mk_accessors(qw/name version dist desc uri src license deps + eb_name eb_version eb_dir eb_file distdir fetched_arch + do_manifest/); + + return 1; +} + +my %gentooism = ( + 'Digest' => 'digest-base', + 'Locale-Maketext' => 'locale-maketext', + 'Net-Ping' => 'net-ping', + 'PathTools' => 'File-Spec', + 'PodParser' => 'Pod-Parser', +); + +sub prepare { + my $self = shift; + my $mod = $self->parent; + my $stat = $self->status; + my $int = $mod->parent; + my $conf = $int->configure_object; + + my %opts = @_; + + my $manifest = delete($opts{'manifest'}); + $manifest = 0 if not defined $manifest or $manifest =~ /^\s*no?\s*$/i; + $stat->do_manifest($manifest); + my $overlay = catdir(delete($opts{'overlay'}) || '/usr/local/portage', + 'perl-cpanp'); + $stat->distdir(delete($opts{'distdir'}) || '/usr/portage/distfiles'); + if ($stat->do_manifest && !-w $stat->distdir) { + error 'distdir isn\'t writable -- aborting'; + return 0; + } + $stat->fetched_arch($mod->status->fetch); + + my $name = $mod->package_name; + $stat->name($name); + + my $version = $mod->package_version; + $stat->version($version); + $stat->dist($name . '-' . $version); + my $f = 1; + $version =~ s/_+/$f ? do { $f = 0; '_p' } : ''/ge; + 1 while $version =~ s/(_p[^.]*)\.+/$1/; + $stat->eb_version($version); + + $stat->eb_name($gentooism{$stat->name} || $stat->name); + $stat->eb_dir(catdir($overlay, $stat->eb_name)); + $stat->eb_file(catfile($stat->eb_dir, + $stat->eb_name . '-' . $stat->eb_version . '.ebuild')); + if (-r $stat->eb_file) { + msg 'Ebuild already generated for ' . $stat->dist . ' -- skipping'; + $stat->prepared(1); + $stat->created(1); + return 1; + } + + $self->SUPER::prepare(%opts); + + my $desc = $mod->description; + ($desc = $name) =~ s/-+/::/g unless $desc; + $stat->desc($desc); + $stat->uri('http://search.cpan.org/dist/' . $name); + unless ($name =~ /^([^-]+)/) { + error 'Wrong distribution name -- aborting'; + return 0; + } + $stat->src('mirror://cpan/modules/by-module/' . $1 . '/' . $mod->package); + $stat->license([ qw/Artistic GPL-2/ ]); + + my $prereqs = $mod->status->prereqs; + my @depends; + for my $prereq (sort keys %$prereqs) { + my $obj = $int->module_tree($prereq); + unless ($obj) { + error 'Wrong module object -- aborting'; + return 0; + } + 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 @depends, [ $obj , $version ]; + } + } + $stat->deps(\@depends); + + return 1; +} + +sub create { + my $self = shift; + my $stat = $self->status; + + unless ($stat->prepared) { + error 'Can\'t create ' . $stat->dist . ' since it was never prepared -- aborting'; + return 0; + } + + if ($stat->created) { + msg $stat->dist . ' was already created -- skipping'; + return 1; + } + + $self->SUPER::create(@_); + + my $dir = $stat->eb_dir; + print STDERR "@@@ mkdir $dir\n"; + unless (-d $dir) { + eval { mkpath $dir }; + if ($@) { + error "mkpath($dir): $@"; + return 0; + } + } + + my $d = "# Generated by CPANPLUS::Dist::Gentoo\n\ninherit perl-module\n\n"; + $d .= 'S="${WORKDIR}/' . $stat->dist . "\"\n"; + $d .= 'DESCRIPTION="' . $stat->desc . "\"\n"; + $d .= 'HOMEPAGE="' . $stat->uri . "\"\n"; + $d .= 'SRC_URI="' . $stat->src . "\"\n"; + $d .= "SLOT=\"0\"\n"; + $d .= 'LICENSE="|| ( ' . join(' ', sort @{$stat->license}) . " )\"\n"; + $d .= 'DEPEND="' . join "\n", + 'dev-lang/perl', + map { + my $a = $_->[0]->package_name; + my $x = ''; + if (defined $_->[1]) { + $x = '>='; + $a .= '-' . $_->[1]; + } + '|| ( ' . join(' ', map "$x$_/$a", + qw/perl-core dev-perl perl-cpanp/) # perl-gcpan ? + . ' )'; + } @{$stat->deps}; + $d .= "\"\n"; + + my $file = $stat->eb_file; + open my $eb, '>', $file or do { + error "open($file): $! -- aborting"; + return 0; + }; + print $eb $d; + close $eb; + + if ($stat->do_manifest) { + unless (copy $stat->fetched_arch, $stat->distdir) { + error "Couldn\'t copy the distribution file to distdir ($!) -- aborting"; + 1 while unlink $file; + return 0; + } + + msg 'Adding Manifest entry for ' . $stat->dist; + unless (scalar run command => [ 'ebuild', $file, 'manifest' ], verbose => 0) { + error 'ebuild manifest failed -- aborting'; + 1 while unlink $file; + return 0; + } + } + + return 1; +} + +sub install { + my $self = shift; + my $stat = $self->status; + my $conf = $self->parent->parent->configure_object; + + my $sudo = $conf->get_program('sudo'); + my @cmd = 'emerge', '=' . $stat->eb_name . '-' . $stat->eb_version; + unshift @cmd, $sudo if $sudo; + + unless (run command => \@cmd, verbose => 1) { + error 'emerge failed -- aborting'; + return 0; + } + + return 1; +} + +sub uninstall { + my $self = shift; + my $stat = $self->status; + my $conf = $self->parent->parent->configure_object; + + my $sudo = $conf->get_program('sudo'); + my @cmd = 'emerge', '=' . $stat->eb_name . '-' . $stat->eb_version; + unshift @cmd, $sudo if $sudo; + + unless (run command => \@cmd, verbose => 1) { + error 'emerge -C failed -- aborting'; + return 0; + } + + return 1; +} + +=head1 DEPENDENCIES + +Gentoo (L). + +L, L (core modules since 5.9.5). + +L (since 5.001), L (5.002), L (5.00504). + +=head1 SEE ALSO + +L. + +L, L, L. + +=head1 AUTHOR + +Vincent Pit, C<< >>, L. + +=head1 BUGS + +Please report any bugs or feature requests to C, or through the web interface at L. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes. + +=head1 SUPPORT + +You can find documentation for this module with the perldoc command. + + perldoc CPANPLUS::Dist::Gentoo + +=head1 ACKNOWLEDGEMENTS + +The module is to some extend cargo-culted from L and L. + +=head1 COPYRIGHT & LICENSE + +Copyright 2008 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. + +=cut + +1; # End of CPANPLUS::Dist::Gentoo diff --git a/t/00-load.t b/t/00-load.t new file mode 100644 index 0000000..ba9be8c --- /dev/null +++ b/t/00-load.t @@ -0,0 +1,12 @@ +#!perl -T + +use strict; +use warnings; + +use Test::More tests => 1; + +BEGIN { + use_ok( 'CPANPLUS::Dist::Gentoo' ); +} + +diag( "Testing CPANPLUS::Dist::Gentoo $CPANPLUS::Dist::Gentoo::VERSION, Perl $], $^X" ); diff --git a/t/90-boilerplate.t b/t/90-boilerplate.t new file mode 100644 index 0000000..f743770 --- /dev/null +++ b/t/90-boilerplate.t @@ -0,0 +1,49 @@ +#!perl -T + +use strict; +use warnings; +use Test::More tests => 3; + +sub not_in_file_ok { + my ($filename, %regex) = @_; + open( my $fh, '<', $filename ) + or die "couldn't open $filename for reading: $!"; + + my %violated; + + while (my $line = <$fh>) { + while (my ($desc, $regex) = each %regex) { + if ($line =~ $regex) { + push @{$violated{$desc}||=[]}, $.; + } + } + } + + if (%violated) { + fail("$filename contains boilerplate text"); + diag "$_ appears on lines @{$violated{$_}}" for keys %violated; + } else { + pass("$filename contains no boilerplate text"); + } +} + +sub module_boilerplate_ok { + my ($module) = @_; + not_in_file_ok($module => + 'the great new $MODULENAME' => qr/ - The great new /, + 'boilerplate description' => qr/Quick summary of what the module/, + 'stub function definition' => qr/function[12]/, + ); +} + +not_in_file_ok(README => + "The README is used..." => qr/The README is used/, + "'version information here'" => qr/to provide version information/, +); + +not_in_file_ok(Changes => + "placeholder date/time" => qr(Date/time) +); + +module_boilerplate_ok('lib/CPANPLUS/Dist/Gentoo.pm'); + diff --git a/t/91-pod.t b/t/91-pod.t new file mode 100644 index 0000000..ee8b18a --- /dev/null +++ b/t/91-pod.t @@ -0,0 +1,12 @@ +#!perl -T + +use strict; +use warnings; +use Test::More; + +# Ensure a recent version of Test::Pod +my $min_tp = 1.22; +eval "use Test::Pod $min_tp"; +plan skip_all => "Test::Pod $min_tp required for testing POD" if $@; + +all_pod_files_ok(); diff --git a/t/92-pod-coverage.t b/t/92-pod-coverage.t new file mode 100644 index 0000000..27e0cf8 --- /dev/null +++ b/t/92-pod-coverage.t @@ -0,0 +1,16 @@ +use strict; +use warnings; +use Test::More; + +# Ensure a recent version of Test::Pod::Coverage +my $min_tpc = 1.08; +eval "use Test::Pod::Coverage $min_tpc"; +plan skip_all => "Test::Pod::Coverage $min_tpc required for testing POD coverage" if $@; + +# Test::Pod::Coverage doesn't require a minimum Pod::Coverage version, +# but older versions don't recognize some common documentation styles +my $min_pc = 0.18; +eval "use Pod::Coverage $min_pc"; +plan skip_all => "Pod::Coverage $min_pc required for testing POD coverage" if $@; + +all_pod_coverage_ok( { also_private => [ qw/format_available init prepare create install uninstall/ ] }); diff --git a/t/95-portability-files.t b/t/95-portability-files.t new file mode 100644 index 0000000..ab541f3 --- /dev/null +++ b/t/95-portability-files.t @@ -0,0 +1,10 @@ +#!perl -T + +use strict; +use warnings; + +use Test::More; + +eval "use Test::Portability::Files"; +plan skip_all => "Test::Portability::Files required for testing filenames portability" if $@; +run_tests(); diff --git a/t/99-kwalitee.t b/t/99-kwalitee.t new file mode 100644 index 0000000..7775e60 --- /dev/null +++ b/t/99-kwalitee.t @@ -0,0 +1,9 @@ +#!perl + +use strict; +use warnings; + +use Test::More; + +eval { require Test::Kwalitee; Test::Kwalitee->import() }; +plan( skip_all => 'Test::Kwalitee not installed; skipping' ) if $@;