Created
January 6, 2015 04:19
-
-
Save science/776757a72b7c29160b60 to your computer and use it in GitHub Desktop.
Simple Workstation CI system. Runs your code when changes are detected. Supports line-by-line debugging.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'irb' | |
require 'term/ansicolor' | |
require 'open3' | |
module LT | |
module Term class << self | |
include ::Term::ANSIColor | |
end; end | |
end | |
# Monitors all files matching "test_*" in ./test and subfolders for changes | |
# When it detects a change, it runs the file | |
# To use, you must edit line 15 for any boot up prelim tasks | |
# And edit line 56 to tell monitor how to run your test file (via rake or ruby or however your test system works) | |
desc "Monitor files for changes and run a single test when a change is detected" | |
task :monitor => [:"ANY BOOT UP TASKS HERE"] do |t, args| | |
keep_running = true | |
last_test_file = nil | |
test_file = "" | |
puts "\n\n" | |
dot = ['.', ' '].cycle | |
while keep_running do | |
# Loop until interrupted by ctrl-c | |
trap("INT") { puts "\nExiting"; keep_running = false; exit;} | |
# if ctrl-z is pressed, re-run the last test file | |
trap("TSTP") { | |
if !last_test_file.nil? then | |
puts "\nRe-running last test: #{last_test_file}" | |
test_file = last_test_file | |
end | |
} | |
test_list = FileList['test/**/*_test.rb'] | |
orig_test_dates = {} | |
test_list.each do |file| | |
orig_test_dates[file] = File.stat(file).mtime | |
end | |
# loop through test_list looking for date changes | |
keep_searching = true | |
while keep_searching && keep_running do | |
print "\r#{LT::Term::white}***#{LT::Term::reset} Waiting for file changes. (#{Time::now.strftime('%I:%M %p')}), ctrl-z: re-run last, ctrl-c: exit#{dot.next}" | |
Kernel::sleep(0.3) # wait 3/10 second between searches for changed files | |
test_list.each do |file| | |
Kernel::sleep(0.05) # keep the cpu from maxing out | |
if orig_test_dates[file] != File.stat(file).mtime | |
print "\n",LT::Term::white," File change detected: ", LT::Term::bold,"./#{file}",LT::Term::reset,"\n" | |
puts " Time is: #{Time::now}" | |
keep_searching = false | |
test_file = file | |
end | |
end | |
if !test_file.blank? && keep_running | |
full_test_file = File::expand_path(File::join('.',test_file)) | |
# invoke the test b/c the file has changed | |
puts "Running test suite..." | |
last_test_file = test_file | |
# we capture the output and stream to stdout it line-by-line | |
IO.popen("rake TASK TO RUN YOUR TEST FILE HERE[#{full_test_file}]").each do |result_line| | |
failure_error = result_line.match(/^\s+[0-9]+\) Error:/) || result_line.match(/^\s+[0-9]+\) Failure:/) | |
asserts_failed = result_line.match(/runs, ([0-9]+) assertions, ([0-9]+) failures, ([0-9]+) errors/) | |
if failure_error then | |
puts LT::Term::red+result_line+LT::Term::reset+LT::Term::yellow | |
elsif asserts_failed | |
asserts = asserts_failed[1] | |
failures = asserts_failed[2] | |
errors = asserts_failed[3] | |
if failures == "0" && errors == "0" then | |
puts LT::Term::reset+LT::Term::green+result_line+LT::Term::reset | |
else | |
puts LT::Term::reset+LT::Term::red+result_line | |
end | |
else | |
puts result_line | |
end | |
end | |
print LT::Term::reset | |
test_file = "" | |
end | |
end # while keep_searching... -- change detection loop | |
end # while keep_running do -- main loop | |
end # task :monitor |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment