aboutsummaryrefslogtreecommitdiffstats
path: root/tool
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-03-25 20:35:51 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-03-25 20:35:51 +0000
commit9d225cd2ad09a6fa7b778a592389bb9b515990e3 (patch)
tree0096ed6f4f10f1e15e37270d75832e88c9512512 /tool
parente5f688d5cebb10d039946aabee7306b03c80a138 (diff)
downloadruby-9d225cd2ad09a6fa7b778a592389bb9b515990e3.tar.gz
Add a tool for backporters.
* 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
Diffstat (limited to 'tool')
-rw-r--r--tool/generate-backport-changelog.rb99
1 files changed, 99 insertions, 0 deletions
diff --git a/tool/generate-backport-changelog.rb b/tool/generate-backport-changelog.rb
new file mode 100644
index 0000000000..435fd1cf63
--- /dev/null
+++ b/tool/generate-backport-changelog.rb
@@ -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 <eregontp@gmail.com>",
+ "kazu" => "Kazuhiro NISHIYAMA <zn@mbf.nifty.com>",
+ "ko1" => "Koichi Sasada <ko1@atdot.net>",
+ "marcandre" => "Marc-Andre Lafortune <ruby-core@marc-andre.ca>",
+ "naruse" => "NARUSE, Yui <naruse@ruby-lang.org>",
+ "nobu" => "Nobuyoshi Nakada <nobu@ruby-lang.org>",
+ "normal" => "Eric Wong <normalperson@yhbt.net>",
+ "rhe" => "Kazuki Yamaguchi <k@rhe.jp>",
+ "shugo" => "Shugo Maeda <shugo@ruby-lang.org>",
+ "stomar" => "Marcus Stollsteimer <sto.mar@web.de>",
+ "usa" => "NAKAMURA Usaku <usa@ruby-lang.org>",
+ "zzak" => "Zachary Scott <e@zzak.io>",
+}
+
+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