Git Hooks For Pre-Commit Rspec Testing

Here’s a pair of scripts for automatically running Ruby rspec tests, refusing to commit if they fail, and pulling in the results into the commit msg. If you want to use them place them in your project’s .git/hooks directory as executable scripts.

These scripts assume you have rspec writing to rspec_results.html. To do this by default add a .rspec file in your project dir with “-f doc -f h -o rspec_results.html” inside.

pre-commit

#!/usr/bin/env ruby
require 'pty'
html_path = "rspec_results.html"  
#PTY.spawn trick from
#http://stackoverflow.com/questions/1154846/continuously-read-from-stdout-of-external-process-in-ruby
begin
	PTY.spawn( "rake spec" ) do |stdin, stdout, pid|
	begin
		stdin.each { |line| print line }
	rescue Errno::EIO
		end
	end
rescue PTY::ChildExited
	puts "The child process exited!"
end
 
# find out how many errors were found  
html = open(html_path).read  
examples = html.match(/(\d+) examples/)[0].to_i rescue 0  
failures = html.match(/(\d+) failures/)[0].to_i rescue 0  
if failures == 0 then
	failures = html.match(/(\d+) failure/)[0].to_i rescue 0  
end
pending = html.match(/(\d+) pending/)[0].to_i rescue 0  
 
if failures.zero?  
  puts "0 failed! #{examples} run, #{pending} pending"  
  puts "View rspec results at #{File.expand_path(html_path)}"  
  sleep 1
  exit 0
else  
  puts "\aDID NOT COMMIT YOUR FILES!"  
  puts "View rspec results at #{File.expand_path(html_path)}"  
  puts  
  puts "#{failures} failed! #{examples} run, #{pending} pending"  
  `open #{html_path}`
  exit 1  
end

prepare-commit-msg

#!/usr/bin/env ruby
html_path = "rspec_results.html"
# find out how many errors were found  
html = open(html_path).read
examples = html.match(/(\d+) examples/)[0].to_i rescue 0
failures = html.match(/(\d+) failures/)[0].to_i rescue 0
if failures == 0 then
        failures = html.match(/(\d+) failure/)[0].to_i rescue 0
end
pending = html.match(/(\d+) pending/)[0].to_i rescue 0
 
 
message_file = ARGV[0]
message = File.read(message_file)
index = message.index('# Please enter the commit message for your changes. Lines starting')
message.insert(index-1, "\n\n#{failures} failed! #{examples} run, #{pending} pending")
open(message_file,'w') { |f|
        f.puts(message)
}

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">