Alien-ROOT
view release on metacpan or search on metacpan
inc/inc_Module-Build/Module/Build/Base.pm view on Meta::CPAN
}
die ("Can't determine distribution version, must supply either 'dist_version',\n".
"'dist_version_from', or 'module_name' parameter")
unless defined $p->{dist_version};
return $p->{dist_version};
}
sub _is_dev_version {
my ($self) = @_;
my $dist_version = $self->dist_version;
my $version_obj = eval { Module::Build::Version->new( $dist_version ) };
# assume it's normal if the version string is fatal -- in this case
# the author might be doing something weird so should play along and
# assume they'll specify all necessary behavior
return $@ ? 0 : $version_obj->is_alpha;
}
sub dist_author { shift->_pod_parse('author') }
sub dist_abstract { shift->_pod_parse('abstract') }
sub _pod_parse {
my ($self, $part) = @_;
my $p = $self->{properties};
my $member = "dist_$part";
return $p->{$member} if defined $p->{$member};
my $docfile = $self->_main_docfile
or return;
my $fh = IO::File->new($docfile)
or return;
require Module::Build::PodParser;
my $parser = Module::Build::PodParser->new(fh => $fh);
my $method = "get_$part";
return $p->{$member} = $parser->$method();
}
sub version_from_file { # Method provided for backwards compatibility
return Module::Build::ModuleInfo->new_from_file($_[1])->version();
}
sub find_module_by_name { # Method provided for backwards compatibility
return Module::Build::ModuleInfo->find_module_by_name(@_[1,2]);
}
{
# $unlink_list_for_pid{$$} = [ ... ]
my %unlink_list_for_pid;
sub _unlink_on_exit {
my $self = shift;
for my $f ( @_ ) {
push @{$unlink_list_for_pid{$$}}, $f if -f $f;
}
return 1;
}
END {
for my $f ( map glob($_), @{ $unlink_list_for_pid{$$} || [] } ) {
next unless -e $f;
File::Path::rmtree($f, 0, 0);
}
}
}
sub add_to_cleanup {
my $self = shift;
my %files = map {$self->localize_file_path($_), 1} @_;
$self->{phash}{cleanup}->write(\%files);
}
sub cleanup {
my $self = shift;
my $all = $self->{phash}{cleanup}->read;
return keys %$all;
}
sub config_file {
my $self = shift;
return unless -d $self->config_dir;
return File::Spec->catfile($self->config_dir, @_);
}
sub read_config {
my ($self) = @_;
my $file = $self->config_file('build_params')
or die "Can't find 'build_params' in " . $self->config_dir;
my $fh = IO::File->new($file) or die "Can't read '$file': $!";
my $ref = eval do {local $/; <$fh>};
die if $@;
my $c;
($self->{args}, $c, $self->{properties}) = @$ref;
$self->{config} = Module::Build::Config->new(values => $c);
close $fh;
}
sub has_config_data {
my $self = shift;
return scalar grep $self->{phash}{$_}->has_data(), qw(config_data features auto_features);
}
sub _write_data {
my ($self, $filename, $data) = @_;
my $file = $self->config_file($filename);
my $fh = IO::File->new("> $file") or die "Can't create '$file': $!";
unless (ref($data)) { # e.g. magicnum
print $fh $data;
return;
}
print {$fh} Module::Build::Dumper->_data_dump($data);
}
sub write_config {
my ($self) = @_;
File::Path::mkpath($self->{properties}{config_dir});
inc/inc_Module-Build/Module/Build/Base.pm view on Meta::CPAN
%args = (%args, Module::Build::Compat->makefile_to_build_macros);
}
return \%args, $action;
}
# Default: do nothing. Overridden for Unix & Windows.
sub _detildefy {}
# merge Module::Build argument lists that have already been parsed
# by read_args(). Takes two references to option hashes and merges
# the contents, giving priority to the first.
sub _merge_arglist {
my( $self, $opts1, $opts2 ) = @_;
$opts1 ||= {};
$opts2 ||= {};
my %new_opts = %$opts1;
while (my ($key, $val) = each %$opts2) {
if ( exists( $opts1->{$key} ) ) {
if ( ref( $val ) eq 'HASH' ) {
while (my ($k, $v) = each %$val) {
$new_opts{$key}{$k} = $v unless exists( $opts1->{$key}{$k} );
}
}
} else {
$new_opts{$key} = $val
}
}
return %new_opts;
}
# Look for a home directory on various systems.
sub _home_dir {
my @home_dirs;
push( @home_dirs, $ENV{HOME} ) if $ENV{HOME};
push( @home_dirs, File::Spec->catpath($ENV{HOMEDRIVE}, $ENV{HOMEPATH}, '') )
if $ENV{HOMEDRIVE} && $ENV{HOMEPATH};
my @other_home_envs = qw( USERPROFILE APPDATA WINDIR SYS$LOGIN );
push( @home_dirs, map $ENV{$_}, grep $ENV{$_}, @other_home_envs );
my @real_home_dirs = grep -d, @home_dirs;
return wantarray ? @real_home_dirs : shift( @real_home_dirs );
}
sub _find_user_config {
my $self = shift;
my $file = shift;
foreach my $dir ( $self->_home_dir ) {
my $path = File::Spec->catfile( $dir, $file );
return $path if -e $path;
}
return undef;
}
# read ~/.modulebuildrc returning global options '*' and
# options specific to the currently executing $action.
sub read_modulebuildrc {
my( $self, $action ) = @_;
return () unless $self->use_rcfile;
my $modulebuildrc;
if ( exists($ENV{MODULEBUILDRC}) && $ENV{MODULEBUILDRC} eq 'NONE' ) {
return ();
} elsif ( exists($ENV{MODULEBUILDRC}) && -e $ENV{MODULEBUILDRC} ) {
$modulebuildrc = $ENV{MODULEBUILDRC};
} elsif ( exists($ENV{MODULEBUILDRC}) ) {
$self->log_warn("WARNING: Can't find resource file " .
"'$ENV{MODULEBUILDRC}' defined in environment.\n" .
"No options loaded\n");
return ();
} else {
$modulebuildrc = $self->_find_user_config( '.modulebuildrc' );
return () unless $modulebuildrc;
}
my $fh = IO::File->new( $modulebuildrc )
or die "Can't open $modulebuildrc: $!";
my %options; my $buffer = '';
while (defined( my $line = <$fh> )) {
chomp( $line );
$line =~ s/#.*$//;
next unless length( $line );
if ( $line =~ /^\S/ ) {
if ( $buffer ) {
my( $action, $options ) = split( /\s+/, $buffer, 2 );
$options{$action} .= $options . ' ';
$buffer = '';
}
$buffer = $line;
} else {
$buffer .= $line;
}
}
if ( $buffer ) { # anything left in $buffer ?
my( $action, $options ) = split( /\s+/, $buffer, 2 );
$options{$action} .= $options . ' '; # merge if more than one line
}
my ($global_opts) =
$self->read_args( $self->split_like_shell( $options{'*'} || '' ) );
# let fakeinstall act like install if not provided
if ( $action eq 'fakeinstall' && ! exists $options{fakeinstall} ) {
$action = 'install';
}
my ($action_opts) =
$self->read_args( $self->split_like_shell( $options{$action} || '' ) );
# specific $action options take priority over global options '*'
return $self->_merge_arglist( $action_opts, $global_opts );
}
# merge the relevant options in ~/.modulebuildrc into Module::Build's
# option list where they do not conflict with commandline options.
sub merge_modulebuildrc {
my( $self, $action, %cmdline_opts ) = @_;
my %rc_opts = $self->read_modulebuildrc( $action || $self->{action} || 'build' );
my %new_opts = $self->_merge_arglist( \%cmdline_opts, \%rc_opts );
$self->merge_args( $action, %new_opts );
}
sub merge_args {
my ($self, $action, %args) = @_;
$self->{action} = $action if defined $action;
my %additive = map { $_ => 1 } $self->hash_properties;
# Extract our 'properties' from $cmd_args, the rest are put in 'args'.
while (my ($key, $val) = each %args) {
$self->{phash}{runtime_params}->access( $key => $val )
if $self->valid_property($key);
if ($key eq 'config') {
$self->config($_ => $val->{$_}) foreach keys %$val;
} else {
my $add_to = $additive{$key} ? $self->{properties}{$key} :
$self->valid_property($key) ? $self->{properties} :
$self->{args} ;
if ($additive{$key}) {
$add_to->{$_} = $val->{$_} foreach keys %$val;
} else {
$add_to->{$key} = $val;
}
}
}
}
sub cull_args {
my $self = shift;
my @arg_list = @_;
unshift @arg_list, $self->split_like_shell($ENV{PERL_MB_OPT})
if $ENV{PERL_MB_OPT};
my ($args, $action) = $self->read_args(@arg_list);
$self->merge_args($action, %$args);
$self->merge_modulebuildrc( $action, %$args );
}
sub super_classes {
my ($self, $class, $seen) = @_;
$class ||= ref($self) || $self;
$seen ||= {};
no strict 'refs';
my @super = grep {not $seen->{$_}++} $class, @{ $class . '::ISA' };
return @super, map {$self->super_classes($_,$seen)} @super;
}
sub known_actions {
my ($self) = @_;
inc/inc_Module-Build/Module/Build/Base.pm view on Meta::CPAN
})->runtests(@$tests);
return $aggregate;
}
sub run_test_harness {
my ($self, $tests) = @_;
require Test::Harness;
my $p = $self->{properties};
my @harness_switches = $self->harness_switches;
# Work around a Test::Harness bug that loses the particular perl
# we're running under. $self->perl is trustworthy, but $^X isn't.
local $^X = $self->perl;
# Do everything in our power to work with all versions of Test::Harness
local $Test::Harness::switches = join ' ', grep defined, $Test::Harness::switches, @harness_switches;
local $Test::Harness::Switches = join ' ', grep defined, $Test::Harness::Switches, @harness_switches;
local $ENV{HARNESS_PERL_SWITCHES} = join ' ', grep defined, $ENV{HARNESS_PERL_SWITCHES}, @harness_switches;
$Test::Harness::switches = undef unless length $Test::Harness::switches;
$Test::Harness::Switches = undef unless length $Test::Harness::Switches;
delete $ENV{HARNESS_PERL_SWITCHES} unless length $ENV{HARNESS_PERL_SWITCHES};
local ($Test::Harness::verbose,
$Test::Harness::Verbose,
$ENV{TEST_VERBOSE},
$ENV{HARNESS_VERBOSE}) = ($p->{verbose} || 0) x 4;
Test::Harness::runtests(@$tests);
}
sub run_visual_script {
my $self = shift;
# This will get run and the user will see the output. It doesn't
# emit Test::Harness-style output.
$self->run_perl_script('visual.pl', '-Mblib='.$self->blib)
if -e 'visual.pl';
}
sub harness_switches {
shift->{properties}{debugger} ? qw(-w -d) : ();
}
sub test_files {
my $self = shift;
my $p = $self->{properties};
if (@_) {
return $p->{test_files} = (@_ == 1 ? shift : [@_]);
}
return $self->find_test_files;
}
sub expand_test_dir {
my ($self, $dir) = @_;
my $exts = $self->{properties}{test_file_exts};
return sort map { @{$self->rscan_dir($dir, qr{^[^.].*\Q$_\E$})} } @$exts
if $self->recursive_test_files;
return sort map { glob File::Spec->catfile($dir, "*$_") } @$exts;
}
sub ACTION_testdb {
my ($self) = @_;
local $self->{properties}{debugger} = 1;
$self->depends_on('test');
}
sub ACTION_testcover {
my ($self) = @_;
unless (Module::Build::ModuleInfo->find_module_by_name('Devel::Cover')) {
warn("Cannot run testcover action unless Devel::Cover is installed.\n");
return;
}
$self->add_to_cleanup('coverage', 'cover_db');
$self->depends_on('code');
# See whether any of the *.pm files have changed since last time
# testcover was run. If so, start over.
if (-e 'cover_db') {
my $pm_files = $self->rscan_dir
(File::Spec->catdir($self->blib, 'lib'), $self->file_qr('\.pm$') );
my $cover_files = $self->rscan_dir('cover_db', sub {-f $_ and not /\.html$/});
$self->do_system(qw(cover -delete))
unless $self->up_to_date($pm_files, $cover_files)
&& $self->up_to_date($self->test_files, $cover_files);
}
local $Test::Harness::switches =
local $Test::Harness::Switches =
local $ENV{HARNESS_PERL_SWITCHES} = "-MDevel::Cover";
$self->depends_on('test');
$self->do_system('cover');
}
sub ACTION_code {
my ($self) = @_;
# All installable stuff gets created in blib/ .
# Create blib/arch to keep blib.pm happy
my $blib = $self->blib;
$self->add_to_cleanup($blib);
File::Path::mkpath( File::Spec->catdir($blib, 'arch') );
if (my $split = $self->autosplit) {
$self->autosplit_file($_, $blib) for ref($split) ? @$split : ($split);
}
foreach my $element (@{$self->build_elements}) {
my $method = "process_${element}_files";
$method = "process_files_by_extension" unless $self->can($method);
$self->$method($element);
}
$self->depends_on('config_data');
}
inc/inc_Module-Build/Module/Build/Base.pm view on Meta::CPAN
foreach my $file (keys %$files) {
my $result = $self->copy_if_modified($file, $script_dir, 'flatten') or next;
$self->fix_shebang_line($result) unless $self->is_vmsish;
$self->make_executable($result);
}
}
sub find_PL_files {
my $self = shift;
if (my $files = $self->{properties}{PL_files}) {
# 'PL_files' is given as a Unix file spec, so we localize_file_path().
if (UNIVERSAL::isa($files, 'ARRAY')) {
return { map {$_, [/^(.*)\.PL$/]}
map $self->localize_file_path($_),
@$files };
} elsif (UNIVERSAL::isa($files, 'HASH')) {
my %out;
while (my ($file, $to) = each %$files) {
$out{ $self->localize_file_path($file) } = [ map $self->localize_file_path($_),
ref $to ? @$to : ($to) ];
}
return \%out;
} else {
die "'PL_files' must be a hash reference or array reference";
}
}
return unless -d 'lib';
return {
map {$_, [/^(.*)\.PL$/i ]}
@{ $self->rscan_dir('lib', $self->file_qr('\.PL$')) }
};
}
sub find_pm_files { shift->_find_file_by_type('pm', 'lib') }
sub find_pod_files { shift->_find_file_by_type('pod', 'lib') }
sub find_xs_files { shift->_find_file_by_type('xs', 'lib') }
sub find_script_files {
my $self = shift;
if (my $files = $self->script_files) {
# Always given as a Unix file spec. Values in the hash are
# meaningless, but we preserve if present.
return { map {$self->localize_file_path($_), $files->{$_}} keys %$files };
}
# No default location for script files
return {};
}
sub find_test_files {
my $self = shift;
my $p = $self->{properties};
if (my $files = $p->{test_files}) {
$files = [keys %$files] if UNIVERSAL::isa($files, 'HASH');
$files = [map { -d $_ ? $self->expand_test_dir($_) : $_ }
map glob,
$self->split_like_shell($files)];
# Always given as a Unix file spec.
return [ map $self->localize_file_path($_), @$files ];
} else {
# Find all possible tests in t/ or test.pl
my @tests;
push @tests, 'test.pl' if -e 'test.pl';
push @tests, $self->expand_test_dir('t') if -e 't' and -d _;
return \@tests;
}
}
sub _find_file_by_type {
my ($self, $type, $dir) = @_;
if (my $files = $self->{properties}{"${type}_files"}) {
# Always given as a Unix file spec
return { map $self->localize_file_path($_), %$files };
}
return {} unless -d $dir;
return { map {$_, $_}
map $self->localize_file_path($_),
grep !/\.\#/,
@{ $self->rscan_dir($dir, $self->file_qr("\\.$type\$")) } };
}
sub localize_file_path {
my ($self, $path) = @_;
return File::Spec->catfile( split m{/}, $path );
}
sub localize_dir_path {
my ($self, $path) = @_;
return File::Spec->catdir( split m{/}, $path );
}
sub fix_shebang_line { # Adapted from fixin() in ExtUtils::MM_Unix 1.35
my ($self, @files) = @_;
my $c = ref($self) ? $self->{config} : 'Module::Build::Config';
my ($does_shbang) = $c->get('sharpbang') =~ /^\s*\#\!/;
for my $file (@files) {
my $FIXIN = IO::File->new($file) or die "Can't process '$file': $!";
local $/ = "\n";
chomp(my $line = <$FIXIN>);
next unless $line =~ s/^\s*\#!\s*//; # Not a shbang file.
my ($cmd, $arg) = (split(' ', $line, 2), '');
next unless $cmd =~ /perl/i;
my $interpreter = $self->{properties}{perl};
$self->log_verbose("Changing sharpbang in $file to $interpreter\n");
my $shb = '';
$shb .= $c->get('sharpbang')."$interpreter $arg\n" if $does_shbang;
# I'm not smart enough to know the ramifications of changing the
# embedded newlines here to \n, so I leave 'em in.
inc/inc_Module-Build/Module/Build/Base.pm view on Meta::CPAN
# XXX include feature prerequisites as optional prereqs?
my $info = $self->_enum_prereqs;
if (! $info ) {
$self->log_info( "No prerequisites detected\n" );
return;
}
my $failures = $self->prereq_failures($info);
if ( ! $failures ) {
$self->log_info( "All prerequisites satisfied\n" );
return;
}
my @install;
while (my ($type, $prereqs) = each %$failures) {
if($type =~ m/^(?:\w+_)?requires$/) {
push(@install, keys %$prereqs);
next;
}
$self->log_info("Checking optional dependencies:\n");
while (my ($module, $status) = each %$prereqs) {
push(@install, $module) if($self->y_n("Install $module?", 'y'));
}
}
return unless @install;
my ($command, @opts) = $self->split_like_shell($self->cpan_client);
# relative command should be relative to our active Perl
# so we need to locate that command
if ( ! File::Spec->file_name_is_absolute( $command ) ) {
# prefer site to vendor to core
my @loc = ( 'site', 'vendor', '' );
my @bindirs = File::Basename::dirname($self->perl);
push @bindirs,
map {
($self->config->{"install${_}bin"}, $self->config->{"install${_}script"})
} @loc;
for my $d ( @bindirs ) {
my $abs_cmd = $self->find_command(File::Spec->catfile( $d, $command ));
if ( defined $abs_cmd ) {
$command = $abs_cmd;
last;
}
}
}
if ( ! -x $command ) {
die "cpan_client '$command' is not executable\n";
}
$self->do_system($command, @opts, @install);
}
sub ACTION_clean {
my ($self) = @_;
$self->log_info("Cleaning up build files\n");
foreach my $item (map glob($_), $self->cleanup) {
$self->delete_filetree($item);
}
}
sub ACTION_realclean {
my ($self) = @_;
$self->depends_on('clean');
$self->log_info("Cleaning up configuration files\n");
$self->delete_filetree(
$self->config_dir, $self->mymetafile, $self->mymetafile2, $self->build_script
);
}
sub ACTION_ppd {
my ($self) = @_;
require Module::Build::PPMMaker;
my $ppd = Module::Build::PPMMaker->new();
my $file = $ppd->make_ppd(%{$self->{args}}, build => $self);
$self->add_to_cleanup($file);
}
sub ACTION_ppmdist {
my ($self) = @_;
$self->depends_on( 'build' );
my $ppm = $self->ppm_name;
$self->delete_filetree( $ppm );
$self->log_info( "Creating $ppm\n" );
$self->add_to_cleanup( $ppm, "$ppm.tar.gz" );
my %types = ( # translate types/dirs to those expected by ppm
lib => 'lib',
arch => 'arch',
bin => 'bin',
script => 'script',
bindoc => 'man1',
libdoc => 'man3',
binhtml => undef,
libhtml => undef,
);
foreach my $type ($self->install_types) {
next if exists( $types{$type} ) && !defined( $types{$type} );
my $dir = File::Spec->catdir( $self->blib, $type );
next unless -e $dir;
my $files = $self->rscan_dir( $dir );
foreach my $file ( @$files ) {
next unless -f $file;
my $rel_file =
File::Spec->abs2rel( File::Spec->rel2abs( $file ),
File::Spec->rel2abs( $dir ) );
my $to_file =
File::Spec->catfile( $ppm, 'blib',
exists( $types{$type} ) ? $types{$type} : $type,
$rel_file );
$self->copy_if_modified( from => $file, to => $to_file );
( run in 0.619 second using v1.01-cache-2.11-cpan-4991d5b9bd9 )