Skip to content

Instantly share code, notes, and snippets.

@afresh1
Created November 24, 2014 23:30
Show Gist options
  • Save afresh1/bc101cb228c3728d1f35 to your computer and use it in GitHub Desktop.
Save afresh1/bc101cb228c3728d1f35 to your computer and use it in GitHub Desktop.
A script that checks for changed files and re-runs prove if they have changed.
#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
use File::Find;
my %options_that_take_arguments = map { $_ => 1 }
qw( I P M e exec harness formatter source a archive j jobs state rc );
open my $prove, '-|', 'prove', '-D', @ARGV or die $!;
my %test_files = map { s/\r?\n//; $_ => 1 } <$prove>;
close $prove or die $!;
my @flags;
my @search_paths;
while (@ARGV) {
$_ = shift @ARGV;
if (/(^--(\w+)(=.*)?)$/) {
push @flags, $1;
push @flags, shift @ARGV
if $options_that_take_arguments{$2} and not defined $3;
}
elsif (/(^-\w*(\w)(=.*)?)$/) {
push @flags, $1;
push @flags, shift @ARGV
if $options_that_take_arguments{$2} and not defined $3;
}
else { push @search_paths, $_ }
}
push @search_paths, keys %test_files;
push @search_paths, split /\s+/, $ENV{WATCH_FILES} || '';
my @watch_files;
find( sub {
return unless -f $_;
push @watch_files, {
name => $File::Find::name,
mtime => (stat(_))[9],
};
}, 'lib', grep {-e} @search_paths);
run_tests();
# brute force file watcher
while (1) {
sleep 3;
check_for_updates();
}
sub run_tests {
my @f = @_;
my @tests = grep { is_test($_) } @f;
@tests = keys %test_files unless @tests;
say "prove @flags @tests";
system 'prove', @flags, @tests;
}
sub is_test {
my ($file) = @_;
return $test_files{$file};
}
sub check_for_updates {
my @changed;
my @new;
foreach my $file (@watch_files) {
next unless -e $file->{name};
push @new, $file;
my $mtime = ( stat(_) )[9];
if ($file->{mtime} != $mtime) {
push @changed, $file->{name};
$file->{mtime} = $mtime;
}
}
@watch_files = @new;
return unless @changed;
return run_tests(@changed);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment