CPAN::FindDependencies::MakeMaker - retrieve dependencies specified in Makefile.PL's


CPAN-FindDependencies documentation Contained in the CPAN-FindDependencies distribution.

Index


Code Index:

NAME

Top

CPAN::FindDependencies::MakeMaker - retrieve dependencies specified in Makefile.PL's

SYNOPSIS

Top

Dependencies are also specified in Makefile.PL files used with the ExtUtils::MakeMaker module.

FUNCTIONS

Top

getreqs_from_mm

Expects the contents of a Makefile.PL as a string.

Returns a hash reference of the form:

    {
        Module::Name => 0.1,
        ...
        Last::Module => 9.0,
    }

SECURITY

Top

This module assumes that its input is trustworthy and can be safely executed. The only protection in place is that a vague attempt is made to catch a Makefile.PL that just sits there doing nothing - either if it's in a loop, or sitting at a prompt. But even that can be defeated by an especially naughty person.

BUGS/LIMITATIONS

Top

Makefile.PLs that have external dependencies/calls that can fatally die will not be able to be successfully parsed and then scanned for dependencies, e.g. libwww-perl.5808.

SOURCE CODE REPOSITORY

Top

http://www.cantrell.org.uk/cgit/cgit.cgi/perlmodules/

SEE ALSO

Top

CPAN::FindDepdendencies

CPAN

http://deps.cpantesters.org

AUTHOR, LICENCE and COPYRIGHT

Top

CONSPIRACY

Top

This module is also free-as-in-mason software.


CPAN-FindDependencies documentation Contained in the CPAN-FindDependencies distribution.
#!perl -w
# TODO    Figure out how to recover from fatal errors inside the 'eval $MakefilePL' call.

package CPAN::FindDependencies::MakeMaker;

use strict;
use vars qw($VERSION @ISA @EXPORT_OK);

use File::Temp qw(tempdir);
use Cwd qw(getcwd abs_path);
use Capture::Tiny qw(capture);
use Config;

require Exporter;
@ISA = qw(Exporter);
@EXPORT_OK = qw( getreqs_from_mm );

$VERSION = '0.3';

sub getreqs_from_mm {
    my $MakefilePL = shift;
    local $/ = undef;

    my $cwd = getcwd();
    my $tempdir = tempdir(CLEANUP => 1);
    chdir($tempdir);

    # write Makefile.PL ...
    open(my $MKFH, '>Makefile.PL') || die("Can't write Makefile.PL in $tempdir\n");
    print $MKFH $MakefilePL;
    close($MKFH);

    # execute, suppressing noise ...
    eval { capture {
        if(my $pid = fork()) { # parent
            local $SIG{ALRM} = sub {
                kill 9, $pid; # quit RIGHT FUCKING NOW
                die("Makefile.PL didn't finish in a reasonable time\n");
            };
            alarm(5);
            waitpid($pid, 0);
            alarm(0);
        } else {
            exec($Config{perlpath}, 'Makefile.PL');
        }
    } };
    if($@) {
        chdir($cwd);
	return $@;
    }

    # read Makefile
    open($MKFH, 'Makefile') || warn "Can't read Makefile\n";
    my $makefile_str = <$MKFH>;
    close($MKFH);
    chdir($cwd);

    return _parse_makefile( $makefile_str );
}

sub _parse_makefile {
    my $makefile_str = shift;
    return "Unable to get Makefile" unless defined $makefile_str;
    my %required_version_for;
    my @prereq_lines = grep { /^\s*#.*PREREQ/ } split /\n/, $makefile_str;
    for my $line ( @prereq_lines ) {
        if ( $line =~ /PREREQ_PM \s+ => \s+ \{ \s* (.*) \s* \} $/x ) {
            no strict 'subs';
            %required_version_for = eval "( $1 )";
            return "Failed to eval $1: $@" if $@;
            use strict 'subs';
        } else {
            return "Unrecognized PREREQ line in Makefile.PL:\n$line";
        }
    }
    return \%required_version_for;
}

1;