Skip to content

Instantly share code, notes, and snippets.

@michaelfeathers
Created March 2, 2011 23:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save michaelfeathers/851953 to your computer and use it in GitHub Desktop.
Save michaelfeathers/851953 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
# Print the vaportrail of a ruby file in a git repo, i.e.,
# the complexity level at each commit.
#
# Requires: >= bash ?.?
# >= git 1.7.1
# >= ruby 1.9.2
# >= flog 2.5.0
#
require 'flog'
require 'time'
TEMP_FILE = "/tmp/vaportrail_junk.rb"
class VaporTrail
class Reporter < ::StringIO
# borrowed from Chad Fowler
SCORE_LINE_DETECTOR = /^\s+([^:]+).*flog total$/
def score
Float(string.scan(SCORE_LINE_DETECTOR).flatten.first)
end
end
def self.trail_for(filename)
new(filename).generate_datestamped_complexities.sort
end
def initialize(filename)
@filename = filename
end
def generate_datestamped_complexities
complexities = {}
sha1s_of_commits.each do |sha1|
complexities[commit_date_of(sha1)] = complexity_of(sha1)
end
complexities
end
def commit_date_of(sha1)
Time.parse(`git show -s --format=%cd #{sha1}`).strftime("%D")
end
def complexity_of(sha1)
`git show #{sha1}:#{@filename} > #{TEMP_FILE}`
flogger = Flog.new
reporter = Reporter.new
flogger.flog(TEMP_FILE)
flogger.report(reporter)
reporter.score
end
def sha1s_of_commits
@commits ||= `git log #{@filename}| grep ^commit`.split(/\n/).map(&:split).map {|fields| fields[sha1_columm = 1] }
end
end
if ARGV.size != 1
puts "help: vaportrail <rubyfilename>"
puts " run in the folder of a git repo"
exit
end
p VaporTrail.trail_for(ARGV[0])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment