Skip to content

Instantly share code, notes, and snippets.

@nathany
Created March 30, 2011 04:58
Show Gist options
  • Save nathany/893888 to your computer and use it in GitHub Desktop.
Save nathany/893888 to your computer and use it in GitHub Desktop.
Generate a "Compare View" in markdown, complete with Gravatars and links to GitHub commits
require 'digest/md5'
namespace :git do
GITHUB_COMMIT_URL = "https://github.com/path/to/your/repo/commit/" # <= set me
# Before doing a deploy, I like to check GitHub's branch list
# but I wanted to be able to save it in a Lighthouse message
COMPARE_FOR = {
'production' => 'origin/production..origin/release',
'release' => 'origin/production..origin/release',
'staging' => 'origin/staging..origin/master',
'master' => 'origin/staging..origin/master'
}
desc "generate compare view from git log"
task :log do
branch = current_branch
compare = COMPARE_FOR[branch]
raise "Not sure what to compare '#{branch}' with." if compare.nil?
today = Time.now.strftime('%Y-%m-%d')
file = "#{today}-compare.md"
raise "File in the way '#{file}'." if File.exists?(file)
run_cmd('git fetch') # track the latest
GitLog.new(file, compare)
end
# local branch currently checked out:
def current_branch
out = run_cmd('git branch')
local_branch = $1 if out =~ /\* (\S+)\s/m
end
def run_cmd(cmd)
out = `#{cmd}`
err = $?
raise "Running `#{cmd}' failed (#{err})." unless err == 0
out
end
# Parse a git log and reformat it as markdown with GitHub links and Gravatars
class GitLog
def initialize(file, compare)
@authors = {}
format = "%ad|%an|%ae|%s|%h" # date, name, email, subject, commit_hash
# get the git log:
# for options: http://www.kernel.org/pub/software/scm/git/docs/git-log.html
raw = run_cmd(%Q{git log --pretty=format:"#{format}" --no-merges --topo-order --reverse --date=short #{compare}})
raise "No differences found." if raw.length == 0
puts "Compare View for #{compare} => #{file}"
File.open(file, "w") do |file|
file << markdown_header("Compare View #{compare}")
raw.each_line do |line|
file << parse(line.chomp) << "\n"
end
file << "\n" << author_references.join("\n")
end
raw = nil
end
def parse(line)
date, name, email, subject, commit_hash = line.split('|')
ref = add_author(name, email)
image_ref = "![][#{ref}]" # markdown image reference ![alt][id]
commit = markdown_github_url(commit_hash)
[date, "#{image_ref} #{name}", subject, commit].join('|')
end
def add_author(name, email)
author = @authors[email]
if author.nil?
author = {:name => name, :email => email, :ref => "id#{@authors.length}"}
@authors[email] = author
end
author[:ref]
end
def author_references
@authors.map do |k, author|
ref = author[:ref]
gravatar = gravatar_url(author[:email])
name = author[:name]
%Q{[#{ref}]: #{gravatar} "#{name}"} # markdown reference-style image
end
end
def markdown_header(title)
<<-MD.gsub(/^\s+/, '')
## #{title}
Date|Name|Subject|Commit
----|----|-------|------
MD
end
# gravatar image url
def gravatar_url(email, size=25)
digest = Digest::MD5.hexdigest(email.strip.downcase)
"https://secure.gravatar.com/avatar/#{digest}?s=#{size}"
end
# markdown-style urls to GitHub commits
def markdown_github_url(commit_hash)
"[#{commit_hash}](#{GITHUB_COMMIT_URL}#{commit_hash})"
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment