Skip to content

Instantly share code, notes, and snippets.

@miyagawa
Created November 6, 2012 11:45
Show Gist options
  • Save miyagawa/4024197 to your computer and use it in GitHub Desktop.
Save miyagawa/4024197 to your computer and use it in GitHub Desktop.
preload modules and then fork and run perl .t like prove. Runs Moose tests in < 50% of the time
package ForkProve::SourceHandler;
use strict;
use parent qw(TAP::Parser::SourceHandler);
use Capture::Tiny qw(capture_stdout);
use File::Spec;
use TAP::Parser::IteratorFactory;
TAP::Parser::IteratorFactory->register_handler(__PACKAGE__);
sub can_handle {
my($class, $src) = @_;
return 1 if $src->meta->{file}{ext} eq '.t';
}
sub make_iterator {
my($class, $src) = @_;
my $path = File::Spec->rel2abs($src->meta->{file}{dir} . $src->meta->{file}{basename});
pipe my $read, my $write;
my $pid = fork;
if ($pid) {
close $write;
my @tap = <$read>;
close $read;
waitpid $pid, 0;
return TAP::Parser::Iterator::Array->new(\@tap);
} else {
close $read;
my $out = capture_stdout { local $0 = $path; eval "package main; do \$path" };
die $! if $!;
print {$write} $out;
close $write;
exit;
}
}
package App::ForkProve;
use App::Prove;
use Getopt::Long qw(:config pass_through);
@ARGV = map { /^(-M)(.+)/ ? ($1,$2) : $_ } @ARGV;
my @modules;
Getopt::Long::GetOptions('M=s@', \@modules);
for (@modules) {
my($module, @import) = split /[=,]/;
eval "require $module" or die $@;
$module->import(@import);
}
my $app = App::Prove->new;
$app->process_args(@ARGV);
$app->run;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment