From: Chris 'BinGOs' Williams Date: Sun, 1 Mar 2009 21:27:17 +0000 (+0100) Subject: Update CPANPLUS::Dist::Build to 0.08 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=e83ba0bd96fd498c8594fb8a8ceeb10f76fabdfc;p=p5sagit%2Fp5-mst-13.2.git Update CPANPLUS::Dist::Build to 0.08 --- diff --git a/lib/CPANPLUS/Dist/Build.pm b/lib/CPANPLUS/Dist/Build.pm index a23b4f8..46b3567 100644 --- a/lib/CPANPLUS/Dist/Build.pm +++ b/lib/CPANPLUS/Dist/Build.pm @@ -1,6 +1,7 @@ package CPANPLUS::Dist::Build; use strict; +use warnings; use vars qw[@ISA $STATUS $VERSION]; @ISA = qw[CPANPLUS::Dist]; @@ -21,6 +22,7 @@ use CPANPLUS::Error; use Config; use FileHandle; use Cwd; +use version; use IPC::Cmd qw[run]; use Params::Check qw[check]; @@ -29,13 +31,13 @@ use Locale::Maketext::Simple Class => 'CPANPLUS', Style => 'gettext'; local $Params::Check::VERBOSE = 1; -$VERSION = '0.06_02'; +$VERSION = '0.08'; =pod =head1 NAME -CPANPLUS::Dist::Build +CPANPLUS::Dist::Build - CPANPLUS plugin to install packages that use Build.PL =head1 SYNOPSIS @@ -44,7 +46,7 @@ CPANPLUS::Dist::Build module => $modobj, ); - $build->prepare; # runs Module::Build->new_from_context; + $build->prepare; # runs Build.PL $build->create; # runs build && build test $build->install; # runs build install @@ -64,11 +66,11 @@ just C when it's loaded. =over 4 -=item parent() +=item C Returns the C object that parented this object. -=item status() +=item C Returns the C object that keeps the status for this module. @@ -82,35 +84,35 @@ All accessors can be accessed as follows: =over 4 -=item build_pl () +=item C Location of the Build file. Set to 0 explicitly if something went wrong. -=item build () +=item C BOOL indicating if the C command was successful. -=item test () +=item C BOOL indicating if the C command was successful. -=item prepared () +=item C BOOL indicating if the C call exited succesfully This gets set after C -=item distdir () +=item C Full path to the directory in which the C call took place, set after a call to C. -=item created () +=item C BOOL indicating if the C call exited succesfully. This gets set after C and C. -=item installed () +=item C BOOL indicating if the module was installed. This gets set after C exits successfully. @@ -119,25 +121,20 @@ C exits successfully. BOOL indicating if the module was uninstalled properly. -=item _create_args () +=item C<_create_args ()> Storage of the arguments passed to C for this object. Used for recursive calls when satisfying prerequisites. -=item _install_args () +=item C<_install_args ()> Storage of the arguments passed to C for this object. Used for recursive calls when satisfying prerequisites. -=item _mb_object () - -Storage of the C object we used for this installation. - =back =cut - =head1 METHODS =head2 $bool = CPANPLUS::Dist::Build->format_available(); @@ -188,12 +185,11 @@ sub init { =head2 $bool = $dist->prepare([perl => '/path/to/perl', buildflags => 'EXTRA=FLAGS', force => BOOL, verbose => BOOL]) -C prepares a distribution, running C's -C method, and establishing any prerequisites this +C prepares a distribution, running C +and establishing any prerequisites this distribution has. -When running C<< Module::Build->new_from_context >>, the environment -variable C will be set to the full path +The variable C will be set to the full path of the C that is being executed. This enables any code inside the C to know that it is being installed via CPANPLUS. @@ -273,19 +269,25 @@ sub prepare { RUN: { # Wrap the exception that may be thrown here (should likely be # done at a much higher level). - my $mb = eval { - my $env = 'ENV_CPANPLUS_IS_EXECUTING'; - local $ENV{$env} = BUILD_PL->( $dir ); - Module::Build->new_from_context( %buildflags ) - }; - if( !$mb or $@ ) { - error(loc("Could not create Module::Build object: %1","$@")); + my $prep_output; + + my $env = 'ENV_CPANPLUS_IS_EXECUTING'; + local $ENV{$env} = BUILD_PL->( $dir ); + + unless ( scalar run( command => [$perl, BUILD_PL->($dir), $buildflags], + buffer => \$prep_output, + verbose => $verbose ) + ) { + error( loc( "Build.PL failed: %1", $prep_output ) ); $fail++; last RUN; } - $dist->status->_mb_object( $mb ); + msg( $prep_output, 0 ); - $self->status->prereqs( $dist->_find_prereqs( verbose => $verbose ) ); + $self->status->prereqs( $dist->_find_prereqs( verbose => $verbose, + dir => $dir, + perl => $perl, + buildflags => $buildflags ) ); } @@ -314,16 +316,64 @@ sub prepare { sub _find_prereqs { my $dist = shift; - my $mb = $dist->status->_mb_object; my $self = $dist->parent; my $cb = $self->parent; + my $conf = $cb->configure_object; + my %hash = @_; + + my ($verbose, $dir, $buildflags, $perl); + my $tmpl = { + verbose => { default => $conf->get_conf('verbose'), store => \$verbose }, + dir => { default => $self->status->extract, store => \$dir }, + perl => { default => $^X, store => \$perl }, + buildflags => { default => $conf->get_conf('buildflags'), + store => \$buildflags }, + }; + + my $args = check( $tmpl, \%hash ) or return; my $prereqs = {}; + + my $safe_ver = version->new('0.31_03'); + + my $content; + + if ( version->new( $Module::Build::VERSION ) >= $safe_ver ) { + # Use the new Build action 'prereq_data' + + unless ( scalar run( command => [$perl, BUILD->($dir), 'prereq_data', $buildflags], + buffer => \$content, + verbose => 0 ) + ) { + error( loc( "Build 'prereq_data' failed: %1 %2", $!, $content ) ); + return; + } + + } + else { + my $file = File::Spec->catfile( $dir, '_build', 'prereqs' ); + return unless -f $file; + + my $fh = FileHandle->new(); + + unless( $fh->open( $file ) ) { + error( loc( "Cannot open '%1': %2", $file, $! ) ); + return; + } + + $content = do { local $/; <$fh> }; + } + + my $bphash = eval $content; + return unless $bphash and ref $bphash eq 'HASH'; foreach my $type ('requires', 'build_requires') { - my $p = $mb->$type() || {}; - $prereqs->{$_} = $p->{$_} foreach keys %$p; + next unless $bphash->{$type} and ref $bphash->{$type} eq 'HASH'; + $prereqs->{$_} = $bphash->{$type}->{$_} for keys %{ $bphash->{$type} }; } + # Temporary fix + delete $prereqs->{'perl'}; + ### allows for a user defined callback to filter the prerequisite ### list as they see fit, to remove (or add) any prereqs they see ### fit. The default installed callback will return the hashref in @@ -341,40 +391,12 @@ sub _find_prereqs { return { %$href }; } -sub prereq_satisfied { - # Return true if this prereq is satisfied. Return false if it's - # not. Also issue an error if the latest CPAN version doesn't - # satisfy it. - - my ($dist, %args) = @_; - my $mb = $dist->status->_mb_object; - my $cb = $dist->parent->parent; - my $mod = $args{modobj}->module; - - my $status = $mb->check_installed_status($mod, $args{version}); - return 1 if $status->{ok}; - - # Check the latest version from the CPAN index - { - no strict 'refs'; - local ${$mod . '::VERSION'} = $args{modobj}->version; - $status = $mb->check_installed_status($mod, $args{version}); - } - unless( $status->{ok} ) { - error(loc("This distribution depends on $mod, but the latest version of $mod on CPAN ". - "doesn't satisfy the specific version dependency ($args{version}). ". - "Please try to resolve this dependency manually.")); - } - - return 0; -} - =pod =head2 $dist->create([perl => '/path/to/perl', buildflags => 'EXTRA=FLAGS', prereq_target => TARGET, force => BOOL, verbose => BOOL, skiptest => BOOL]) C preps a distribution for installation. This means it will -run C and C, via the C API. +run C and C. This will also satisfy any prerequisites the module may have. If you set C to true, it will skip the C stage. @@ -403,7 +425,6 @@ sub create { my $cb = $self->parent; my $conf = $cb->configure_object; - my $mb = $dist->status->_mb_object; my %hash = @_; my $dir; @@ -509,45 +530,57 @@ sub create { last RUN; } - eval { $mb->dispatch('build', %buildflags) }; - if( $@ ) { - error(loc("Could not run '%1': %2", 'Build', "$@")); + my $captured; + + unless ( scalar run( command => [$perl, BUILD->($dir), $buildflags], + buffer => \$captured, + verbose => $verbose ) + ) { + error( loc( "MAKE failed:\n%1", $captured ) ); $dist->status->build(0); $fail++; last RUN; } + msg( $captured, 0 ); + $dist->status->build(1); ### add this directory to your lib ### - $cb->_add_to_includepath( - directories => [ BLIB_LIBDIR->( $self->status->extract ) ] - ); + $self->add_to_includepath(); ### this buffer will not include what tests failed due to a ### M::B/Test::Harness bug. Reported as #9793 with patch ### against 0.2607 on 26/1/2005 unless( $skiptest ) { - eval { $mb->dispatch('test', %buildflags) }; - if( $@ ) { - error(loc("Could not run '%1': %2", 'Build test', "$@")); + my $test_output; + my $flag = ON_VMS ? '"test"' : 'test'; + my $cmd = [$perl, BUILD->($dir), $flag, $buildflags]; + unless ( scalar run( command => $cmd, + buffer => \$test_output, + verbose => $verbose ) + ) { + error( loc( "MAKE TEST failed:\n%1 ", $test_output ) ); ### mark specifically *test* failure.. so we dont ### send success on force... $test_fail++; if( !$force and !$cb->_callbacks->proceed_on_test_failure->( - $self, $@ ) + $self, $@ ) ) { - $dist->status->test(0); - $fail++; last RUN; + $dist->status->test(0); + $fail++; last RUN; } - - } else { + + } + else { + msg( $test_output, 0 ); $dist->status->test(1); } - } else { + } + else { msg(loc("Tests skipped"), $verbose); - } + } } unless( $cb->_chdir( dir => $orig ) ) { @@ -587,7 +620,6 @@ sub install { ### we're also the cpan_dist, since we don't need to have anything ### prepared from another installer $dist = $self->status->dist_cpan if $self->status->dist_cpan; - my $mb = $dist->status->_mb_object; my $cb = $self->parent; my $conf = $cb->configure_object; @@ -658,11 +690,19 @@ sub install { } else { my %buildflags = $dist->_buildflags_as_hash($buildflags); - eval { $mb->dispatch('install', %buildflags) }; - if( $@ ) { - error(loc("Could not run '%1': %2", 'Build install', "$@")); + my $install_output; + my $flag = ON_VMS ? '"install"' : 'install'; + my $cmd = [$perl, BUILD->($dir), $flag, $buildflags]; + unless( scalar run( command => $cmd, + buffer => \$install_output, + verbose => $verbose ) + ) { + error(loc("Could not run '%1': %2", 'Build install', $install_output)); $fail++; } + else { + msg( $install_output, 0 ); + } } @@ -684,97 +724,14 @@ sub _buildflags_as_hash { return %$argv; } - -sub dist_dir { - ### just in case you already did a create call for this module object - ### just via a different dist object - my $dist = shift; - my $self = $dist->parent; - - ### we're also the cpan_dist, since we don't need to have anything - ### prepared from another installer - $dist = $self->status->dist_cpan if $self->status->dist_cpan; - my $mb = $dist->status->_mb_object; - - my $cb = $self->parent; - my $conf = $cb->configure_object; - my %hash = @_; - - - my $dir; - unless( $dir = $self->status->extract ) { - error( loc( "No dir found to operate on!" ) ); - return; - } - - ### chdir to work directory ### - my $orig = cwd(); - unless( $cb->_chdir( dir => $dir ) ) { - error( loc( "Could not chdir to build directory '%1'", $dir ) ); - return; - } - - my $fail; my $distdir; - TRY: { - $dist->prepare( @_ ) or (++$fail, last TRY); - - - eval { $mb->dispatch('distdir') }; - if( $@ ) { - error(loc("Could not run '%1': %2", 'Build distdir', "$@")); - ++$fail, last TRY; - } - - ### /path/to/Foo-Bar-1.2/Foo-Bar-1.2 - $distdir = File::Spec->catdir( $dir, $self->package_name . '-' . - $self->package_version ); - - unless( -d $distdir ) { - error(loc("Do not know where '%1' got created", 'distdir')); - ++$fail, last TRY; - } - } - - unless( $cb->_chdir( dir => $orig ) ) { - error( loc( "Could not chdir to start directory '%1'", $orig ) ); - return; - } - - return if $fail; - return $distdir; -} - -=head1 KNOWN ISSUES - -Below are some of the known issues with Module::Build, that we hope -the authors will resolve at some point, so we can make full use of -Module::Build's power. -The number listed is the bug number on C. - -=over 4 - -=item * Module::Build can not be upgraded using its own API (#13169) - -This is due to the fact that the Build file insists on adding a path -to C<@INC> which force the loading of the C -Module::Build when it shells out to run it's own build procedure: - -=item * Module::Build does not provide access to install history (#9793) - -C runs the create, test and install procedures in it's -own processes, but does not provide access to any diagnostic messages of -those processes. As an end result, we can not offer these diagnostic -messages when, for example, reporting automated build failures to sites -like C. - -=back - =head1 AUTHOR Originally by Jos Boumans Ekane@cpan.orgE. Brought to working -condition and currently maintained by Ken Williams Ekwilliams@cpan.orgE. +condition by Ken Williams Ekwilliams@cpan.orgE. + +Other hackery and currently maintained by Chris 'BinGOs' Williams ( no relation ). Ebingos@cpan.orgE. -=head1 COPYRIGHT +=head1 LICENSE The CPAN++ interface (of which this module is a part of) is copyright (c) 2001, 2002, 2003, 2004, 2005 Jos Boumans Ekane@cpan.orgE. @@ -788,9 +745,11 @@ terms as Perl itself. 1; + # Local variables: # c-indentation-style: bsd # c-basic-offset: 4 # indent-tabs-mode: nil # End: # vim: expandtab shiftwidth=4: + diff --git a/lib/CPANPLUS/Dist/Build/Constants.pm b/lib/CPANPLUS/Dist/Build/Constants.pm index 47986f9..07aaca3 100644 --- a/lib/CPANPLUS/Dist/Build/Constants.pm +++ b/lib/CPANPLUS/Dist/Build/Constants.pm @@ -1,6 +1,7 @@ package CPANPLUS::Dist::Build::Constants; use strict; +use warnings; use File::Spec; BEGIN { @@ -31,6 +32,34 @@ use constant BUILD => sub { my $file = @_ 1; +=head1 NAME + +CPANPLUS::Dist::Build::Constants - Constants for CPANPLUS::Dist::Build + +=head1 SYNOPSIS + + use CPANPLUS::Dist::Build::Constants; + +=head1 DESCRIPTION + +CPANPLUS::Dist::Build::Constants provides some constants required by L. + +=head1 AUTHOR + +Originally by Jos Boumans Ekane@cpan.orgE. Brought to working +condition and currently maintained by Ken Williams Ekwilliams@cpan.orgE. + +=head1 LICENSE + +The CPAN++ interface (of which this module is a part of) is +copyright (c) 2001, 2002, 2003, 2004, 2005 Jos Boumans Ekane@cpan.orgE. +All rights reserved. + +This library is free software; +you may redistribute and/or modify it under the same +terms as Perl itself. + +=cut # Local variables: # c-indentation-style: bsd diff --git a/lib/CPANPLUS/Dist/Build/t/02_CPANPLUS-Dist-Build.t b/lib/CPANPLUS/Dist/Build/t/02_CPANPLUS-Dist-Build.t index 2c64905..7914136 100644 --- a/lib/CPANPLUS/Dist/Build/t/02_CPANPLUS-Dist-Build.t +++ b/lib/CPANPLUS/Dist/Build/t/02_CPANPLUS-Dist-Build.t @@ -133,7 +133,8 @@ while( my($path,$need_cc) = each %Map ) { "-- skipping compile tests", 5) if $need_cc && !$Have_CC; skip("Module::Build is not compiled with C support ". "-- skipping compile tests", 5) - unless Module::Build->_mb_feature('C_support'); + unless eval { require Module::Build::ConfigData; + Module::Build::ConfigData->feature('C_support') }; ok( $mod->create( ), "Creating module" ); ok( $mod->status->dist_cpan->status->created, @@ -214,15 +215,15 @@ while( my($path,$need_cc) = each %Map ) { ### clear errors CPANPLUS::Error->flush; - ### since we're die'ing in the Build.PL, do a local *STDERR, - ### so we dont spam the result through the test -- this is expected - ### behaviour after all. - ### also quell the warning for print() on unopened fh... - my $rv = do { - local $^W; - local *STDERR; - $clone->prepare( force => 1 ) - }; + ### since we're die'ing in the Build.PL, localize + ### $CPANPLUS::Error::ERROR_FH and redirect to devnull + ### so we dont spam the result through the test + ### as this is expected behaviour after all. + my $rv = do { + local *CPANPLUS::Error::ERROR_FH; + open $CPANPLUS::Error::ERROR_FH, ">", File::Spec->devnull; + $clone->prepare( force => 1 ) + }; ok( !$rv, ' $mod->prepare failed' ); my $re = quotemeta( $build_pl );