## MakeAll.pl -- See pod at bottom.
use strict;
use warnings;
use Data::Dumper;
use File::Find;
use File::Spec;
use Getopt::Long;
use Pod::Usage;
use Text::Wrap qw(wrap);
use Cwd;
use vars qw/$VERSION/;
$VERSION='0.1';
sub _join {
return join("\n",map { wrap ""," ",$_ } @_),"\n";
}
GetOptions(
'help|?' => \(my $Help =0 ),
'run|r!' => \(my $Run =1 ),
'install|i!' => \(my $Install =0 ),
'verbose|v:+'=> \(my $Verbose =0 ),
'debug|d:+' => \(my $Debug =0 ),
'scan|s!' => \(my $Scan =0 ),
'man' => \(my $Man =0 )
)
or pod2usage(2);
pod2usage(1) if $Help;
pod2usage(-exitstatus => 0, -verbose => 2) if $Man;
warn "Run:$Run : Install:$Install : Verbose:$Verbose : Scan:$Scan\n"
if $Debug;
if($Scan) {
$Run=0;
$Verbose||=1;
}
my $fs='File::Spec';
my @vers;
foreach my $dir (split /;/,$ENV{PATH}) {
foreach (glob $fs->catdir("$dir","perl*.*")) {
if(/(perl(?:\d+\.\d+\.\d+)?(\.exe)?)$/i and -e $_){
my $name=$1;
my $spec=$_;
chomp( my ($ver,$arch,@V)=`$spec -V:version -V:archname -V
+`);
s/\w+='([^'']+)';/$1/g for $ver,$arch;
my $V=join "\n",@V;
push @vers,[$name,$spec,$ver,$arch,$V];
}
}
}
my %seen;
my %vers;
@vers=reverse grep {
if (!$seen{$_->[-1]}) {
$seen{$_->[-1]}=$_->[0];
printf "--- Found %s at %s version %s on %s ---\n",@$_
if $Verbose;
$vers{$_->[2]}{$_->[3]}++;
1
} else {
printf "--- Skipping duplicate of %s at %s version %s
+on %s ---\n",
$seen{$_->[-1]},@{$_}[1..$#$_-1]
if $Verbose>2;
0
}
} sort {
$b->[0] cmp $a->[0] ||
$b->[2] cmp $a->[2] ||
$b->[3] cmp $a->[3]
} @vers;
exit(0) unless $Run;
print "--- Work Dir: ".cwd()." ---\n";
my %status;
foreach my $perl (@vers) {
my ($name,$spec,$ver,$arch,$V)=@$perl;
my $test_name="Perl$ver ($arch) ".($vers{$perl->[2]}{$perl->[3]}>1
+ ? "[$spec]" : '');
$status{$test_name}=0;
print "--- Testing $test_name ---\n";
unlink 'Makefile';
print "Makefile.PL\n" if $Verbose;
my $makefile=`$spec Makefile.PL 2>&1 `;
unless(-e 'Makefile') {
warn "Failed to build with $test_name\nMakefile.PL output:\n$m
+akefile\n";
next;
} elsif ($Verbose>2) {
print "$makefile\n";
}
#print $makefile,"\n";
my $maker='make';
$maker="n$maker" if $arch=~/Win32/i;
print "$maker\n" if $Verbose;
my $make_out=`$maker 2>&1 `;
my $exit=$? >> 8;
if ($exit) {
warn "Failed to build with $test_name\n$maker output:\n$make_o
+ut\n";
next;
} elsif ($Verbose>2) {
print "$make_out\n";
}
print "$maker test\n" if $Verbose;
chomp(my @res=`$maker test 2>&1 `);
if ($exit) {
warn "Failed test with $test_name\n$maker test output:\n"._joi
+n(@res)."\n";
next;
}
if (join("",@res)=~/No tests defined/i) {
warn "No tests defined for the module\n";
next;
}
unless ($Verbose>4) {
# remove some stuff at the front, like possible version
# copyright crap from the maker.
shift @res while @res and $res[0]!~/\Q$name\E/;
shift @res if @res and $res[0]=~/\Q$name\E/;
}
#print Dumper(\@res),"\n\n";
#All tests successful, 38 subtests skipped.
#Files=16, Tests=279, 12 wallclock secs ( 0.00 cusr + 0.00 csys =
+ 0.00 CPU)
if ($res[-1]=~/Stop|Error|Failed/i) {
pop @res while @res and $res[-1]!~/$maker/i;
pop @res;
if ($Verbose>2) {
print _join(@res)."\n";
} else {
my @out;
unshift @out,pop @res until $res[-1]=~/^\s*Failed\s+\d+/;
unshift @out,pop @res;
print _join(@out);
}
} else {
#all goood
if ($Verbose>2) {
print _join(@res);
} else {
#all goood
print "$res[-2]\n$res[-1]\n";
}
$status{$test_name}=1;
if ($Install) {
# should trap errors here...
my $install=`$maker install 2>&1 `;
my $exit=$? >> 8;
if ($exit) {
warn "Exitcode $exit.\nFailed install with $test_name\
+n$maker install output:\n$install\n";
next;
} elsif ($Verbose>2) {
print "$install\n";
}
}
}
print "---End Test---\n\n";
}
__END__
=head1 NAME
MakeAll.pl - Build, test and optionally install a module on all versio
+ns of perl
located in path.
=head1 SYNOPSIS
MakeAll.pl [options] [file ...]
Options:
--help brief help message
--man full documentation
--verbose be talkative, repeat or assign a higher value for
+ more
--install do an install in each perl if build is good
--no-run don't run test, just scan path
--scan short for --verbose --no-run
=head1 DESCRIPTION
B<This program> will run the standard
perl Makefile.PL
make
make test
and optionally
make install
for each distinct perl executable it finds in the path (it uses some t
+ricks to make sure
they aren't dupes). On Win32 it will use make or nmake as is necessary
+ based on whether
the script itself is run under Activestate perl or Cygwin perl. On non
+ win32 machines
it will use make.
=head1 NOTES
Theres probably issues with this on some platform or another. Patches
+welcome.
=head1 AUTHOR AND COPYRIGHT
Copyright Yves Orton 2004. Released under the same terms as Perl itsel
+f. Please
see the Perl Artistic License distributed with Perl for details.
=cut
|