1package CPANPLUS::Dist::Build;
2$CPANPLUS::Dist::Build::VERSION = '0.90';
3#ABSTRACT: CPANPLUS plugin to install packages that use Build.PL
4
5use if $] > 5.017, 'deprecate';
6
7use strict;
8use warnings;
9use vars    qw[@ISA $STATUS];
10@ISA =      qw[CPANPLUS::Dist];
11
12use CPANPLUS::Internals::Constants;
13
14### these constants were exported by CPANPLUS::Internals::Constants
15### in previous versions.. they do the same though. If we want to have
16### a normal 'use' here, up the dependency to CPANPLUS 0.056 or higher
17BEGIN {
18    require CPANPLUS::Dist::Build::Constants;
19    CPANPLUS::Dist::Build::Constants->import()
20        if not __PACKAGE__->can('BUILD') && __PACKAGE__->can('BUILD_DIR');
21}
22
23use CPANPLUS::Error;
24
25use Config;
26use FileHandle;
27use Cwd;
28use version;
29
30use IPC::Cmd                    qw[run];
31use Params::Check               qw[check];
32use Module::Load::Conditional   qw[can_load check_install];
33use Locale::Maketext::Simple    Class => 'CPANPLUS', Style => 'gettext';
34
35local $Params::Check::VERBOSE = 1;
36
37
38
39### check if the format is available ###
40sub format_available {
41    my $mod = 'Module::Build';
42    unless( can_load( modules => { $mod => '0.2611' }, nocache => 1 ) ) {
43        error( loc( "You do not have '%1' -- '%2' not available",
44                    $mod, __PACKAGE__ ) );
45        return;
46    }
47
48    return 1;
49}
50
51
52
53sub init {
54    my $dist    = shift;
55    my $status  = $dist->status;
56
57    $status->mk_accessors(qw[build_pl build test created installed uninstalled
58                             _create_args _install_args _prepare_args
59                             _mb_object _buildflags _metadata
60                            ]);
61
62    ### just in case 'format_available' didn't get called
63    require Module::Build;
64
65    return 1;
66}
67
68
69sub prepare {
70    ### just in case you already did a create call for this module object
71    ### just via a different dist object
72    my $dist = shift;
73    my $self = $dist->parent;
74
75    ### we're also the cpan_dist, since we don't need to have anything
76    ### prepared from another installer
77    $dist    = $self->status->dist_cpan if      $self->status->dist_cpan;
78    $self->status->dist_cpan( $dist )   unless  $self->status->dist_cpan;
79
80    my $cb   = $self->parent;
81    my $conf = $cb->configure_object;
82    my %hash = @_;
83
84    my $dir;
85    unless( $dir = $self->status->extract ) {
86        error( loc( "No dir found to operate on!" ) );
87        return;
88    }
89
90    my $args;
91    my( $force, $verbose, $buildflags, $perl, $prereq_target, $prereq_format,
92        $prereq_build );
93    {   local $Params::Check::ALLOW_UNKNOWN = 1;
94        my $tmpl = {
95            force           => {    default => $conf->get_conf('force'),
96                                    store   => \$force },
97            verbose         => {    default => $conf->get_conf('verbose'),
98                                    store   => \$verbose },
99            perl            => {    default => $^X, store => \$perl },
100            buildflags      => {    default => $conf->get_conf('buildflags'),
101                                    store   => \$buildflags },
102            prereq_target   => {    default => '', store => \$prereq_target },
103            prereq_format   => {    default => '',
104                                    store   => \$prereq_format },
105            prereq_build    => {    default => 0, store => \$prereq_build },
106        };
107
108        $args = check( $tmpl, \%hash ) or return;
109    }
110
111    return 1 if $dist->status->prepared && !$force;
112
113    $dist->status->_prepare_args( $args );
114
115    ### chdir to work directory ###
116    my $orig = cwd();
117    unless( $cb->_chdir( dir => $dir ) ) {
118        error( loc( "Could not chdir to build directory '%1'", $dir ) );
119        return;
120    }
121
122    ### by now we've loaded module::build, and we're using the API, so
123    ### it's safe to remove CPANPLUS::inc from our inc path, especially
124    ### because it can trip up tests run under taint (just like EU::MM).
125    ### turn off our PERL5OPT so no modules from CPANPLUS::inc get
126    ### included in make test -- it should build without.
127    ### also, modules that run in taint mode break if we leave
128    ### our code ref in perl5opt
129    ### XXX we've removed the ENV settings from cp::inc, so only need
130    ### to reset the @INC
131    #local $ENV{PERL5OPT} = CPANPLUS::inc->original_perl5opt;
132    #local $ENV{PERL5LIB} = CPANPLUS::inc->original_perl5lib;
133    #local @INC           = CPANPLUS::inc->original_inc;
134
135    ### this will generate warnings under anything lower than M::B 0.2606
136    my @buildflags = $dist->_buildflags_as_list( $buildflags );
137    $dist->status->_buildflags( $buildflags );
138
139    my $fail; my $prereq_fail;
140    my $status = { };
141    RUN: {
142
143        # 0.85_01
144        ### we resolve 'configure requires' here, so we can run the 'perl
145        ### Makefile.PL' command
146        ### XXX for tests: mock f_c_r to something that *can* resolve and
147        ### something that *doesn't* resolve. Check the error log for ok
148        ### on this step or failure
149        ### XXX make a separate tarball to test for this scenario: simply
150        ### containing a makefile.pl/build.pl for test purposes?
151        my $safe_ver = version->new('0.85_01');
152        if ( version->new($CPANPLUS::Internals::VERSION) >= $safe_ver )
153        {   my $configure_requires = $dist->find_configure_requires;
154            my $ok = $dist->_resolve_prereqs(
155                            format          => $prereq_format,
156                            verbose         => $verbose,
157                            prereqs         => $configure_requires,
158                            target          => $prereq_target,
159                            force           => $force,
160                            prereq_build    => $prereq_build,
161                    );
162
163            unless( $ok ) {
164
165                #### use $dist->flush to reset the cache ###
166                error( loc( "Unable to satisfy '%1' for '%2' " .
167                            "-- aborting install",
168                            'configure_requires', $self->module ) );
169                $dist->status->prepared(0);
170                $prereq_fail++;
171                $fail++;
172                last RUN;
173            }
174            ### end of prereq resolving ###
175        }
176
177        # Wrap the exception that may be thrown here (should likely be
178        # done at a much higher level).
179        my $prep_output;
180
181        my $metadata = $dist->status->_metadata;
182        my $x_use_unsafe_inc = ( defined $metadata && exists $metadata->{x_use_unsafe_inc} ? $metadata->{x_use_unsafe_inc} : undef );
183        $x_use_unsafe_inc = 1 unless defined $x_use_unsafe_inc;
184
185        local $ENV{PERL_USE_UNSAFE_INC} = $x_use_unsafe_inc
186          unless exists $ENV{PERL_USE_UNSAFE_INC};
187
188        my $env = ENV_CPANPLUS_IS_EXECUTING;
189        local $ENV{$env} = BUILD_PL->( $dir );
190        my @run_perl    = $dist->_perlrun();
191        my $cmd = [$perl, @run_perl, BUILD_PL->($dir), @buildflags];
192
193        unless ( scalar run(    command => $cmd,
194                                buffer  => \$prep_output,
195                                verbose => $verbose )
196        ) {
197            error( loc( "Build.PL failed: %1", $prep_output ) );
198            if ( $conf->get_conf('cpantest') ) {
199               $status->{stage} = 'prepare';
200               $status->{capture} = $prep_output;
201            }
202            $fail++; last RUN;
203        }
204
205        unless ( -e BUILD->( $dir ) ) {
206            error( loc( "Build.PL failed to generate a Build script: %1", $prep_output ) );
207            if ( $conf->get_conf('cpantest') ) {
208               $status->{stage} = 'prepare';
209               $status->{capture} = $prep_output;
210            }
211            $fail++; last RUN;
212        }
213
214        msg( $prep_output, 0 );
215
216        my $prereqs = $self->status->prereqs;
217
218        $prereqs ||= $dist->_find_prereqs( verbose => $verbose,
219                                           dir => $dir,
220                                           perl => $perl,
221                                           buildflags => $buildflags );
222
223    }
224
225    ### send out test report? ###
226    ### there is no way to accurately know if it is a PASS/FAIL/ETC
227    ### CPANPLUS::Dist::MM doesn't bother why are we?
228    if( 0 and $fail and $conf->get_conf('cpantest') and not $prereq_fail ) {
229           $cb->_send_report(
230            module  => $self,
231            failed  => $fail,
232            buffer  => CPANPLUS::Error->stack_as_string,
233            status  => $status,
234            verbose => $verbose,
235            force   => $force,
236        ) or error(loc("Failed to send test report for '%1'",
237                    $self->module ) );
238    }
239
240    unless( $cb->_chdir( dir => $orig ) ) {
241        error( loc( "Could not chdir back to start dir '%1'", $orig ) );
242    }
243
244    ### save where we wrote this stuff -- same as extract dir in normal
245    ### installer circumstances
246    $dist->status->distdir( $self->status->extract );
247
248    return $dist->status->prepared( $fail ? 0 : 1 );
249}
250
251sub _find_prereqs {
252    my $dist = shift;
253    my $self = $dist->parent;
254    my $cb   = $self->parent;
255    my $conf = $cb->configure_object;
256    my %hash = @_;
257
258    my ($verbose, $dir, $buildflags, $perl);
259    my $tmpl = {
260        verbose => { default => $conf->get_conf('verbose'), store => \$verbose },
261        dir     => { default => $self->status->extract, store => \$dir },
262        perl    => { default => $^X, store => \$perl },
263        buildflags => { default => $conf->get_conf('buildflags'),
264                        store   => \$buildflags },
265    };
266
267    my $args = check( $tmpl, \%hash ) or return;
268
269    my $prereqs = {};
270
271    $prereqs = $dist->find_mymeta_requires()
272       if $dist->can('find_mymeta_requires');
273
274    if ( keys %$prereqs ) {
275        # Ugly hack
276    }
277    else {
278      my $safe_ver = version->new('0.31_03');
279      my $content;
280      PREREQS: {
281        if ( version->new( $Module::Build::VERSION ) >= $safe_ver and IPC::Cmd->can_capture_buffer ) {
282          my @buildflags = $dist->_buildflags_as_list( $buildflags );
283
284          # Use the new Build action 'prereq_data'
285          my @run_perl    = $dist->_perlrun();
286
287          unless ( scalar run(    command => [$perl, @run_perl, BUILD->($dir), 'prereq_data', @buildflags],
288                                buffer  => \$content,
289                                verbose => 0 )
290          ) {
291            error( loc( "Build 'prereq_data' failed: %1 %2", $!, $content ) );
292            #return;
293          }
294          else {
295            last PREREQS;
296          }
297
298        }
299
300        my $file = File::Spec->catfile( $dir, '_build', 'prereqs' );
301        return unless -f $file;
302
303        my $fh = FileHandle->new();
304
305        unless( $fh->open( $file ) ) {
306          error( loc( "Cannot open '%1': %2", $file, $! ) );
307          return;
308        }
309
310        $content = do { local $/; <$fh> };
311
312      }
313
314      return unless $content;
315      my $bphash = eval $content;
316      return unless $bphash and ref $bphash eq 'HASH';
317      foreach my $type ('requires', 'build_requires', 'test_requires') {
318        next unless $bphash->{$type} and ref $bphash->{$type} eq 'HASH';
319        $prereqs->{$_} = $bphash->{$type}->{$_} for keys %{ $bphash->{$type} };
320      }
321    }
322
323    {
324      delete $prereqs->{'perl'}
325         unless version->new($CPANPLUS::Internals::VERSION)
326             >= version->new('0.9102');
327    }
328
329    ### allows for a user defined callback to filter the prerequisite
330    ### list as they see fit, to remove (or add) any prereqs they see
331    ### fit. The default installed callback will return the hashref in
332    ### an unmodified form
333    ### this callback got added after cpanplus 0.0562, so use a 'can'
334    ### to find out if it's supported. For older versions, we'll just
335    ### return the hashref as is ourselves.
336    my $href    = $cb->_callbacks->can('filter_prereqs')
337                    ? $cb->_callbacks->filter_prereqs->( $cb, $prereqs )
338                    : $prereqs;
339
340    $self->status->prereqs( $href );
341
342    ### make sure it's not the same ref
343    return { %$href };
344}
345
346
347sub create {
348    ### just in case you already did a create call for this module object
349    ### just via a different dist object
350    my $dist = shift;
351    my $self = $dist->parent;
352
353    ### we're also the cpan_dist, since we don't need to have anything
354    ### prepared from another installer
355    $dist    = $self->status->dist_cpan if      $self->status->dist_cpan;
356    $self->status->dist_cpan( $dist )   unless  $self->status->dist_cpan;
357
358    my $cb   = $self->parent;
359    my $conf = $cb->configure_object;
360    my %hash = @_;
361
362    my $dir;
363    unless( $dir = $self->status->extract ) {
364        error( loc( "No dir found to operate on!" ) );
365        return;
366    }
367
368    my $args;
369    my( $force, $verbose, $buildflags, $skiptest, $prereq_target,
370        $perl, $prereq_format, $prereq_build);
371    {   local $Params::Check::ALLOW_UNKNOWN = 1;
372        my $tmpl = {
373            force           => {    default => $conf->get_conf('force'),
374                                    store   => \$force },
375            verbose         => {    default => $conf->get_conf('verbose'),
376                                    store   => \$verbose },
377            perl            => {    default => $^X, store => \$perl },
378            buildflags      => {    default => $conf->get_conf('buildflags'),
379                                    store   => \$buildflags },
380            skiptest        => {    default => $conf->get_conf('skiptest'),
381                                    store   => \$skiptest },
382            prereq_target   => {    default => '', store => \$prereq_target },
383            ### don't set the default format to 'build' -- that is wrong!
384            prereq_format   => {    #default => $self->status->installer_type,
385                                    default => '',
386                                    store   => \$prereq_format },
387            prereq_build    => {    default => 0, store => \$prereq_build },
388        };
389
390        $args = check( $tmpl, \%hash ) or return;
391    }
392
393    # restore the state as we have created this already.
394    if ( $dist->status->created && !$force ) {
395        ### add this directory to your lib ###
396        $self->add_to_includepath();
397        return 1;
398    }
399
400    $dist->status->_create_args( $args );
401
402    ### is this dist prepared?
403    unless( $dist->status->prepared ) {
404        error( loc( "You have not successfully prepared a '%2' distribution ".
405                    "yet -- cannot create yet", __PACKAGE__ ) );
406        return;
407    }
408
409    ### chdir to work directory ###
410    my $orig = cwd();
411    unless( $cb->_chdir( dir => $dir ) ) {
412        error( loc( "Could not chdir to build directory '%1'", $dir ) );
413        return;
414    }
415
416    ### by now we've loaded module::build, and we're using the API, so
417    ### it's safe to remove CPANPLUS::inc from our inc path, especially
418    ### because it can trip up tests run under taint (just like EU::MM).
419    ### turn off our PERL5OPT so no modules from CPANPLUS::inc get
420    ### included in make test -- it should build without.
421    ### also, modules that run in taint mode break if we leave
422    ### our code ref in perl5opt
423    ### XXX we've removed the ENV settings from cp::inc, so only need
424    ### to reset the @INC
425    #local $ENV{PERL5OPT} = CPANPLUS::inc->original_perl5opt;
426    #local $ENV{PERL5LIB} = CPANPLUS::inc->original_perl5lib;
427    #local @INC           = CPANPLUS::inc->original_inc;
428
429    ### but do it *before* the new_from_context, as M::B seems
430    ### to be actually running the file...
431    ### an unshift in the block seems to be ignored.. somehow...
432    #{   my $lib = $self->best_path_to_module_build;
433    #    unshift @INC, $lib if $lib;
434    #}
435    unshift @INC, $self->best_path_to_module_build
436                if $self->best_path_to_module_build;
437
438    ### this will generate warnings under anything lower than M::B 0.2606
439    my @buildflags = $dist->_buildflags_as_list( $buildflags );
440    $dist->status->_buildflags( $buildflags );
441
442    my $fail; my $prereq_fail; my $test_fail;
443    my $status = { };
444    RUN: {
445
446        my @run_perl    = $dist->_perlrun();
447
448        ### this will set the directory back to the start
449        ### dir, so we must chdir /again/
450        my $ok = $dist->_resolve_prereqs(
451                        force           => $force,
452                        format          => $prereq_format,
453                        verbose         => $verbose,
454                        prereqs         => $self->status->prereqs,
455                        target          => $prereq_target,
456                        prereq_build    => $prereq_build,
457                    );
458
459        my $metadata = $dist->status->_metadata;
460        my $x_use_unsafe_inc = ( defined $metadata && exists $metadata->{x_use_unsafe_inc} ? $metadata->{x_use_unsafe_inc} : undef );
461        $x_use_unsafe_inc = 1 unless defined $x_use_unsafe_inc;
462
463        local $ENV{PERL_USE_UNSAFE_INC} = $x_use_unsafe_inc
464          unless exists $ENV{PERL_USE_UNSAFE_INC};
465
466        unless( $cb->_chdir( dir => $dir ) ) {
467            error( loc( "Could not chdir to build directory '%1'", $dir ) );
468            return;
469        }
470
471        unless( $ok ) {
472            #### use $dist->flush to reset the cache ###
473            error( loc( "Unable to satisfy prerequisites for '%1' " .
474                        "-- aborting install", $self->module ) );
475            $dist->status->build(0);
476            $fail++; $prereq_fail++;
477            last RUN;
478        }
479
480        my ($captured, $cmd);
481        if ( ON_VMS ) {
482            $cmd = [$perl, BUILD->($dir), @buildflags];
483        }
484        else {
485            $cmd = [$perl, @run_perl, BUILD->($dir), @buildflags];
486        }
487
488        unless ( scalar run(    command => $cmd,
489                                buffer  => \$captured,
490                                verbose => $verbose )
491        ) {
492            error( loc( "MAKE failed:\n%1", $captured ) );
493            $dist->status->build(0);
494            if ( $conf->get_conf('cpantest') ) {
495               $status->{stage} = 'build';
496               $status->{capture} = $captured;
497            }
498            $fail++; last RUN;
499        }
500
501        msg( $captured, 0 );
502
503        $dist->status->build(1);
504
505        ### add this directory to your lib ###
506        $self->add_to_includepath();
507
508        ### this buffer will not include what tests failed due to a
509        ### M::B/Test::Harness bug. Reported as #9793 with patch
510        ### against 0.2607 on 26/1/2005
511        unless( $skiptest ) {
512            my $test_output;
513            if ( ON_VMS ) {
514                $cmd     = [$perl, BUILD->($dir), "test", @buildflags];
515            }
516            else {
517                $cmd     = [$perl, @run_perl, BUILD->($dir), "test", @buildflags];
518            }
519            local $ENV{PERL_INSTALL_QUIET};
520            unless ( scalar run(    command => $cmd,
521                                    buffer  => \$test_output,
522                                    verbose => $verbose )
523            ) {
524                error( loc( "MAKE TEST failed:\n%1 ", $test_output ), ( $verbose ? 0 : 1 ) );
525
526                ### mark specifically *test* failure.. so we don't
527                ### send success on force...
528                $test_fail++;
529
530                if( !$force and !$cb->_callbacks->proceed_on_test_failure->(
531                                      $self, $@ )
532                ) {
533                    $dist->status->test(0);
534                    if ( $conf->get_conf('cpantest') ) {
535                      $status->{stage} = 'test';
536                      $status->{capture} = $test_output;
537                    }
538                    $fail++; last RUN;
539                }
540
541            }
542            else {
543                msg( loc( "MAKE TEST passed:\n%1", $test_output ), 0 );
544                $dist->status->test(1);
545                if ( $conf->get_conf('cpantest') ) {
546                   $status->{stage} = 'test';
547                   $status->{capture} = $test_output;
548                }
549            }
550        }
551        else {
552            msg(loc("Tests skipped"), $verbose);
553        }
554    }
555
556    unless( $cb->_chdir( dir => $orig ) ) {
557        error( loc( "Could not chdir back to start dir '%1'", $orig ) );
558    }
559
560    ### send out test report? ###
561    if( $conf->get_conf('cpantest') and not $prereq_fail ) {
562        $cb->_send_report(
563            module          => $self,
564            failed          => $test_fail || $fail,
565            buffer          => CPANPLUS::Error->stack_as_string,
566            status          => $status,
567            verbose         => $verbose,
568            force           => $force,
569            tests_skipped   => $skiptest,
570        ) or error(loc("Failed to send test report for '%1'",
571                    $self->module ) );
572    }
573
574    return $dist->status->created( $fail ? 0 : 1 );
575}
576
577
578sub install {
579    ### just in case you already did a create call for this module object
580    ### just via a different dist object
581    my $dist = shift;
582    my $self = $dist->parent;
583
584    ### we're also the cpan_dist, since we don't need to have anything
585    ### prepared from another installer
586    $dist    = $self->status->dist_cpan if $self->status->dist_cpan;
587
588    my $cb   = $self->parent;
589    my $conf = $cb->configure_object;
590    my %hash = @_;
591
592
593    my $verbose; my $perl; my $force; my $buildflags;
594    {   local $Params::Check::ALLOW_UNKNOWN = 1;
595        my $tmpl = {
596            verbose => { default => $conf->get_conf('verbose'),
597                         store   => \$verbose },
598            force   => { default => $conf->get_conf('force'),
599                         store   => \$force },
600            buildflags => { default => $conf->get_conf('buildflags'),
601                            store   => \$buildflags },
602            perl    => { default => $^X, store   => \$perl },
603        };
604
605        my $args = check( $tmpl, \%hash ) or return;
606        $dist->status->_install_args( $args );
607    }
608
609    my $dir;
610    unless( $dir = $self->status->extract ) {
611        error( loc( "No dir found to operate on!" ) );
612        return;
613    }
614
615    my $orig = cwd();
616
617    unless( $cb->_chdir( dir => $dir ) ) {
618        error( loc( "Could not chdir to build directory '%1'", $dir ) );
619        return;
620    }
621
622    ### value set and false -- means failure ###
623    if( defined $self->status->installed &&
624        !$self->status->installed && !$force
625    ) {
626        error( loc( "Module '%1' has failed to install before this session " .
627                    "-- aborting install", $self->module ) );
628        return;
629    }
630
631    my $fail;
632    my @buildflags = $dist->_buildflags_as_list( $buildflags );
633    my @run_perl    = $dist->_perlrun();
634
635    my $metadata = $dist->status->_metadata;
636    my $x_use_unsafe_inc = ( defined $metadata && exists $metadata->{x_use_unsafe_inc} ? $metadata->{x_use_unsafe_inc} : undef );
637    $x_use_unsafe_inc = 1 unless defined $x_use_unsafe_inc;
638
639    local $ENV{PERL_USE_UNSAFE_INC} = $x_use_unsafe_inc
640      unless exists $ENV{PERL_USE_UNSAFE_INC};
641
642    ### hmm, how is this going to deal with sudo?
643    ### for now, check effective uid, if it's not root,
644    ### shell out, otherwise use the method
645    if( $> ) {
646
647        ### don't worry about loading the right version of M::B anymore
648        ### the 'new_from_context' already added the 'right' path to
649        ### M::B at the top of the build.pl
650        my $cmd;
651        if ( ON_VMS ) {
652            $cmd     = [$perl, BUILD->($dir), "install", @buildflags];
653        }
654        else {
655            $cmd     = [$perl, @run_perl, BUILD->($dir), "install", @buildflags];
656        }
657
658        ### Detect local::lib type behaviour. Do not use 'sudo' in these cases
659        my $sudo    = $conf->get_program('sudo');
660        SUDO: {
661          ### Actual local::lib in use
662          last SUDO if defined $ENV{PERL_MB_OPT} and $ENV{PERL_MB_OPT} =~ m!install_base!;
663          ### 'buildflags' is configured with '--install_base'
664          last SUDO if scalar grep { m!install_base! } @buildflags;
665          ### oh well 'sudo make me a sandwich'
666          unshift @$cmd, $sudo;
667        }
668
669        my $buffer;
670        unless( scalar run( command => $cmd,
671                            buffer  => \$buffer,
672                            verbose => $verbose )
673        ) {
674            error(loc("Could not run '%1': %2", 'Build install', $buffer));
675            $fail++;
676        }
677    } else {
678        my ($install_output, $cmd);
679        if ( ON_VMS ) {
680            $cmd     = [$perl, BUILD->($dir), "install", @buildflags];
681        }
682        else {
683            $cmd     = [$perl, @run_perl, BUILD->($dir), "install", @buildflags];
684        }
685        unless( scalar run( command => $cmd,
686                            buffer  => \$install_output,
687                            verbose => $verbose )
688        ) {
689            error(loc("Could not run '%1': %2", 'Build install', $install_output));
690            $fail++;
691        }
692        else {
693            msg( $install_output, 0 );
694        }
695    }
696
697
698    unless( $cb->_chdir( dir => $orig ) ) {
699        error( loc( "Could not chdir back to start dir '%1'", $orig ) );
700    }
701
702    return $dist->status->installed( $fail ? 0 : 1 );
703}
704
705### returns the string 'foo=bar --zot quux'
706###        as the list 'foo=bar', '--zot', 'qux'
707sub _buildflags_as_list {
708    my $self    = shift;
709    my $flags   = shift or return;
710
711    return Module::Build->split_like_shell($flags);
712}
713
714{
715   my $afe_ver = version->new($CPANPLUS::Internals::VERSION) >= version->new("0.9166");
716
717   sub _perlrun {
718      my $self    = shift;
719      if ( $afe_ver ) {
720        return ( '-MCPANPLUS::Internals::Utils::Autoflush' );
721      }
722      else {
723        return ( '-e', CPDB_PERL_WRAPPER );
724      }
725   }
726}
727
728
729qq[Putting the Module::Build into CPANPLUS];
730
731
732# Local variables:
733# c-indentation-style: bsd
734# c-basic-offset: 4
735# indent-tabs-mode: nil
736# End:
737# vim: expandtab shiftwidth=4:
738
739__END__
740
741=pod
742
743=encoding UTF-8
744
745=head1 NAME
746
747CPANPLUS::Dist::Build - CPANPLUS plugin to install packages that use Build.PL
748
749=head1 VERSION
750
751version 0.90
752
753=head1 SYNOPSIS
754
755    my $build = CPANPLUS::Dist->new(
756                                format  => 'CPANPLUS::Dist::Build',
757                                module  => $modobj,
758                            );
759
760    $build->prepare;    # runs Build.PL
761    $build->create;     # runs build && build test
762    $build->install;    # runs build install
763
764=head1 DESCRIPTION
765
766C<CPANPLUS::Dist::Build> is a distribution class for C<Module::Build>
767related modules.
768Using this package, you can create, install and uninstall perl
769modules. It inherits from C<CPANPLUS::Dist>.
770
771Normal users won't have to worry about the interface to this module,
772as it functions transparently as a plug-in to C<CPANPLUS> and will
773just C<Do The Right Thing> when it's loaded.
774
775=head1 ACCESSORS
776
777=over 4
778
779=item C<parent()>
780
781Returns the C<CPANPLUS::Module> object that parented this object.
782
783=item C<status()>
784
785Returns the C<Object::Accessor> object that keeps the status for
786this module.
787
788=back
789
790=head1 STATUS ACCESSORS
791
792All accessors can be accessed as follows:
793    $build->status->ACCESSOR
794
795=over 4
796
797=item C<build_pl ()>
798
799Location of the Build file.
800Set to 0 explicitly if something went wrong.
801
802=item C<build ()>
803
804BOOL indicating if the C<Build> command was successful.
805
806=item C<test ()>
807
808BOOL indicating if the C<Build test> command was successful.
809
810=item C<prepared ()>
811
812BOOL indicating if the C<prepare> call exited successfully
813This gets set after C<perl Build.PL>
814
815=item C<distdir ()>
816
817Full path to the directory in which the C<prepare> call took place,
818set after a call to C<prepare>.
819
820=item C<created ()>
821
822BOOL indicating if the C<create> call exited successfully. This gets
823set after C<Build> and C<Build test>.
824
825=item C<installed ()>
826
827BOOL indicating if the module was installed. This gets set after
828C<Build install> exits successfully.
829
830=item uninstalled ()
831
832BOOL indicating if the module was uninstalled properly.
833
834=item C<_create_args ()>
835
836Storage of the arguments passed to C<create> for this object. Used
837for recursive calls when satisfying prerequisites.
838
839=item C<_install_args ()>
840
841Storage of the arguments passed to C<install> for this object. Used
842for recursive calls when satisfying prerequisites.
843
844=back
845
846=head1 METHODS
847
848=head2 $bool = CPANPLUS::Dist::Build->format_available();
849
850Returns a boolean indicating whether or not you can use this package
851to create and install modules in your environment.
852
853=head2 $bool = $dist->init();
854
855Sets up the C<CPANPLUS::Dist::Build> object for use.
856Effectively creates all the needed status accessors.
857
858Called automatically whenever you create a new C<CPANPLUS::Dist> object.
859
860=head2 $bool = $dist->prepare([perl => '/path/to/perl', buildflags => 'EXTRA=FLAGS', force => BOOL, verbose => BOOL])
861
862C<prepare> prepares a distribution, running C<Build.PL>
863and establishing any prerequisites this
864distribution has.
865
866The variable C<PERL5_CPANPLUS_IS_EXECUTING> will be set to the full path
867of the C<Build.PL> that is being executed. This enables any code inside
868the C<Build.PL> to know that it is being installed via CPANPLUS.
869
870After a successful C<prepare> you may call C<create> to create the
871distribution, followed by C<install> to actually install it.
872
873Returns true on success and false on failure.
874
875=head2 $dist->create([perl => '/path/to/perl', buildflags => 'EXTRA=FLAGS', prereq_target => TARGET, force => BOOL, verbose => BOOL, skiptest => BOOL])
876
877C<create> preps a distribution for installation. This means it will
878run C<Build> and C<Build test>.
879This will also satisfy any prerequisites the module may have.
880
881If you set C<skiptest> to true, it will skip the C<Build test> stage.
882If you set C<force> to true, it will go over all the stages of the
883C<Build> process again, ignoring any previously cached results. It
884will also ignore a bad return value from C<Build test> and still allow
885the operation to return true.
886
887Returns true on success and false on failure.
888
889You may then call C<< $dist->install >> on the object to actually
890install it.
891
892=head2 $dist->install([verbose => BOOL, perl => /path/to/perl])
893
894Actually installs the created dist.
895
896Returns true on success and false on failure.
897
898=head1 PROMINENCE
899
900Originally by Jos Boumans E<lt>kane@cpan.orgE<gt>.  Brought to working
901condition by Ken Williams E<lt>kwilliams@cpan.orgE<gt>.
902
903Other hackery and currently maintained by Chris C<BinGOs> Williams ( no relation ). E<lt>bingos@cpan.orgE<gt>.
904
905=head1 AUTHOR
906
907Jos Boumans <kane[at]cpan.org>, Ken Williams <kwilliams@cpan.org>
908
909=head1 COPYRIGHT AND LICENSE
910
911This software is copyright (c) 2018 by Jos Boumans, Ken Williams, Chris Williams and David Golden.
912
913This is free software; you can redistribute it and/or modify it under
914the same terms as the Perl 5 programming language system itself.
915
916=cut
917