#!/usr/bin/env ruby # tester_elf simply autoruns a ruby test file when you save it. # As dumb as it gets, but sometimes convenient. # # Usage: # 1) Place it in your "script" dir # 2) chmod +x script/tester_elf # 3) script/tester_elf # Stop using Ctrl/Cmd + C # # Based on restarter script by Jonathan Penn (http://www.wavethenavel.com). # Tweaked around by Maxim Chernyak (http://mediumexposure.com) POLL_DIRECTORIES = %w(test/unit test/functional) POLL_TIME = 0.9 RUN_WITH = "ruby -Itest" class TesterElf def initialize(options = {}) @dirs = options[:dirs] || %w(test/unit test/functional) @interval = options[:interval] || 0.9 @command = options[:command] || 'ruby -Itest' @states = {} end def work! Dir.chdir(File.join(File.dirname(__FILE__), '..')) $stderr.puts "Tester Elf is at your service... Checking files in #{@dirs.join(', ')} every #{@interval} seconds." processes = [] Signal.trap(0) do processes.map{|p| Process.kill("INT", p)} end Signal.trap("INT") do $stderr.puts "Shutting down tester_elf" exit end check_for_changes loop do sleep @interval changes = check_for_changes unless changes.empty? $stderr.puts emphasized("Running test...#{changes.inspect}") processes.map{|p| Process.kill("INT", p)} processes = changes.collect do |path| fork { exec("#{@command} #{path}") } end end end end private def emphasized(m) "\e[1;1m\e[41m \e[0m \e[1;1m\e[1m #{m} \e[0m" end def check_for_changes changes = [] Dir[*@dirs.map{|i|i+"/**/*"}].each do |file| unless File.symlink?(file) new_time = File.stat(file).mtime if @states[file] != new_time @states[file] = new_time changes << file end end end changes end end elf = TesterElf.new(:dirs => POLL_DIRECTORIES, :interval => POLL_TIME, :command => RUN_WITH) elf.work!