Skip to content

Instantly share code, notes, and snippets.

@wr0ngway
Last active August 29, 2015 13:57
Show Gist options
  • Save wr0ngway/9504108 to your computer and use it in GitHub Desktop.
Save wr0ngway/9504108 to your computer and use it in GitHub Desktop.
For generating changelogs for bundler rubygem projects
#!/usr/bin/env ruby
require 'bundler'
changelog_file = 'CHANGELOG'
entries = ""
helper = Bundler::GemHelper.new(Dir.pwd)
current_version = "v#{helper.gemspec.version}"
starting_version = nil
ending_version = nil, ending_version_name = nil
if ENV['VERSION']
ver = ENV['VERSION']
first_ver, second_ver = ver.split("..")
starting_version = "v#{first_ver.gsub(/^[^\d]*/, '')}" if ! first_ver.nil? && first_ver.size > 0
ending_version = "v#{second_ver.gsub(/^[^\d]*/, '')}" if ! second_ver.nil? && second_ver.size > 0
ending_version_name = ending_version if ending_version
end
# If we already have a changelog, make the starting_version be the
# last one in the changelog
#
if ! starting_version && File.exist?(changelog_file)
entries = File.read(changelog_file)
head = entries.split.first
if head =~ /(\d+\.\d+\.\d+).*/
starting_version = "v#{$1}"
if current_version == starting_version
puts "WARN: gemspec version is the same as most recent changelog: #{current_version}"
end
end
end
# Get a list of current tags
tags = `git tag -l`.split
tags = tags.sort_by {|t| t[1..-1].split(".").collect {|s| s.to_i } }
newest_tag = tags[-1]
if current_version == newest_tag
# When generating CHANGELOG after release, we want the last tag as the ending version
ending_version = newest_tag
ending_version_name = newest_tag
else
# When generating CHANGELOG before release, we want the current ver as the ending version
ending_version = "HEAD"
ending_version_name = current_version
end
if starting_version
version_selector = "#{starting_version}..#{ending_version}"
else
puts "WARN: No starting version, dumping entire history, try: rake changelog VERSION=v1.2.3"
version_selector = ""
end
# Generate changelog from repo
puts "Generating a changelog for #{version_selector}"
log=`git log --pretty='format:%s <%h> [%cn]' #{version_selector}`.lines.to_a
# Strip out maintenance entries
log = log.delete_if do |l|
l =~ /^Regenerated? gemspec/ ||
l =~ /^version bump/i ||
l =~ /^bump version/i ||
l =~ /^updated changelog/i ||
l =~ /^merged? branch/i
end
# Add templates user needs to run vulcanize for (only for rubber project)
if File.basename(Dir.pwd) == 'rubber'
log = log.collect do |l|
if l =~ /<(.+)>/
ver = $1
files = `git diff --name-only #{ver}^1 #{ver}`.lines.to_a
templates = files.collect {|f| f =~ /templates\/([^\/]+)\// ? $1 : nil}.compact.sort.uniq
templates << 'core' if templates.size == 0
l = "[#{templates.join(", ")}] #{l}"
end
l
end
end
# sort so core comes first
log = log.sort_by {|s| s =~ /\[.*core.*\]/ ? "" : s }
# Write out changelog file
File.open(changelog_file, 'w') do |out|
ver_title = ending_version_name.gsub(/^v/, '') + " (#{Time.now.strftime("%m/%d/%Y")})"
out.puts ver_title
out.puts "-" * ver_title.size
out.puts "\n"
out.puts log
out.puts "\n"
out.puts entries
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment