Skip to content

Instantly share code, notes, and snippets.

@evnm
Last active December 28, 2015 11:19
Show Gist options
  • Save evnm/7492445 to your computer and use it in GitHub Desktop.
Save evnm/7492445 to your computer and use it in GitHub Desktop.
A Ruby script that runs tests with Pants for all projects that have been modified in the current working tree.
#!/usr/bin/env ruby
#
# Run tests for all projects that have been modified in the Birdcage,
# relative to HEAD.
#
# For example, if you've edited files in three projects, this script will
# run tests serially for these three projects in one command.
print "Determining which files have been changed..."
$stdout.flush
birdcage_root=File.expand_path("../../", __FILE__)
test_targets = []
changed_files = `git status --porcelain`.split("\n").map do |line|
line[3..-1]
end
# Run through all changed files, picking out their corresponding
# BUILD:tests targets.
changed_files.each do |changed_file|
# Backtrack from the source file, hunting for the maximally-deep BUILD
# file containing a 'tests' target.
path_elements = changed_file.split('/')
path_elements.each_index do |i|
prefix = path_elements[0..(path_elements.size-1-i)]
build_files = Dir["#{prefix.join('/')}/**/BUILD"].select do |build_file|
found = `#{birdcage_root}/pants goal filter #{build_file}:: --filter-type=junit_tests 2> /dev/null`.split("\n")
unless found.empty?
test_targets += found
break
end
end
end
end
puts " Done."
if test_targets.empty?
puts "Working directory is clean. No tests to run."
else
test_targets.each do |test_target|
puts "Running tests at #{test_target}"
# `Kernel.system` captures SIGINT for subshells only, so we set a trap to
# explicitly exit when a user hits ^C.
unless system("#{birdcage_root}/pants goal test #{test_target}")
exit $?.exitstatus
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment