|
Packit |
7d6a7d |
#!/usr/bin/perl -w
|
|
Packit |
7d6a7d |
################################################################################
|
|
Packit |
7d6a7d |
#
|
|
Packit |
7d6a7d |
# soak -- Test Perl modules with multiple Perl releases.
|
|
Packit |
7d6a7d |
#
|
|
Packit |
7d6a7d |
# Original Author: Paul Marquess
|
|
Packit |
7d6a7d |
#
|
|
Packit |
7d6a7d |
################################################################################
|
|
Packit |
7d6a7d |
#
|
|
Packit |
7d6a7d |
# Version 3.x, Copyright (C) 2004-2013, Marcus Holland-Moritz.
|
|
Packit |
7d6a7d |
# Version 2.x, Copyright (C) 2001, Paul Marquess.
|
|
Packit |
7d6a7d |
# Version 1.x, Copyright (C) 1999, Kenneth Albanowski.
|
|
Packit |
7d6a7d |
#
|
|
Packit |
7d6a7d |
# This program is free software; you can redistribute it and/or
|
|
Packit |
7d6a7d |
# modify it under the same terms as Perl itself.
|
|
Packit |
7d6a7d |
#
|
|
Packit |
7d6a7d |
################################################################################
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
require 5.006001;
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
use strict;
|
|
Packit |
7d6a7d |
use warnings;
|
|
Packit |
7d6a7d |
use ExtUtils::MakeMaker;
|
|
Packit |
7d6a7d |
use Getopt::Long;
|
|
Packit |
7d6a7d |
use Pod::Usage;
|
|
Packit |
7d6a7d |
use File::Find;
|
|
Packit |
7d6a7d |
use List::Util qw(max);
|
|
Packit |
7d6a7d |
use Config;
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
my $VERSION = '3.36';
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
$| = 1;
|
|
Packit |
7d6a7d |
my %OPT = (
|
|
Packit |
7d6a7d |
verbose => 0,
|
|
Packit |
7d6a7d |
make => $Config{make} || 'make',
|
|
Packit |
7d6a7d |
min => '5.000',
|
|
Packit |
7d6a7d |
color => 1,
|
|
Packit |
7d6a7d |
);
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
GetOptions(\%OPT, qw(verbose make=s min=s mmargs=s@ color!)) or pod2usage(2);
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
$OPT{mmargs} = [''] unless exists $OPT{mmargs};
|
|
Packit |
7d6a7d |
$OPT{min} = parse_version($OPT{min}) - 1e-10;
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub cs($;$$) { my $x = shift; my($s, $p) = @_ ? @_ : ('', 's'); ($x, $x == 1 ? $s : $p) }
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
my @GoodPerls = map { $_->[0] }
|
|
Packit |
7d6a7d |
sort { $a->[1] <=> $b->[1] or $a->[0] cmp $b->[0] }
|
|
Packit |
7d6a7d |
grep { $_->[1] >= $OPT{min} }
|
|
Packit |
7d6a7d |
map { [$_ => perl_version($_)] }
|
|
Packit |
7d6a7d |
@ARGV ? SearchPerls(@ARGV) : FindPerls();
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
unless (@GoodPerls) {
|
|
Packit |
7d6a7d |
print "Sorry, got no Perl binaries for testing.\n\n";
|
|
Packit |
7d6a7d |
exit 0;
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
my $maxlen = max(map length, @GoodPerls) + 3;
|
|
Packit |
7d6a7d |
my $mmalen = max(map length, @{$OPT{mmargs}});
|
|
Packit |
7d6a7d |
$maxlen += $mmalen+3 if $mmalen > 0;
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
my $rep = Soak::Reporter->new( verbose => $OPT{verbose}
|
|
Packit |
7d6a7d |
, color => $OPT{color}
|
|
Packit |
7d6a7d |
, width => $maxlen
|
|
Packit |
7d6a7d |
);
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
$SIG{__WARN__} = sub { $rep->warn(@_) };
|
|
Packit |
7d6a7d |
$SIG{__DIE__} = sub { $rep->die(@_) };
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
# prime the pump, so the first "make realclean" will work.
|
|
Packit |
7d6a7d |
runit("$^X Makefile.PL") && runit("$OPT{make} realclean")
|
|
Packit |
7d6a7d |
or $rep->die("Cannot run $^X Makefile.PL && $OPT{make} realclean\n");
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
my $tot = @GoodPerls*@{$OPT{mmargs}};
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
$rep->set(tests => $tot);
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
$rep->status(sprintf("Testing %d version%s / %d configuration%s (%d combination%s)...\n",
|
|
Packit |
7d6a7d |
cs(@GoodPerls), cs(@{$OPT{mmargs}}), cs($tot)));
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
for my $perl (@GoodPerls) {
|
|
Packit |
7d6a7d |
for my $mm (@{$OPT{mmargs}}) {
|
|
Packit |
7d6a7d |
$rep->set(perl => $perl, config => $mm);
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
$rep->test;
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
my @warn_mfpl;
|
|
Packit |
7d6a7d |
my @warn_make;
|
|
Packit |
7d6a7d |
my @warn_test;
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
my $ok = runit("$perl Makefile.PL $mm", \@warn_mfpl) &&
|
|
Packit |
7d6a7d |
runit("$OPT{make}", \@warn_make) &&
|
|
Packit |
7d6a7d |
runit("$OPT{make} test", \@warn_test);
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
$rep->warnings(['Makefile.PL' => \@warn_mfpl],
|
|
Packit |
7d6a7d |
['make' => \@warn_make],
|
|
Packit |
7d6a7d |
['make test' => \@warn_test]);
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
if ($ok) {
|
|
Packit |
7d6a7d |
$rep->passed;
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
else {
|
|
Packit |
7d6a7d |
$rep->failed;
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
runit("$OPT{make} realclean");
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
exit $rep->finish;
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub runit
|
|
Packit |
7d6a7d |
{
|
|
Packit |
7d6a7d |
# TODO -- portability alert!!
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
my($cmd, $warn) = @_;
|
|
Packit |
7d6a7d |
$rep->vsay("\n Running [$cmd]");
|
|
Packit |
7d6a7d |
my $output = `$cmd 2>&1;;
|
|
Packit |
7d6a7d |
$output = "\n" unless defined $output;
|
|
Packit |
7d6a7d |
$output =~ s/^/ > /gm;
|
|
Packit |
7d6a7d |
$rep->say("\n Output:\n$output") if $OPT{verbose} || $?;
|
|
Packit |
7d6a7d |
if ($?) {
|
|
Packit |
7d6a7d |
$rep->warn(" Running '$cmd' failed: $?\n");
|
|
Packit |
7d6a7d |
return 0;
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
push @$warn, $output =~ /(warning: .*)/ig;
|
|
Packit |
7d6a7d |
return 1;
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub FindPerls
|
|
Packit |
7d6a7d |
{
|
|
Packit |
7d6a7d |
# TODO -- need to decide how far back we go.
|
|
Packit |
7d6a7d |
# TODO -- get list of user releases prior to 5.004
|
|
Packit |
7d6a7d |
# TODO -- does not work on Windows (at least)
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
# find versions of Perl that are available
|
|
Packit |
7d6a7d |
my @PerlBinaries = qw(
|
|
Packit |
7d6a7d |
5.000
|
|
Packit |
7d6a7d |
5.001
|
|
Packit |
7d6a7d |
5.002
|
|
Packit |
7d6a7d |
5.003
|
|
Packit |
7d6a7d |
5.004 5.00401 5.00402 5.00403 5.00404 5.00405
|
|
Packit |
7d6a7d |
5.005 5.00501 5.00502 5.00503 5.00504
|
|
Packit |
7d6a7d |
5.6.0 5.6.1 5.6.2
|
|
Packit |
7d6a7d |
5.7.0 5.7.1 5.7.2 5.7.3
|
|
Packit |
7d6a7d |
5.8.0 5.8.1 5.8.2 5.8.3 5.8.4 5.8.5 5.8.6 5.8.7 5.8.8
|
|
Packit |
7d6a7d |
5.9.0 5.9.1 5.9.2 5.9.3
|
|
Packit |
7d6a7d |
);
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
print "Searching for Perl binaries...\n";
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
# find_perl will send a warning to STDOUT if it can't find
|
|
Packit |
7d6a7d |
# the requested perl, so need to temporarily silence STDOUT.
|
|
Packit |
7d6a7d |
tie *STDOUT, 'NoSTDOUT';
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
my $mm = MM->new( { NAME => 'dummy' });
|
|
Packit |
7d6a7d |
my @path = $mm->path;
|
|
Packit |
7d6a7d |
my @GoodPerls;
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
for my $perl (@PerlBinaries) {
|
|
Packit |
7d6a7d |
if (my $abs = $mm->find_perl($perl, ["perl$perl"], \@path, 0)) {
|
|
Packit |
7d6a7d |
push @GoodPerls, $abs;
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
untie *STDOUT;
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
print "\nFound:\n", (map " $_\n", @GoodPerls), "\n";
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
return @GoodPerls;
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub SearchPerls
|
|
Packit |
7d6a7d |
{
|
|
Packit |
7d6a7d |
my @args = @_;
|
|
Packit |
7d6a7d |
my @perls;
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
for my $arg (@args) {
|
|
Packit |
7d6a7d |
if (-d $arg) {
|
|
Packit |
7d6a7d |
my @found;
|
|
Packit |
7d6a7d |
print "Searching for Perl binaries in '$arg'...\n";
|
|
Packit |
7d6a7d |
find({ wanted => sub {
|
|
Packit |
7d6a7d |
$File::Find::name =~ m!perl5[\w._]+$!
|
|
Packit |
7d6a7d |
and -f $File::Find::name
|
|
Packit |
7d6a7d |
and -x $File::Find::name
|
|
Packit |
7d6a7d |
and perl_version($File::Find::name)
|
|
Packit |
7d6a7d |
and push @found, $File::Find::name;
|
|
Packit |
7d6a7d |
}, follow => 1 }, $arg);
|
|
Packit |
7d6a7d |
printf "Found %d Perl binar%s in '%s'.\n\n", cs(@found, 'y', 'ies'), $arg;
|
|
Packit |
7d6a7d |
push @perls, @found;
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
else {
|
|
Packit |
7d6a7d |
push @perls, $arg;
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
return @perls;
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub perl_version
|
|
Packit |
7d6a7d |
{
|
|
Packit |
7d6a7d |
my $perl = shift;
|
|
Packit |
7d6a7d |
my $ver = `$perl -e 'print \$]' 2>&1;;
|
|
Packit |
7d6a7d |
return $? == 0 && $ver =~ /^\d+\.\d+/ && $ver >= 5 ? $ver : 0;
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub parse_version
|
|
Packit |
7d6a7d |
{
|
|
Packit |
7d6a7d |
my $ver = shift;
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
if ($ver =~ /^(\d+)\.(\d+)\.(\d+)$/) {
|
|
Packit |
7d6a7d |
return $1 + 1e-3*$2 + 1e-6*$3;
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
elsif ($ver =~ /^\d+\.[\d_]+$/) {
|
|
Packit |
7d6a7d |
$ver =~ s/_//g;
|
|
Packit |
7d6a7d |
return $ver;
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
die "cannot parse version '$ver'\n";
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
package NoSTDOUT;
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
use Tie::Handle;
|
|
Packit |
7d6a7d |
our @ISA = qw(Tie::Handle);
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub TIEHANDLE { bless \(my $s = ''), shift }
|
|
Packit |
7d6a7d |
sub PRINT {}
|
|
Packit |
7d6a7d |
sub WRITE {}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
package Soak::Reporter;
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
use strict;
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub cs($;$$) { my $x = shift; my($s, $p) = @_ ? @_ : ('', 's'); ($x, $x == 1 ? $s : $p) }
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub new
|
|
Packit |
7d6a7d |
{
|
|
Packit |
7d6a7d |
my $class = shift;
|
|
Packit |
7d6a7d |
bless {
|
|
Packit |
7d6a7d |
tests => undef,
|
|
Packit |
7d6a7d |
color => 1,
|
|
Packit |
7d6a7d |
verbose => 0,
|
|
Packit |
7d6a7d |
@_,
|
|
Packit |
7d6a7d |
_cur => 0,
|
|
Packit |
7d6a7d |
_atbol => 1,
|
|
Packit |
7d6a7d |
_total => 0,
|
|
Packit |
7d6a7d |
_good => [],
|
|
Packit |
7d6a7d |
_bad => [],
|
|
Packit |
7d6a7d |
}, $class;
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub colored
|
|
Packit |
7d6a7d |
{
|
|
Packit |
7d6a7d |
my $self = shift;
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
if ($self->{color}) {
|
|
Packit |
7d6a7d |
my $c = eval {
|
|
Packit |
7d6a7d |
require Term::ANSIColor;
|
|
Packit |
7d6a7d |
Term::ANSIColor::colored(@_);
|
|
Packit |
7d6a7d |
};
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
if ($@) {
|
|
Packit |
7d6a7d |
$self->{color} = 0;
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
else {
|
|
Packit |
7d6a7d |
return $c;
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
return $_[0];
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub _config
|
|
Packit |
7d6a7d |
{
|
|
Packit |
7d6a7d |
my $self = shift;
|
|
Packit |
7d6a7d |
return $self->{config} =~ /\S+/ ? " ($self->{config})" : '';
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub _progress
|
|
Packit |
7d6a7d |
{
|
|
Packit |
7d6a7d |
my $self = shift;
|
|
Packit |
7d6a7d |
return '' unless defined $self->{tests};
|
|
Packit |
7d6a7d |
my $tlen = length $self->{tests};
|
|
Packit |
7d6a7d |
my $text = sprintf "[%${tlen}d/%${tlen}d] ", $self->{_cur}, $self->{tests};
|
|
Packit |
7d6a7d |
return $self->colored($text, 'bold');
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub _test
|
|
Packit |
7d6a7d |
{
|
|
Packit |
7d6a7d |
my $self = shift;
|
|
Packit |
7d6a7d |
return $self->_progress . "Testing "
|
|
Packit |
7d6a7d |
. $self->colored($self->{perl}, 'blue')
|
|
Packit |
7d6a7d |
. $self->colored($self->_config, 'green');
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub _testlen
|
|
Packit |
7d6a7d |
{
|
|
Packit |
7d6a7d |
my $self = shift;
|
|
Packit |
7d6a7d |
return length("Testing " . $self->{perl} . $self->_config);
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub _dots
|
|
Packit |
7d6a7d |
{
|
|
Packit |
7d6a7d |
my $self = shift;
|
|
Packit |
7d6a7d |
return '.' x $self->_dotslen;
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub _dotslen
|
|
Packit |
7d6a7d |
{
|
|
Packit |
7d6a7d |
my $self = shift;
|
|
Packit |
7d6a7d |
return $self->{width} - length($self->{perl} . $self->_config);
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub _sep
|
|
Packit |
7d6a7d |
{
|
|
Packit |
7d6a7d |
my $self = shift;
|
|
Packit |
7d6a7d |
my $width = shift;
|
|
Packit |
7d6a7d |
$self->print($self->colored('-'x$width, 'bold'), "\n");
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub _vsep
|
|
Packit |
7d6a7d |
{
|
|
Packit |
7d6a7d |
goto &_sep if $_[0]->{verbose};
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub set
|
|
Packit |
7d6a7d |
{
|
|
Packit |
7d6a7d |
my $self = shift;
|
|
Packit |
7d6a7d |
while (@_) {
|
|
Packit |
7d6a7d |
my($k, $v) = splice @_, 0, 2;
|
|
Packit |
7d6a7d |
$self->{$k} = $v;
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub test
|
|
Packit |
7d6a7d |
{
|
|
Packit |
7d6a7d |
my $self = shift;
|
|
Packit |
7d6a7d |
$self->{_cur}++;
|
|
Packit |
7d6a7d |
$self->_vsep($self->_testlen);
|
|
Packit |
7d6a7d |
$self->print($self->_test, $self->{verbose} ? "\n" : ' ' . $self->_dots . ' ');
|
|
Packit |
7d6a7d |
$self->_vsep($self->_testlen);
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub _warnings
|
|
Packit |
7d6a7d |
{
|
|
Packit |
7d6a7d |
my($self, $mode) = @_;
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
my $warnings = 0;
|
|
Packit |
7d6a7d |
my $differ = 0;
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
for my $w (@{$self->{_warnings}}) {
|
|
Packit |
7d6a7d |
if (@{$w->[1]}) {
|
|
Packit |
7d6a7d |
$warnings += @{$w->[1]};
|
|
Packit |
7d6a7d |
$differ++;
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
my $rv = '';
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
if ($warnings) {
|
|
Packit |
7d6a7d |
if ($mode eq 'summary') {
|
|
Packit |
7d6a7d |
$rv .= sprintf " (%d warning%s", cs($warnings);
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
else {
|
|
Packit |
7d6a7d |
$rv .= "\n";
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
for my $w (@{$self->{_warnings}}) {
|
|
Packit |
7d6a7d |
if (@{$w->[1]}) {
|
|
Packit |
7d6a7d |
if ($mode eq 'detail') {
|
|
Packit |
7d6a7d |
$rv .= " Warnings during '$w->[0]':\n";
|
|
Packit |
7d6a7d |
my $cnt = 1;
|
|
Packit |
7d6a7d |
for my $msg (@{$w->[1]}) {
|
|
Packit |
7d6a7d |
$rv .= sprintf " [%d] %s", $cnt++, $msg;
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
$rv .= "\n";
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
else {
|
|
Packit |
7d6a7d |
unless ($self->{verbose}) {
|
|
Packit |
7d6a7d |
$rv .= $differ == 1 ? " during " . $w->[0]
|
|
Packit |
7d6a7d |
: sprintf(", %d during %s", scalar @{$w->[1]}, $w->[0]);
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
if ($mode eq 'summary') {
|
|
Packit |
7d6a7d |
$rv .= ')';
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
return $rv;
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub _result
|
|
Packit |
7d6a7d |
{
|
|
Packit |
7d6a7d |
my($self, $text, $color) = @_;
|
|
Packit |
7d6a7d |
my $sum = $self->_warnings('summary');
|
|
Packit |
7d6a7d |
my $len = $self->_testlen + $self->_dotslen + length($text) + length($sum) + 2;
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
$self->_vsep($len);
|
|
Packit |
7d6a7d |
$self->print($self->_test, ' ', $self->_dots, ' ') if $self->{verbose} || $self->{_atbol};
|
|
Packit |
7d6a7d |
$self->print($self->colored($text, $color));
|
|
Packit |
7d6a7d |
$self->print($self->colored($sum, 'red'));
|
|
Packit |
7d6a7d |
$self->print("\n");
|
|
Packit |
7d6a7d |
$self->_vsep($len);
|
|
Packit |
7d6a7d |
$self->print($self->_warnings('detail')) if $self->{verbose};
|
|
Packit |
7d6a7d |
$self->{_total}++;
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub passed
|
|
Packit |
7d6a7d |
{
|
|
Packit |
7d6a7d |
my $self = shift;
|
|
Packit |
7d6a7d |
$self->_result(@_, 'ok', 'bold green');
|
|
Packit |
7d6a7d |
push @{$self->{_good}}, [$self->{perl}, $self->{config}];
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub failed
|
|
Packit |
7d6a7d |
{
|
|
Packit |
7d6a7d |
my $self = shift;
|
|
Packit |
7d6a7d |
$self->_result(@_, 'not ok', 'bold red');
|
|
Packit |
7d6a7d |
push @{$self->{_bad}}, [$self->{perl}, $self->{config}];
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub warnings
|
|
Packit |
7d6a7d |
{
|
|
Packit |
7d6a7d |
my $self = shift;
|
|
Packit |
7d6a7d |
$self->{_warnings} = \@_;
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub _tobol
|
|
Packit |
7d6a7d |
{
|
|
Packit |
7d6a7d |
my $self = shift;
|
|
Packit |
7d6a7d |
print "\n" unless $self->{_atbol};
|
|
Packit |
7d6a7d |
$self->{_atbol} = 1;
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub print
|
|
Packit |
7d6a7d |
{
|
|
Packit |
7d6a7d |
my $self = shift;
|
|
Packit |
7d6a7d |
my $text = join '', @_;
|
|
Packit |
7d6a7d |
print $text;
|
|
Packit |
7d6a7d |
$self->{_atbol} = $text =~ /[\r\n]$/;
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub say
|
|
Packit |
7d6a7d |
{
|
|
Packit |
7d6a7d |
my $self = shift;
|
|
Packit |
7d6a7d |
$self->_tobol;
|
|
Packit |
7d6a7d |
$self->print(@_, "\n");
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub vsay
|
|
Packit |
7d6a7d |
{
|
|
Packit |
7d6a7d |
goto &say if $_[0]->{verbose};
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub warn
|
|
Packit |
7d6a7d |
{
|
|
Packit |
7d6a7d |
my $self = shift;
|
|
Packit |
7d6a7d |
$self->say($self->colored(join('', @_), 'red'));
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub die
|
|
Packit |
7d6a7d |
{
|
|
Packit |
7d6a7d |
my $self = shift;
|
|
Packit |
7d6a7d |
$self->say($self->colored(join('', 'FATAL: ', @_), 'bold red'));
|
|
Packit |
7d6a7d |
exit -1;
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub status
|
|
Packit |
7d6a7d |
{
|
|
Packit |
7d6a7d |
my($self, $text) = @_;
|
|
Packit |
7d6a7d |
$self->_tobol;
|
|
Packit |
7d6a7d |
$self->print($self->colored($text, 'bold'), "\n");
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sub finish
|
|
Packit |
7d6a7d |
{
|
|
Packit |
7d6a7d |
my $self = shift;
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
if (@{$self->{_bad}}) {
|
|
Packit |
7d6a7d |
$self->status("\nFailed with:");
|
|
Packit |
7d6a7d |
for my $fail (@{$self->{_bad}}) {
|
|
Packit |
7d6a7d |
my($perl, $cfg) = @$fail;
|
|
Packit |
7d6a7d |
$self->set(config => $cfg);
|
|
Packit |
7d6a7d |
$self->say(" ", $self->colored($perl, 'blue'), $self->colored($self->_config, 'green'));
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
$self->status(sprintf("\nPassed with %d of %d combination%s.\n",
|
|
Packit |
7d6a7d |
scalar @{$self->{_good}}, cs($self->{_total})));
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
return scalar @{$self->{_bad}};
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
__END__
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
=head1 NAME
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
soak - Test Perl modules with multiple Perl releases
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
=head1 SYNOPSIS
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
soak [options] [perl ...]
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
--make=program override name of make program ($Config{make})
|
|
Packit |
7d6a7d |
--min=version use at least this version of perl
|
|
Packit |
7d6a7d |
--mmargs=options pass options to Makefile.PL (multiple --mmargs possible)
|
|
Packit |
7d6a7d |
--verbose be verbose
|
|
Packit |
7d6a7d |
--nocolor don't use colored output
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
=head1 DESCRIPTION
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
The F<soak> utility can be used to test Perl modules with
|
|
Packit |
7d6a7d |
multiple Perl releases or build options. It automates the
|
|
Packit |
7d6a7d |
task of running F<Makefile.PL> and the modules test suite.
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
It is not primarily intended for cross-platform checking,
|
|
Packit |
7d6a7d |
so don't expect it to work on all platforms.
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
=head1 EXAMPLES
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
To test your favourite module, just change to its root
|
|
Packit |
7d6a7d |
directory (where the F<Makefile.PL> is located) and run:
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
soak
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
This will automatically look for Perl binaries installed
|
|
Packit |
7d6a7d |
on your system.
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
Alternatively, you can explicitly pass F<soak> a list of
|
|
Packit |
7d6a7d |
Perl binaries:
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
soak perl5.8.6 perl5.9.2
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
Last but not least, you can pass it a list of directories
|
|
Packit |
7d6a7d |
to recursively search for Perl binaries, for example:
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
soak /tmp/perl/install /usr/bin
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
All of the above examples will run
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
perl Makefile.PL
|
|
Packit |
7d6a7d |
make
|
|
Packit |
7d6a7d |
make test
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
for your module and report success or failure.
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
If your F<Makefile.PL> can take arguments, you may also
|
|
Packit |
7d6a7d |
want to test different configurations for your module.
|
|
Packit |
7d6a7d |
You can do so with the I<--mmargs> option:
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
soak --mmargs=' ' --mmargs='CCFLAGS=-Wextra' --mmargs='enable-debug'
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
This will run
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
perl Makefile.PL
|
|
Packit |
7d6a7d |
make
|
|
Packit |
7d6a7d |
make test
|
|
Packit |
7d6a7d |
perl Makefile.PL CCFLAGS=-Wextra
|
|
Packit |
7d6a7d |
make
|
|
Packit |
7d6a7d |
make test
|
|
Packit |
7d6a7d |
perl Makefile.PL enable-debug
|
|
Packit |
7d6a7d |
make
|
|
Packit |
7d6a7d |
make test
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
for each Perl binary.
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
If you have a directory full of different Perl binaries,
|
|
Packit |
7d6a7d |
but your module isn't expected to work with ancient perls,
|
|
Packit |
7d6a7d |
you can use the I<--min> option to specify the minimum
|
|
Packit |
7d6a7d |
version a Perl binary must have to be chosen for testing:
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
soak --min=5.8.1
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
Usually, the output of F<soak> is rather terse, to give
|
|
Packit |
7d6a7d |
you a good overview. If you'd like to see more of what's
|
|
Packit |
7d6a7d |
going on, use the I<--verbose> option:
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
soak --verbose
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
=head1 COPYRIGHT
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
Version 3.x, Copyright (c) 2004-2013, Marcus Holland-Moritz.
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
Version 2.x, Copyright (C) 2001, Paul Marquess.
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
Version 1.x, Copyright (C) 1999, Kenneth Albanowski.
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
This program is free software; you can redistribute it and/or
|
|
Packit |
7d6a7d |
modify it under the same terms as Perl itself.
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
=head1 SEE ALSO
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
See L<Devel::PPPort>.
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
=cut
|