lib/rspactor/runner.rb in mislav-rspactor-0.3.2 vs lib/rspactor/runner.rb in mislav-rspactor-0.3.3

- old
+ new

@@ -1,55 +1,98 @@ require 'rspactor' module RSpactor class Runner - def self.load - dotfile = File.join(ENV['HOME'], '.rspactor') - Kernel.load dotfile if File.exists?(dotfile) - - dir = Dir.pwd - @inspector = Inspector.new(dir) - @interactor = Interactor.new - + def self.start(options = {}) + new(Dir.pwd, options).start + end + + attr_reader :dir, :options, :inspector, :interactor + + def initialize(dir, options = {}) + @dir = dir + @options = options + read_git_head + end + + def start + load_dotfile puts "** RSpactor is now watching at '#{dir}'" - - aborted = initial_spec_run_abort + start_interactor + start_listener + end + + def start_interactor + @interactor = Interactor.new + aborted = @interactor.wait_for_enter_key("** Hit <enter> to skip initial spec run", 3) @interactor.start_termination_handler run_all_specs unless aborted + end + + def start_listener + @inspector = Inspector.new(dir) Listener.new(Inspector::EXTENSIONS) do |files| - files_to_spec = [] - files.each do |file| - spec_files = @inspector.determine_spec_files(file) - unless spec_files.empty? - puts spec_files.join("\n") - files_to_spec.concat spec_files - end - end - run_spec_command(files_to_spec) + spec_changed_files(files) unless git_head_changed? end.run(dir) end - - def self.initial_spec_run_abort - @interactor.wait_for_enter_key("** Hit <enter> to skip initial spec run", 3) + + def load_dotfile + dotfile = File.join(ENV['HOME'], '.rspactor') + if File.exists?(dotfile) + begin + Kernel.load dotfile + rescue => e + $stderr.puts "Error while loading #{dotfile}: #{e}" + end + end end - def self.run_all_specs + def run_all_specs run_spec_command('spec') end - def self.run_spec_command(paths) + def run_spec_command(paths) paths = Array(paths) - return if paths.empty? - run_command [ruby_opts, spec_runner, paths, spec_opts].flatten.join(' ') + if paths.empty? + @last_run_failed = nil + else + cmd = [ruby_opts, spec_runner, paths, spec_opts].flatten.join(' ') + @last_run_failed = run_command(cmd) + end end + + def last_run_failed? + @last_run_failed == false + end + + protected - def self.run_command(cmd) + def run_command(cmd) system(cmd) + $?.success? end + + def spec_changed_files(files) + files_to_spec = files.inject([]) do |all, file| + all.concat inspector.determine_spec_files(file) + end + unless files_to_spec.empty? + puts files_to_spec.join("\n") + + previous_run_failed = last_run_failed? + run_spec_command(files_to_spec) + + if options[:retry_failed] and previous_run_failed and not last_run_failed? + run_all_specs + end + end + end + + private - def self.spec_opts + def spec_opts if File.exist?('spec/spec.opts') opts = File.read('spec/spec.opts').gsub("\n", ' ') else opts = "--color" end @@ -59,24 +102,36 @@ opts << ' -f progress' unless opts.scan(/\s(?:-f|--format)\b/).length > 1 opts end - def self.formatter_opts + def formatter_opts "-r #{File.dirname(__FILE__)}/../rspec_growler.rb -f RSpecGrowler:STDOUT" end - def self.spec_runner + def spec_runner if File.exist?("script/spec") "script/spec" else "spec" end end - def self.ruby_opts + def ruby_opts other = ENV['RUBYOPT'] ? " #{ENV['RUBYOPT']}" : '' + other << ' -rcoral' if options[:coral] %(RUBYOPT='-Ilib:spec#{other}') + end + + def git_head_changed? + old_git_head = @git_head + read_git_head + @git_head and old_git_head and @git_head != old_git_head + end + + def read_git_head + git_head_file = File.join(dir, '.git', 'HEAD') + @git_head = File.exists?(git_head_file) && File.read(git_head_file) end end end # backward compatibility \ No newline at end of file