Skip to content

Instantly share code, notes, and snippets.

@dtan4
Last active August 29, 2015 14:16
Show Gist options
  • Save dtan4/fa87628d99293d6f573b to your computer and use it in GitHub Desktop.
Save dtan4/fa87628d99293d6f573b to your computer and use it in GitHub Desktop.
Extract spec files which were changed from specified branch/commit
#!/usr/bin/env ruby
#
# Example usage
# - Test only changed model files & specs from master
# $ bundle exec rspec $(script/changed-specs model master)
#
require "open3"
require "shellwords"
def detect_spec_file(file_name)
spec_file = if %r(^app\/(.+)) =~ file_name
"spec/#{$1}"
elsif %r(^spec\/(.+)) =~ file_name
file_name
else
nil
end
return "" unless spec_file && File.exist?(spec_file)
spec_file
end
def git_diff_command(base_branch)
"git --no-pager diff --name-only #{Shellwords.escape(base_branch)}"
end
def model_spec?(spec_name)
!!(%r(^spec/models) =~ spec_name)
end
def controller_spec?(spec_name)
!!(%r(^spec/controllers) =~ spec_name)
end
def lib_spec?(spec_name)
!!(%r(^spec/lib) =~ spec_name)
end
def helper_spec?(spec_name)
!!(%r(^spec/helpers) =~ spec_name)
end
def mailer_spec?(spec_name)
!!(%r(^spec/mailers) =~ spec_name)
end
def concern_spec?(spec_name)
!!(%r(^spec/concern) =~ spec_name)
end
def feature_spec?(spec_name)
!!(%r(^spec/features) =~ spec_name)
end
def select_run_specs(spec_types, spec_files)
return spec_files if spec_types.include?("all")
spec_types.inject([]) do |result, spec_type|
result << spec_files.select { |spec| self.send("#{spec_type}_spec?", spec) }
result
end.flatten.uniq
end
AVAILABLE_SPEC_TYPES = %w(all model controller lib helper mailer concern feature)
USAGE = <<-EOS
$ changed-specs <types = all> <base_branch = master>
Available spec types:
#{AVAILABLE_SPEC_TYPES.map { |type| " #{type}" }.join("\n")}
EOS
spec_types = %w(all)
base_branch = "master"
case ARGV.length
when 2
spec_types, base_branch = ARGV[0].split(","), ARGV[1]
when 1
spec_types = ARGV[0].split(",")
when 0
else
$stderr.puts USAGE
exit 1
end
spec_types.each do |spec_type|
unless AVAILABLE_SPEC_TYPES.include?(spec_type.downcase)
$stderr.puts USAGE
exit 1
end
end
stdout, stderr, exit_code = *Open3.capture3(git_diff_command(base_branch))
unless exit_code.to_i.zero?
$stderr.puts stderr
exit exit_code.to_i
end
spec_files = stdout.lines.map { |line| detect_spec_file(line.strip) }.reject { |spec| spec == "" }
run_spec_files = select_run_specs(spec_types, spec_files)
puts run_spec_files.join(" ")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment