Skip to content

Commit

Permalink
Add a tool for backporters.
Browse files Browse the repository at this point in the history
* tool/generate-backport-changelog.rb: Generate ChangeLog entries from svn log.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58132 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information
unak committed Mar 25, 2017
1 parent cd80709 commit 14ae786
Showing 1 changed file with 99 additions and 0 deletions.
99 changes: 99 additions & 0 deletions tool/generate-backport-changelog.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#!ruby
require "time"

def usage!
STDERR.puts <<-EOS
Usage: $0 [--trunk=<dir>] [--target=<dir>] <revision(s)>
Generate ChangeLog entries for backporting.
The entries are output to STDOUT, and the messages of this tool are output to
STDERR. So you can simply redirect STDOUT to get the entries.
You should specify the path of trunk by `--trunk`. If not, assumed cwd.
You also should specify the path of the target branch by `--target`. If not,
assumed cwd.
This means that you have to specify at least one of `--trunk` or `--target`.
revision(s) can be below or their combinations:
12345 # means r12345
12345,54321 # means r12345 and r54321
12345-12347 # means r12345, r12346 and r12347 (of course, if available)
Note that the revisions is backported branch's ones, not trunk's.
The target of this tool is *not* to generate ChangeLog automatically, but to
generate the draft of ChangeLog.
You have to check and modify the output.
EOS
exit
end

Majors = {
"eregon" => "Benoit Daloze <[email protected]>",
"kazu" => "Kazuhiro NISHIYAMA <[email protected]>",
"ko1" => "Koichi Sasada <[email protected]>",
"marcandre" => "Marc-Andre Lafortune <[email protected]>",
"naruse" => "NARUSE, Yui <[email protected]>",
"nobu" => "Nobuyoshi Nakada <[email protected]>",
"normal" => "Eric Wong <[email protected]>",
"rhe" => "Kazuki Yamaguchi <[email protected]>",
"shugo" => "Shugo Maeda <[email protected]>",
"stomar" => "Marcus Stollsteimer <[email protected]>",
"usa" => "NAKAMURA Usaku <[email protected]>",
"zzak" => "Zachary Scott <[email protected]>",
}

trunk = "."
target = "."
ARGV.delete_if{|e| /^--trunk=(.*)/ =~ e && trunk = $1}
ARGV.delete_if{|e| /^--target=/ =~ e && target = $1}
usage! if ARGV.size == 0 || trunk == target

revisions = []
ARGV.each do |a|
a.split(/,/).each do |b|
if /-/ =~ b
revisions += Range.new(*b.split(/-/, 2).map{|e| Integer(e)}).to_a
else
revisions << Integer(b)
end
end
end
revisions.sort!
revisions.reverse!

revisions.each do |rev|
if /^Index: ChangeLog$/ =~ `svn diff -c #{rev} #{target}`
STDERR.puts "#{rev} already has ChangeLog. Skip."
else
lines = `svn log -r #{rev} #{target}`.lines[1..-2]
if lines.empty?
STDERR.puts "#{rev} does not exist. Skip."
next
end
unless /^merge revision\(s\) (\d+)/ =~ lines[2]
STDERR.puts "#{rev} is not seems to be a merge commit. Skip."
next
end
original = $1
committer = `svn log -r #{original} #{trunk}`.lines[1].split(/\|/)[1].strip
if Majors[committer]
committer = Majors[committer]
else
committer = "#{committer} <#{committer}@ruby-lang.org>"
end
time = Time.parse(lines.shift.split(/\|/)[2]).getlocal("+09:00")
puts "#{time.asctime} #{committer}"
puts
lines.shift(2) # skip "merge" line
lines.shift while lines.first == "\n"
lines.pop while lines.last == "\n"
lines.each do |line|
line.chomp!
line = "\t#{line}" if line[0] != "\t" && line != ""
puts line
end
puts
STDERR.puts "#{rev} is processed."
end
end

0 comments on commit 14ae786

Please sign in to comment.