Created
July 24, 2013 14:31
-
-
Save mattwynne/6071100 to your computer and use it in GitHub Desktop.
See the blog post http://blog.mattwynne.net/2013/07/24/how-much-should-i-refactor/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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