#!/usr/bin/env perl
# Copyright 2004-2016, Paul Johnson (paul@pjcj.net)
# This software is free. It is licensed under the same terms as Perl itself.
# The latest version of this software should be available from my homepage:
# http://www.pjcj.net
use strict;
use warnings;
use lib "utils";
use Getopt::Long;
use Parallel::Iterator "iterate_as_array";
use Devel::Cover::BuildUtils qw( prove_command cpus nice_cpus );
my $Options = {
build => 0,
dry_run => 0,
force => 0,
ignore_failure => 0,
silent => 1,
version => [],
};
my $Silent = " >/dev/null 2>&1";
sub get_options {
die "Bad option" unless
GetOptions($Options, qw(
build!
dry_run!
force!
ignore_failure!
list!
silent!
version=s
));
$Options->{version} = [ map { ($_, "$_-thr") } qw(
5.8.1 5.8.2 5.8.3 5.8.4 5.8.5 5.8.6 5.8.7 5.8.8 5.8.9
5.10.0 5.10.1
5.12.0 5.12.1 5.12.2 5.12.3 5.12.4 5.12.5
5.14.0 5.14.1 5.14.2 5.14.3 5.14.4
5.16.0 5.16.1 5.16.2 5.16.3
5.18.0 5.18.1 5.18.2 5.18.3 5.18.4
5.20.0 5.20.1 5.20.2 5.20.3
5.22.0 5.22.1
5.23.0 5.23.1 5.23.2 5.23.3 5.23.4 5.23.5 5.23.6 5.23.7 5.23.8 5.23.9
) ] unless @{$Options->{version}};
$Options->{version} =
[ grep {
my $cmd = "dc-$_ -v$Silent";
my $exists = eval { !system $cmd };
$Options->{force} || ($exists ^ $Options->{build})
} @{$Options->{version}} ];
print "Versions: @{$Options->{version}}\n";
if ($Options->{list}) {
exit;
}
}
sub sys {
my ($command, $user) = @_;
print "$command\n";
return if $Options->{dry_run};
$command .= $Silent if $Options->{silent} && !$user;
my $ret = system $command;
warn "command failed: $?" if $ret && !$Options->{ignore_failure};
!$ret
}
sub _mods {
my ($v, $n) = @_;
my ($s) = $n =~ /(\d+)$/;
my $version = version->parse($n);
my @mods = qw( Test::Harness Test::Warn HTML::Entities );
return @mods if $v =~ /-thr/ && $s != 1;
push @mods, qw(
Template
Pod::Coverage
Test::Differences
Readonly
Parallel::Iterator
Sereal
);
push @mods, "Algorithm::C3" if $n =~ /^5\.8\.9\b/;
push @mods, "Moose" unless $n =~ /^5\.8\.[012]\b/;
push @mods, "Moo" unless $n =~ /^5\.8\.[012]\b/;
push @mods, "DBM::Deep" unless $n =~ /^5\.8\.[01234]\b/;
push @mods, "Perl::Tidy" if !$s || $s % 2;
push @mods, "PPI::HTML" if !$s || !($s % 2);
@mods
}
sub _build_version {
my ($v) = @_;
print "building $v\n";
# sleep 1; return;
my $dir = ($ENV{PERLBREW_ROOT} || die 'No $PERLBREW_ROOT') .
"/perls/dc-$v/bin";
my ($n) = $v =~ /(\d+\.\d+\.\d+)/ or die "Can't parse [$v}";
unless (-d $dir) {
my $opts = "";
$opts .= " --thread" if $v =~ /thr/;
my $j = cpus + 1;
sys "perlbrew -v install $n --as dc-$v -j $j $opts --notest --noman" or
do {
die "perlbrew $v failed";
return;
};
unless (-d $dir) {
warn "perl for $v does not exist";
return;
}
}
$ENV{PATH} = "$dir:$ENV{PATH}";
sys "curl -L http://cpanmin.us | perl - App::cpanminus" or do {
warn "cpanm installation for $v failed";
return;
};
my @mods = _mods($v, $n);
sys "cpanm --notest @mods" or do {
warn "module installation for $v failed";
return;
};
my $ln = "/usr/local/bin/dc-$v";
sys "sudo rm $ln$Silent";
my ($perl) = "$dir/perl";
print "$perl => $ln\n";
sys "sudo ln -s $perl $ln" or warn "Can't ln $perl => $ln: $!";
}
sub build {
print "Building: @{$Options->{version}}\n";
my @res = iterate_as_array(
{ workers => nice_cpus * 2 },
sub {
my (undef, $v) = @_;
_build_version($v);
},
$Options->{version}
);
exit;
}
sub main {
get_options;
build if $Options->{build};
my $command = "@ARGV" or die "Usage: $0 [-v version] command\n";
for my $v (@{$Options->{version}}) {
my $perl = "dc-$v";
(my $c = $command) =~ s/=perl/$perl/g;
# print "Running [$c] from $v\n";
# $c =~ s/=v/$v/g;
if ($c =~ /^make /) {
sys "rm -rf t/e2e";
sys "$perl Makefile.PL";
sys "make clean";
sys "$perl Makefile.PL";
sys "make";
}
sys $c, 1;
}
}
main