Skip to content

Instantly share code, notes, and snippets.

@chrisgaunt
Forked from le0pard/git_changlog
Created July 26, 2011 01:41
Show Gist options
  • Save chrisgaunt/1105738 to your computer and use it in GitHub Desktop.
Save chrisgaunt/1105738 to your computer and use it in GitHub Desktop.
Automatic git changelog
#!/usr/bin/env ruby
SPECIAL_TOKEN = 'SpecialTokenForSearch'
WITHOUT_MERGES = "--no-merges"
GIT_COMMIT_LINK="https://github.com/some_projects/commit/:commit"
cmd = `git show-ref --tags`
tags = []
cmd.each do |l|
tag_commit, tag_name = l.chomp.split(" ")
tags << {:name => tag_name.sub("refs/tags/", ""), :commit => tag_commit}
end
tags.each do |tag|
cmd = `git show --pretty='format:#{SPECIAL_TOKEN}|%H|%d|%cD|%ci|%ct|%an|%ae' --no-notes #{tag[:name]}`
line = nil
cmd.each do |l|
if l.match(/^#{SPECIAL_TOKEN}/)
line = l.chomp
break
end
end
if line
line_array = line.split("|")
tag[:date] = line_array[4]
tag[:unix_date] = line_array[5]
tag[:username] = line_array[6]
tag[:email] = line_array[7]
end
end
tags = tags.sort{|a,b| a[:unix_date] <=> b[:unix_date]}.reverse
changelog_array = []
before_tag = nil
tags.each do |tag|
if before_tag
temp_data = {}
temp_data[:tag] = before_tag
cmd = `git log #{WITHOUT_MERGES} --date=short --pretty='%H|%h|%cr|%cn|%cd|%ci|%an|%ae|%s' #{tag[:commit]}..#{before_tag[:commit]}`
temp_data[:commits] = []
cmd.each do |l|
line_array = l.chomp.split("|")
temp_data[:commits] << {:username => line_array[3],
:email => line_array[7], :comment => line_array[8],
:date_ago => line_array[2], :commit => line_array[0],
:date => line_array[7]}
end
changelog_array << temp_data
end
before_tag = tag
end
output_type = ARGV[0]
out_types = ['plain', 'html']
if output_type.nil? || output_type == 'plain' || (output_type && !out_types.include?(output_type))
File.open('CHANGELOG', 'w+') do |fl|
changelog_array.each do |changelog|
fl.puts "#{changelog[:tag][:name]}"
fl.puts "#{changelog[:tag][:date]} - #{changelog[:tag][:username]} <#{changelog[:tag][:email]}>"
fl.puts ""
changelog[:commits].each do |commit|
fl.puts " * #{commit[:username]} <#{commit[:email]}>: #{commit[:comment]} (#{commit[:date]}, commit: #{commit[:commit]})"
end
fl.puts ""
fl.puts ""
end
fl.puts "Date of generation: #{Time.now}"
end
elsif output_type == 'html'
REDMINE_LINK = "http://redmine.adility.com/issues/:num"
File.open('CHANGELOG.html', 'w+') do |fl|
fl.puts '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><title>CHANGELOG</title></head><body>'
changelog_array.each do |changelog|
fl.puts "<h2>#{changelog[:tag][:name]}</h2>"
fl.puts "<p>#{changelog[:tag][:date]} - #{changelog[:tag][:username]} <#{changelog[:tag][:email]}></p>"
fl.puts "<br />"
fl.puts "<ul>"
changelog[:commits].each do |commit|
redmine_links = []
commit_link = GIT_COMMIT_LINK.gsub(":commit", commit[:commit])
redmine_id = commit[:comment].scan(/\#(\d+)/i).flatten
unless redmine_id.nil?
redmine_id.each do |id|
redmine_links << {:id => id, :link => REDMINE_LINK.gsub(":num", id)}
end
end
fl.puts "<li>#{commit[:username]} <#{commit[:email]}>: #{commit[:comment]} ("
if redmine_links.size > 0
redmine_links.each do |redmine_link|
fl.puts "Redmine ticket: <a href='#{redmine_link[:link]}' target='_blank'>#{redmine_link[:id]}</a>, "
end
end
fl.puts "#{commit[:date]}, commit: <a href='#{commit_link}' target='_blank'>#{commit[:commit]}</a>)"
end
fl.puts "</ul>"
fl.puts "<br />"
fl.puts "<br />"
end
fl.puts "<p style='color:#333;'>Date of generation: #{Time.now}</p>"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment