lib/respec/app.rb in respec-0.8.3 vs lib/respec/app.rb in respec-0.9.0
- old
+ new
@@ -10,15 +10,21 @@
@args = args
@raw_args = []
end
@failures_path = self.class.default_failures_path
@update_failures = true
+ @error = nil
process_args
end
attr_accessor :failures_path
+ def error
+ command
+ @error
+ end
+
def command
@command ||= program_args + generated_args + raw_args + formatter_args
end
def program_args
@@ -56,10 +62,11 @@
|
|Run rspec, recording failed examples for easy rerunning later.
|
|RESPEC-ARGS may consist of:
|
+ | d Run all spec files changed since the last git commit
| f Rerun all failed examples
| <N> Rerun only the N-th failure
| <file name> Run all specs in this file
| <file name:N> Run specs at line N in this file
| <other> Run only examples matching this pattern
@@ -77,10 +84,11 @@
def process_args
args = []
files = []
pass_next_arg = false
using_filters = false
+ changed_only = false
@args.each do |arg|
if pass_next_arg
args << arg
pass_next_arg = false
elsif rspec_option_that_requires_an_argument?(arg)
@@ -92,10 +100,12 @@
@help_only = true
elsif arg =~ /\A-/
args << arg
elsif arg =~ /\AFAILURES=(.*)\z/
self.failures_path = $1
+ elsif arg == 'd'
+ changed_only = true
elsif arg == 'f'
# failures_path could still be overridden -- delay evaluation of this.
args << lambda do
if File.exist?(failures_path)
if failures.empty?
@@ -115,11 +125,11 @@
if (failure = failures[i - 1])
args << '-e' << failure
@update_failures = false
using_filters = true
else
- warn "invalid failure: #{i} for (1..#{failures.size})"
+ @error = "invalid failure: #{i} for (1..#{failures.size})"
end
else
args << '-e' << arg.gsub(/[$]/, '\\\\\\0')
end
end
@@ -141,13 +151,26 @@
# Since we append our formatter as a file to run, rspec won't fall back to
# using 'spec' by default. Add it explicitly here.
files << 'spec' if files.empty?
+ # Filter files only to those changed if 'd' is present.
+ if changed_only
+ files = changed_paths(files)
+ end
+
# If we selected individual failures to rerun, don't give the files to
# rspec, as those files will be run in their entirety.
@generated_args = expanded
@generated_args.concat(files)
+ end
+
+ def changed_paths(paths)
+ changes = `git status --short --untracked-files=all #{paths.shelljoin}`
+ changes.lines.map do |line|
+ path = line[3..-1].chomp
+ path if File.exist?(path) && path =~ /\.rb\z/i
+ end.compact.uniq
end
def failures
@failures ||=
if File.exist?(failures_path)