CPANPLUS

 view release on metacpan or  search on metacpan

lib/CPANPLUS/Dist/MM.pm  view on Meta::CPAN

        ### start resolving prereqs ###
        my $prereqs = $self->status->prereqs;

        ### a hashref of prereqs on success, undef on failure ###
        $prereqs    ||= $dist->_find_prereqs(
                                    verbose => $verbose,
                                    file    => $dist->status->makefile
                                );

        unless( $prereqs ) {
            error( loc( "Unable to scan '%1' for prereqs",
                        $dist->status->makefile ) );

            $fail++; last RUN;
        }
    }

	unless( $cb->_chdir( dir => $orig ) ) {
        error( loc( "Could not chdir back to start dir '%1'", $orig ) );
    }

    ### save where we wrote this stuff -- same as extract dir in normal
    ### installer circumstances
    $dist->status->distdir( $self->status->extract );

    return $dist->status->prepared( $fail ? 0 : 1);
}

=pod

=head2 $href = $dist->_find_prereqs( file => '/path/to/Makefile', [verbose => BOOL])

Parses a C<Makefile> for C<PREREQ_PM> entries and distills from that
any prerequisites mentioned in the C<Makefile>

Returns a hash with module-version pairs on success and false on
failure.

=cut

sub _find_prereqs {
    my $dist = shift;
    my $self = $dist->parent;
    my $cb   = $self->parent;
    my $conf = $cb->configure_object;
    my %hash = @_;

    my ($verbose, $file);
    my $tmpl = {
        verbose => { default => $conf->get_conf('verbose'), store => \$verbose },
        file    => { required => 1, allow => FILE_READABLE, store => \$file },
    };

    my $args = check( $tmpl, \%hash ) or return;

    ### see if we got prereqs from MYMETA
    my $prereqs = $dist->find_mymeta_requires();

    ### we found some prereqs, we'll trust MYMETA
    ### but we do need to run it through the callback
    return $cb->_callbacks->filter_prereqs->( $cb, $prereqs ) if keys %$prereqs;

    my $fh = FileHandle->new();
    unless( $fh->open( $file ) ) {
        error( loc( "Cannot open '%1': %2", $file, $! ) );
        return;
    }

    my %p;
    while( local $_ = <$fh> ) {
        my ($found) = m|^[\#]\s+PREREQ_PM\s+=>\s+(.+)|;

        next unless $found;

        while( $found =~ m/(?:\s)([\w\:]+)=>(?:q\[(.*?)\],?|undef)/g ) {
            if( defined $p{$1} ) {
                my $ver = $cb->_version_to_number(version => $2);
                $p{$1} = $ver
                  if $cb->_vcmp( $ver, $p{$1} ) > 0;
            }
            else {
                $p{$1} = $cb->_version_to_number(version => $2);
            }
        }
        last;
    }

    my $href = $cb->_callbacks->filter_prereqs->( $cb, \%p );

    $self->status->prereqs( $href );

    ### just to make sure it's not the same reference ###
    return { %$href };
}

=pod

=head2 $bool = $dist->create([perl => '/path/to/perl', make => '/path/to/make', makeflags => 'EXTRA=FLAGS', prereq_target => TARGET, skiptest => BOOL, force => BOOL, verbose => BOOL])

C<create> creates the files necessary for installation. This means
it will run C<make> and C<make test>.  This will also scan for and
attempt to satisfy any prerequisites the module may have.

If you set C<skiptest> to true, it will skip the C<make test> stage.
If you set C<force> to true, it will go over all the stages of the
C<make> process again, ignoring any previously cached results. It
will also ignore a bad return value from C<make test> and still allow
the operation to return true.

Returns true on success and false on failure.

You may then call C<< $dist->install >> on the object to actually
install it.

=cut

sub create {
    ### 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
    $dist    = $self->status->dist_cpan if      $self->status->dist_cpan;
    $self->status->dist_cpan( $dist )   unless  $self->status->dist_cpan;

    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;
    }

    my $args;
    my( $force, $verbose, $make, $makeflags, $skiptest, $prereq_target, $perl,
        @mmflags, $prereq_format, $prereq_build);
    {   local $Params::Check::ALLOW_UNKNOWN = 1;
        my $tmpl = {
            perl            => {    default => $^X, store => \$perl },
            force           => {    default => $conf->get_conf('force'),
                                    store   => \$force },
            verbose         => {    default => $conf->get_conf('verbose'),
                                    store   => \$verbose },
            make            => {    default => $conf->get_program('make'),

lib/CPANPLUS/Dist/MM.pm  view on Meta::CPAN

            #last RUN if $skiptest;
        }

        ### 'make test' section ###
        unless( $skiptest ) {

            ### turn off our PERL5OPT so no modules from CPANPLUS::inc get
            ### included in make test -- it should build without
            ### also, modules that run in taint mode break if we leave
            ### our code ref in perl5opt
            ### XXX CPANPLUS::inc functionality is now obsolete.
            #local $ENV{PERL5OPT} = CPANPLUS::inc->original_perl5opt || '';

            ### you can turn off running this verbose by changing
            ### the config setting below, although it is really not
            ### recommended
            my $run_verbose =
                        $verbose ||
                        $conf->get_conf('allow_build_interactivity') ||
                        0;

            ### XXX need to add makeflags here too?
            ### yes, but they should really be split out -- see bug #4143
            local $ENV{PERL_INSTALL_QUIET}; # shield tests from ExtUtils::Install
            if( scalar run(
                        command => [$make, 'test', @makeflags],
                        buffer  => \$captured,
                        verbose => $run_verbose,
            ) ) {
                ### tests might pass because it doesn't have any tests defined
                ### log this occasion non-verbosely, so our test reporter can
                ### pick up on this
                if ( NO_TESTS_DEFINED->( $captured ) ) {
                    msg( NO_TESTS_DEFINED->( $captured ), 0 )
                } else {
                    msg( loc( "MAKE TEST passed: %1", $captured ), 0 );
                }

                if ( $conf->get_conf('cpantest') ) {
                  $status->{stage} = 'test';
                  $status->{capture} = $captured;
                }

                $dist->status->test(1);
            } else {
                error( loc( "MAKE TEST failed: %1", $captured ), ( $run_verbose ? 0 : 1 ) );

                if ( $conf->get_conf('cpantest') ) {
                  $status->{stage} = 'test';
                  $status->{capture} = $captured;
                }

                ### send out error report here? or do so at a higher level?
                ### --higher level --kane.
                $dist->status->test(0);

                ### mark specifically *test* failure.. so we don't
                ### send success on force...
                $test_fail++;

                if( !$force and !$cb->_callbacks->proceed_on_test_failure->(
                                      $self, $captured )
                ) {
                    $fail++; last RUN;
                }
            }
        }
    } #</RUN>

    unless( $cb->_chdir( dir => $orig ) ) {
        error( loc( "Could not chdir back to start dir '%1'", $orig ) );
    }

    ### TODO: Add $stage to _send_report()
    ### send out test report?
    ### only do so if the failure is this module, not its prereq
    if( $conf->get_conf('cpantest') and not $prereq_fail) {
        $cb->_send_report(
            module  => $self,
            failed  => $test_fail || $fail,
            buffer  => CPANPLUS::Error->stack_as_string,
            status  => $status,
            verbose => $verbose,
            force   => $force,
        ) or error(loc("Failed to send test report for '%1'",
                    $self->module ) );
    }

    return $dist->status->created( $fail ? 0 : 1);
}

=pod

=head2 $bool = $dist->install([make => '/path/to/make',  makemakerflags => 'EXTRA=FLAGS', force => BOOL, verbose => BOOL])

C<install> runs the following command:
    make install

Returns true on success, false on failure.

=cut

sub install {

    ### just in case you did the create with ANOTHER dist object linked
    ### to the same module object
    my $dist = shift();
    my $self = $dist->parent;
    $dist    = $self->status->dist_cpan if $self->status->dist_cpan;

    my $cb   = $self->parent;
    my $conf = $cb->configure_object;
    my %hash = @_;


    unless( $dist->status->created ) {
        error(loc("You have not successfully created a '%2' distribution yet " .
                  "-- cannot install yet", __PACKAGE__ ));
        return;
    }



( run in 0.486 second using v1.01-cache-2.11-cpan-39bf76dae61 )