Created
May 18, 2010 17:31
-
-
Save tiegz/405270 to your computer and use it in GitHub Desktop.
A Ruby script that uses grit.rb and raphael.js to visualize your JS LOC per commit over time
This file contains hidden or 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
# 1) Put this file in your working directory | |
# 2) run 'sudo gem install active_support grit' | |
# 3) run 'ruby git-line-count.rb' | |
# 4) run 'open loc.html' | |
# 5) yay | |
require 'rubygems' | |
require 'active_support' | |
require 'grit' | |
require 'open-uri' | |
require 'fileutils' | |
include Grit | |
repo = Repo.new(".") | |
MAX_COMMITS = 1_000_000 | |
OUTPUT_FILE = "loc.html" | |
FILE_EXTENSION = /\.js$/ | |
EXCLUDED_FILES = %w(files.js to.js exclude.js).map { |str| Regexp.escape(str) }.join('|') | |
EXCLUDED = /#{EXCLUDED_FILES}/i | |
PER_DAY = true # true = show 1-commit-per-day, false = show all commits | |
TITLE = "'#{repo.head.name}' branch JavaScript LOC #{PER_DAY ? 'per day' : 'per commit'}" | |
commits_with_loc = [] | |
total_count = 0 # gets reset every commit | |
current_date = nil # gets reset every commit | |
recursive_loc_count = lambda do |tree_or_blob| | |
if tree_or_blob.is_a?(Grit::Tree) | |
# A directory | |
tree_or_blob.contents.each(&recursive_loc_count) | |
elsif tree_or_blob.is_a?(Grit::Blob) \ | |
&& tree_or_blob.name =~ FILE_EXTENSION \ | |
&& tree_or_blob.name !~ EXCLUDED | |
# A matched file | |
total_count += tree_or_blob.data.select { |line| line !~ /^[\n\s\r]*$/ }.count | |
else | |
# A non-matched file. | |
end | |
end | |
# puts repo.commits[0].methods.sort.join(', ') | |
repo.commits('master', MAX_COMMITS).each do |commit| | |
total_count = 0 | |
this_date = commit.committed_date.to_date | |
if !PER_DAY || (PER_DAY && this_date != current_date) | |
# Record this commit as end-of-day commit | |
current_date = this_date | |
commit.tree.contents.each(&recursive_loc_count) | |
commits_with_loc << { | |
:date => commit.committed_date.to_datetime.strftime("%-m/%-d/%y"), | |
:id => commit.id, | |
:loc => total_count | |
} | |
else | |
# The day this commits falls on has already been recorded | |
end | |
end | |
mod = (commits_with_loc.size / 5).round | |
commits_with_loc.reverse! | |
html = %Q! | |
<\!doctype html> | |
<html> | |
<head> | |
<title>LOC Visualization</title> | |
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> | |
<style type="text/css" media="screen"> | |
/* http://raphaeljs.com/demo.css */ | |
body { | |
background: #000; | |
color: #fff; | |
font: 300 100.1% "Helvetica Neue", Helvetica, "Arial Unicode MS", Arial, sans-serif; | |
} | |
#holder { | |
height: 480px; | |
left: 50%; | |
margin: -240px 0 0 -320px; | |
position: absolute; | |
top: 50%; | |
width: 800px; | |
} | |
#copy { | |
bottom: 0; | |
font: 300 .7em "Helvetica Neue", Helvetica, "Arial Unicode MS", Arial, sans-serif; | |
position: absolute; | |
right: 1em; | |
text-align: right; | |
} | |
#copy a { | |
color: #fff; | |
} | |
</style> | |
<script type="text/javascript" charset="utf-8"> | |
/* raphael.js */ | |
#{open('http://github.com/DmitryBaranovskiy/raphael/raw/master/raphael.js').read} | |
/* raphael.path.methods.js */ | |
#{open('http://github.com/DmitryBaranovskiy/raphael/raw/master/plugins/raphael.path.methods.js').read} | |
/* jquery.js */ | |
#{open('http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js').read} | |
/* raphael.js */ | |
#{open('http://raphaeljs.com/analytics.js').read.gsub('"" : "s"', '"" : ""').gsub('height = 250', 'height = 400').gsub('Y * data[i]', 'Y * parseInt(data[i])').gsub('hit', 'LOC').gsub('dot.attr("r", 5);', 'dot.attr("r", 0);').gsub('r.circle(x, y, 5)', 'r.circle(x, y, 0)').gsub('{text: lbl + " September 2008"}', '{text: lbl}')} | |
</script> | |
</head> | |
<body> | |
<h1 style="text-align: center;">#{TITLE}</h1> | |
<table id="data"> | |
<tfoot> | |
<tr>! | |
commits_with_loc.each_with_index do |commit, index| | |
html << %Q! | |
<th>#{commit[:date] if index % mod == 0 || index == commits_with_loc.size - 1}</th>! | |
end | |
html << %Q! | |
</tr> | |
</tfoot> | |
<tbody> | |
<tr> | |
! | |
commits_with_loc.each_with_index do |commit, index| | |
html << %Q! | |
<td>#{commit[:loc]}</td>! | |
end | |
html << %Q!</tr> | |
</tbody> | |
</table> | |
<div id="holder"></div> | |
<p id="copy">Git LOC-per-commit visualization by @tiegz using <a href="http://grit.rubyforge.org/">grit.rb</a> & <a href="http://raphaeljs.com/">Raphaël</a>—JavaScript Vector Library</p> | |
</body> | |
</html> | |
! | |
FileUtils.rm_f(OUTPUT_FILE) | |
f = File.open(OUTPUT_FILE, 'w').write(html) |
Fixed that with tree_or_blob.lines.data
--must be a Ruby 1.8 vs. 1.9 thing.
Of course now I am getting illegal character: [Break On This Error] #{open('http://raphaeljs.com/analy...
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I'm getting an error on line 37, it says
tree_or_blob.data
is a String and thus #select is not a method.