Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Commit = Struct.new(:repo, :sha, :comment, :stats) do
def refactoring?(previous_commit)
return :spec_files_unchanged if no_changes_to_specs
return :comment if refactoring_comment
return false if result.nil? || result.failed > 0 || result.total == 0
return :spec_results_unchanged if result == previous_commit.result
return false
end
def no_changes_to_specs
!stats.any? { |s| s.path =~ /^spec/ }
end
def refactoring_comment
comment =~ /refactor/i
end
def result
@result ||= repo.test(sha)
end
end
Stat = Struct.new(:pct, :path)
Result = Struct.new(:total, :failed)
Repo = Struct.new(:path) do
def dirstat
`cd #{path} && git co master && git log --pretty=oneline --dirstat`.split("\n")
end
def test(sha)
output = `cd #{path} && git checkout #{sha} && (rake || rspec)`
results_match = output.match(/(\d+) examples, (\d+) failures/)
if results_match
total, failed = results_match.captures
Result.new(total.to_i, failed.to_i)
end
end
end
class Log
def initialize(repo_path)
@repo = Repo.new(repo_path)
end
def commits
commits = []
@repo.dirstat.each do |line|
match_commit = line.match(/^(\w+) (.*)$/)
match_stat = line.match(/([\d\.]+)\% (.*)/)
if match_commit
sha, comment = match_commit.captures
commit = Commit.new(@repo, sha, comment, [])
commits << commit
elsif match_stat
pct, path = match_stat.captures
stat = Stat.new(pct, path)
commits.last.stats << stat
else
raise "Unable to parse this line:\n#{line}"
end
end
commits
end
def refactoring_commits
result = []
commits.each_index do |index|
previous = commits[index - 1]
commit = commits[index]
reason = commit.refactoring?(previous)
result << [commit, reason] if reason
end
result
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.