mirror of
https://github.com/ruby/ruby.git
synced 2025-09-15 16:44:01 +02:00
Sync merger.rb and redmine-backporter.rb
This commit is contained in:
parent
a777087be6
commit
e96ba90fd6
2 changed files with 94 additions and 241 deletions
188
tool/merger.rb
188
tool/merger.rb
|
@ -2,9 +2,8 @@
|
|||
# -*- ruby -*-
|
||||
exec "${RUBY-ruby}" "-x" "$0" "$@" && [ ] if false
|
||||
#!ruby
|
||||
# This needs ruby 2.0, Subversion and Git.
|
||||
# As a Ruby committer, run this in an SVN repository
|
||||
# to commit a change.
|
||||
# This needs ruby 2.0 and Git.
|
||||
# As a Ruby committer, run this in a git repository to commit a change.
|
||||
|
||||
require 'tempfile'
|
||||
require 'net/http'
|
||||
|
@ -15,20 +14,11 @@ ENV['LC_ALL'] = 'C'
|
|||
ORIGIN = 'git@git.ruby-lang.org:ruby.git'
|
||||
GITHUB = 'git@github.com:ruby/ruby.git'
|
||||
|
||||
module Merger
|
||||
REPOS = 'svn+ssh://svn@ci.ruby-lang.org/ruby/'
|
||||
end
|
||||
|
||||
class << Merger
|
||||
include Merger
|
||||
|
||||
class << Merger = Object.new
|
||||
def help
|
||||
puts <<-HELP
|
||||
\e[1msimple backport\e[0m
|
||||
ruby #$0 1234
|
||||
|
||||
\e[1mbackport from other branch\e[0m
|
||||
ruby #$0 17502 mvm
|
||||
ruby #$0 1234abc
|
||||
|
||||
\e[1mrevision increment\e[0m
|
||||
ruby #$0 revisionup
|
||||
|
@ -37,16 +27,16 @@ class << Merger
|
|||
ruby #$0 teenyup
|
||||
|
||||
\e[1mtagging major release\e[0m
|
||||
ruby #$0 tag 2.2.0
|
||||
ruby #$0 tag 3.2.0
|
||||
|
||||
\e[1mtagging patch release\e[0m (about 2.1.0 or later, it means X.Y.Z (Z > 0) release)
|
||||
\e[1mtagging patch release\e[0m (for 2.1.0 or later, it means X.Y.Z (Z > 0) release)
|
||||
ruby #$0 tag
|
||||
|
||||
\e[1mtagging preview/RC\e[0m
|
||||
ruby #$0 tag 2.2.0-preview1
|
||||
ruby #$0 tag 3.2.0-preview1
|
||||
|
||||
\e[1mremove tag\e[0m
|
||||
ruby #$0 removetag 2.2.9
|
||||
ruby #$0 removetag 3.2.9
|
||||
|
||||
\e[33;1m* all operations shall be applied to the working directory.\e[0m
|
||||
HELP
|
||||
|
@ -57,11 +47,11 @@ class << Merger
|
|||
yield if block_given?
|
||||
STDERR.puts "\e[1;33m#{str} ([y]es|[a]bort|[r]etry#{'|[e]dit' if editfile})\e[0m"
|
||||
case STDIN.gets
|
||||
when /\Aa/i then exit
|
||||
when /\Aa/i then exit 1
|
||||
when /\Ar/i then redo
|
||||
when /\Ay/i then break
|
||||
when /\Ae/i then system(ENV['EDITOR'], editfile)
|
||||
else exit
|
||||
else exit 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -69,11 +59,7 @@ class << Merger
|
|||
def version_up(teeny: false)
|
||||
now = Time.now
|
||||
now = now.localtime(9*60*60) # server is Japan Standard Time +09:00
|
||||
if svn_mode?
|
||||
system('svn', 'revert', 'version.h')
|
||||
else
|
||||
system('git', 'checkout', 'HEAD', 'version.h')
|
||||
end
|
||||
system('git', 'checkout', 'HEAD', 'version.h')
|
||||
v, pl = version
|
||||
|
||||
if teeny
|
||||
|
@ -129,31 +115,10 @@ class << Merger
|
|||
end
|
||||
tagname = "v#{v.join('_')}#{("_#{pl}" if v[0] < "2" || (v[0] == "2" && v[1] < "1") || /^(?:preview|rc)/ =~ pl)}"
|
||||
|
||||
if svn_mode?
|
||||
if relname
|
||||
branch_url = `svn info`[/URL: (.*)/, 1]
|
||||
else
|
||||
branch_url = "#{REPOS}branches/ruby_"
|
||||
if v[0] < '2' || (v[0] == '2' && v[1] < '1')
|
||||
abort 'patchlevel must be greater than 0 for patch release' if pl == '0'
|
||||
branch_url << v.join('_')
|
||||
else
|
||||
abort 'teeny must be greater than 0 for patch release' if v[2] == '0'
|
||||
branch_url << v.join('_').sub(/_\d+\z/, '')
|
||||
end
|
||||
end
|
||||
tag_url = "#{REPOS}tags/#{tagname}"
|
||||
system('svn', 'info', tag_url, out: IO::NULL, err: IO::NULL)
|
||||
if $?.success?
|
||||
abort 'specfied tag already exists. check tag name and remove it if you want to force re-tagging'
|
||||
end
|
||||
execute('svn', 'cp', '-m', "add tag #{tagname}", branch_url, tag_url, interactive: true)
|
||||
else
|
||||
unless execute('git', 'tag', tagname)
|
||||
abort 'specfied tag already exists. check tag name and remove it if you want to force re-tagging'
|
||||
end
|
||||
execute('git', 'push', ORIGIN, tagname, interactive: true)
|
||||
unless execute('git', 'tag', tagname)
|
||||
abort 'specfied tag already exists. check tag name and remove it if you want to force re-tagging'
|
||||
end
|
||||
execute('git', 'push', ORIGIN, tagname, interactive: true)
|
||||
end
|
||||
|
||||
def remove_tag(relname)
|
||||
|
@ -173,64 +138,44 @@ class << Merger
|
|||
tagname = relname
|
||||
end
|
||||
|
||||
if svn_mode?
|
||||
tag_url = "#{REPOS}tags/#{tagname}"
|
||||
execute('svn', 'rm', '-m', "remove tag #{tagname}", tag_url, interactive: true)
|
||||
else
|
||||
execute('git', 'tag', '-d', tagname)
|
||||
execute('git', 'push', ORIGIN, ":#{tagname}", interactive: true)
|
||||
execute('git', 'push', GITHUB, ":#{tagname}", interactive: true)
|
||||
end
|
||||
execute('git', 'tag', '-d', tagname)
|
||||
execute('git', 'push', ORIGIN, ":#{tagname}", interactive: true)
|
||||
execute('git', 'push', GITHUB, ":#{tagname}", interactive: true)
|
||||
end
|
||||
|
||||
def update_revision_h
|
||||
if svn_mode?
|
||||
execute('svn', 'up')
|
||||
end
|
||||
execute('ruby tool/file2lastrev.rb --revision.h . > revision.tmp')
|
||||
execute('tool/ifchange', '--timestamp=.revision.time', 'revision.h', 'revision.tmp')
|
||||
execute('rm', '-f', 'revision.tmp')
|
||||
end
|
||||
|
||||
def stat
|
||||
if svn_mode?
|
||||
`svn stat`
|
||||
else
|
||||
`git status --short`
|
||||
end
|
||||
`git status --short`
|
||||
end
|
||||
|
||||
def diff(file = nil)
|
||||
if svn_mode?
|
||||
command = %w[svn diff --diff-cmd=diff -x -upw]
|
||||
else
|
||||
command = %w[git diff --color]
|
||||
end
|
||||
command = %w[git diff --color HEAD]
|
||||
IO.popen(command + [file].compact, &:read)
|
||||
end
|
||||
|
||||
def commit(file)
|
||||
if svn_mode?
|
||||
begin
|
||||
execute('svn', 'ci', '-F', file)
|
||||
execute('svn', 'update') # svn ci doesn't update revision info on working copy
|
||||
ensure
|
||||
execute('rm', '-f', 'subversion.commitlog')
|
||||
end
|
||||
else
|
||||
current_branch = IO.popen(['git', 'rev-parse', '--abbrev-ref', 'HEAD'], &:read).strip
|
||||
execute('git', 'add', '.') &&
|
||||
execute('git', 'commit', '-F', file)
|
||||
end
|
||||
current_branch = IO.popen(['git', 'rev-parse', '--abbrev-ref', 'HEAD'], &:read).strip
|
||||
execute('git', 'add', '.') && execute('git', 'commit', '-F', file)
|
||||
end
|
||||
|
||||
def has_conflicts?
|
||||
changes = IO.popen(%w[git status --porcelain -z]) { |io| io.readlines("\0", chomp: true) }
|
||||
# Discover unmerged files
|
||||
# AU: unmerged, added by us
|
||||
# DU: unmerged, deleted by us
|
||||
# UU: unmerged, both modified
|
||||
# AA: unmerged, both added
|
||||
conflict = changes.grep(/\A(?:.U|AA) /) {$'}
|
||||
!conflict.empty?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def svn_mode?
|
||||
return @svn_mode if defined?(@svn_mode)
|
||||
@svn_mode = system("svn info", %i(out err) => IO::NULL)
|
||||
end
|
||||
|
||||
# Prints the version of Ruby found in version.h
|
||||
def version
|
||||
v = p = nil
|
||||
|
@ -289,21 +234,21 @@ else
|
|||
|
||||
case ARGV[0]
|
||||
when /--ticket=(.*)/
|
||||
tickets = $1.split(/,/).map{|num| " [Backport ##{num}]"}.join
|
||||
tickets = $1.split(/,/)
|
||||
ARGV.shift
|
||||
else
|
||||
tickets = ''
|
||||
tickets = []
|
||||
detect_ticket = true
|
||||
end
|
||||
|
||||
revstr = ARGV[0].delete('^, :\-0-9a-fA-F')
|
||||
revstr = ARGV[0].gsub(%r!https://github\.com/ruby/ruby/commit/|https://bugs\.ruby-lang\.org/projects/ruby-master/repository/git/revisions/!, '')
|
||||
revstr = revstr.delete('^, :\-0-9a-fA-F')
|
||||
revs = revstr.split(/[,\s]+/)
|
||||
commit_message = ''
|
||||
|
||||
revs.each do |rev|
|
||||
git_rev = nil
|
||||
case rev
|
||||
when /\A\d{1,6}\z/
|
||||
svn_rev = rev
|
||||
when /\A\h{7,40}\z/
|
||||
git_rev = rev
|
||||
when nil then
|
||||
|
@ -314,27 +259,24 @@ else
|
|||
exit
|
||||
end
|
||||
|
||||
# Merge revision from Git patch or SVN
|
||||
if git_rev
|
||||
git_uri = "https://git.ruby-lang.org/ruby.git/patch/?id=#{git_rev}"
|
||||
resp = Net::HTTP.get_response(URI(git_uri))
|
||||
if resp.code != '200'
|
||||
abort "'#{git_uri}' returned status '#{resp.code}':\n#{resp.body}"
|
||||
end
|
||||
patch = resp.body.sub(/^diff --git a\/version\.h b\/version\.h\nindex .*\n--- a\/version\.h\n\+\+\+ b\/version\.h\n@@ .* @@\n(?:[-\+ ].*\n|\n)+/, '')
|
||||
|
||||
message = "\n\n#{(patch[/^Subject: (.*)\n\ndiff --git/m, 1] || "Message not found for revision: #{git_rev}\n")}"
|
||||
puts '+ git apply'
|
||||
IO.popen(['git', 'apply'], 'wb') { |f| f.write(patch) }
|
||||
else
|
||||
default_merge_branch = (%r{^URL: .*/branches/ruby_1_8_} =~ `svn info` ? 'branches/ruby_1_8' : 'trunk')
|
||||
svn_src = "#{Merger::REPOS}#{ARGV[1] || default_merge_branch}"
|
||||
message = IO.popen(['svn', 'log', '-c', svn_rev, svn_src], &:read)
|
||||
|
||||
cmd = ['svn', 'merge', '--accept=postpone', '-c', svn_rev, svn_src]
|
||||
puts "+ #{cmd.join(' ')}"
|
||||
system(*cmd)
|
||||
# Merge revision from Git patch
|
||||
git_uri = "https://git.ruby-lang.org/ruby.git/patch/?id=#{git_rev}"
|
||||
resp = Net::HTTP.get_response(URI(git_uri))
|
||||
if resp.code != '200'
|
||||
abort "'#{git_uri}' returned status '#{resp.code}':\n#{resp.body}"
|
||||
end
|
||||
patch = resp.body.sub(/^diff --git a\/version\.h b\/version\.h\nindex .*\n--- a\/version\.h\n\+\+\+ b\/version\.h\n@@ .* @@\n(?:[-\+ ].*\n|\n)+/, '')
|
||||
|
||||
if detect_ticket
|
||||
tickets += patch.scan(/\[(?:Bug|Feature|Misc) #(\d+)\]/i).map(&:first)
|
||||
end
|
||||
|
||||
message = "#{(patch[/^Subject: (.*)\n---\n /m, 1] || "Message not found for revision: #{git_rev}\n")}"
|
||||
message.gsub!(/\G(.*)\n( .*)/, "\\1\\2")
|
||||
message = "\n\n#{message}"
|
||||
|
||||
puts '+ git apply'
|
||||
IO.popen(['git', 'apply', '--3way'], 'wb') { |f| f.write(patch) }
|
||||
|
||||
commit_message << message.sub(/\A-+\nr.*/, '').sub(/\n-+\n\z/, '').gsub(/^./, "\t\\&")
|
||||
end
|
||||
|
@ -345,20 +287,22 @@ else
|
|||
|
||||
Merger.version_up
|
||||
f = Tempfile.new 'merger.rb'
|
||||
f.printf "merge revision(s) %s:%s", revstr, tickets
|
||||
f.printf "merge revision(s) %s:%s", revstr, tickets.map{|num| " [Backport ##{num}]"}.join
|
||||
f.write commit_message
|
||||
f.flush
|
||||
f.close
|
||||
|
||||
Merger.interactive('conflicts resolved?', f.path) do
|
||||
IO.popen(ENV['PAGER'] || ['less', '-R'], 'w') do |g|
|
||||
g << Merger.stat
|
||||
g << "\n\n"
|
||||
f.open
|
||||
g << f.read
|
||||
f.close
|
||||
g << "\n\n"
|
||||
g << Merger.diff
|
||||
if Merger.has_conflicts?
|
||||
Merger.interactive('conflicts resolved?', f.path) do
|
||||
IO.popen(ENV['PAGER'] || ['less', '-R'], 'w') do |g|
|
||||
g << Merger.stat
|
||||
g << "\n\n"
|
||||
f.open
|
||||
g << f.read
|
||||
f.close
|
||||
g << "\n\n"
|
||||
g << Merger.diff
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -10,13 +10,7 @@ require 'optparse'
|
|||
require 'abbrev'
|
||||
require 'pp'
|
||||
require 'shellwords'
|
||||
begin
|
||||
require 'readline'
|
||||
rescue LoadError
|
||||
module Readline; end
|
||||
end
|
||||
|
||||
VERSION = '0.0.1'
|
||||
require 'reline'
|
||||
|
||||
opts = OptionParser.new
|
||||
target_version = nil
|
||||
|
@ -24,10 +18,9 @@ repo_path = nil
|
|||
api_key = nil
|
||||
ssl_verify = true
|
||||
opts.on('-k REDMINE_API_KEY', '--key=REDMINE_API_KEY', 'specify your REDMINE_API_KEY') {|v| api_key = v}
|
||||
opts.on('-t TARGET_VERSION', '--target=TARGET_VARSION', /\A\d(?:\.\d)+\z/, 'specify target version (ex: 2.1)') {|v| target_version = v}
|
||||
opts.on('-t TARGET_VERSION', '--target=TARGET_VARSION', /\A\d(?:\.\d)+\z/, 'specify target version (ex: 3.1)') {|v| target_version = v}
|
||||
opts.on('-r RUBY_REPO_PATH', '--repository=RUBY_REPO_PATH', 'specify repository path') {|v| repo_path = v}
|
||||
opts.on('--[no-]ssl-verify', TrueClass, 'use / not use SSL verify') {|v| ssl_verify = v}
|
||||
opts.version = VERSION
|
||||
opts.parse!(ARGV)
|
||||
|
||||
http_options = {use_ssl: true}
|
||||
|
@ -35,17 +28,17 @@ http_options[:verify_mode] = OpenSSL::SSL::VERIFY_NONE unless ssl_verify
|
|||
$openuri_options = {}
|
||||
$openuri_options[:ssl_verify_mode] = OpenSSL::SSL::VERIFY_NONE unless ssl_verify
|
||||
|
||||
TARGET_VERSION = target_version || ENV['TARGET_VERSION'] || (raise 'need to specify TARGET_VERSION')
|
||||
TARGET_VERSION = target_version || ENV['TARGET_VERSION'] || (puts opts.help; raise 'need to specify TARGET_VERSION')
|
||||
RUBY_REPO_PATH = repo_path || ENV['RUBY_REPO_PATH']
|
||||
BACKPORT_CF_KEY = 'cf_5'
|
||||
STATUS_CLOSE = 5
|
||||
REDMINE_API_KEY = api_key || ENV['REDMINE_API_KEY'] || (raise 'need to specify REDMINE_API_KEY')
|
||||
REDMINE_API_KEY = api_key || ENV['REDMINE_API_KEY'] || (puts opts.help; raise 'need to specify REDMINE_API_KEY')
|
||||
REDMINE_BASE = 'https://bugs.ruby-lang.org'
|
||||
|
||||
@query = {
|
||||
'f[]' => BACKPORT_CF_KEY,
|
||||
"op[#{BACKPORT_CF_KEY}]" => '~',
|
||||
"v[#{BACKPORT_CF_KEY}][]" => "#{TARGET_VERSION}: REQUIRED",
|
||||
"v[#{BACKPORT_CF_KEY}][]" => "\"#{TARGET_VERSION}: REQUIRED\"",
|
||||
'limit' => 40,
|
||||
'status_id' => STATUS_CLOSE,
|
||||
'sort' => 'updated_on'
|
||||
|
@ -70,28 +63,28 @@ COLORS = {
|
|||
}
|
||||
|
||||
class String
|
||||
def color(fore=nil, back=nil, bold: false, underscore: false)
|
||||
def color(fore=nil, back=nil, opts={}, bold: false, underscore: false)
|
||||
seq = ""
|
||||
if bold
|
||||
seq << "\e[1m"
|
||||
if bold || opts[:bold]
|
||||
seq = seq + "\e[1m"
|
||||
end
|
||||
if underscore
|
||||
seq << "\e[2m"
|
||||
if underscore || opts[:underscore]
|
||||
seq = seq + "\e[2m"
|
||||
end
|
||||
if fore
|
||||
c = COLORS[fore]
|
||||
raise "unknown foreground color #{fore}" unless c
|
||||
seq << "\e[#{c}m"
|
||||
seq = seq + "\e[#{c}m"
|
||||
end
|
||||
if back
|
||||
c = COLORS[back]
|
||||
raise "unknown background color #{back}" unless c
|
||||
seq << "\e[#{c + 10}m"
|
||||
seq = seq + "\e[#{c + 10}m"
|
||||
end
|
||||
if seq.empty?
|
||||
self
|
||||
else
|
||||
seq << self << "\e[0m"
|
||||
seq = seq + self + "\e[0m"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -162,84 +155,6 @@ def more(sio)
|
|||
end
|
||||
end
|
||||
|
||||
class << Readline
|
||||
def readline(prompt = '')
|
||||
console = IO.console
|
||||
console.binmode
|
||||
_, lx = console.winsize
|
||||
if /mswin|mingw/ =~ RUBY_PLATFORM or /^(?:vt\d\d\d|xterm)/i =~ ENV["TERM"]
|
||||
cls = "\r\e[2K"
|
||||
else
|
||||
cls = "\r" << (" " * lx)
|
||||
end
|
||||
cls << "\r" << prompt
|
||||
console.print prompt
|
||||
console.flush
|
||||
line = ''
|
||||
while true
|
||||
case c = console.getch
|
||||
when "\r", "\n"
|
||||
puts
|
||||
HISTORY << line
|
||||
return line
|
||||
when "\C-?", "\b" # DEL/BS
|
||||
print "\b \b" if line.chop!
|
||||
when "\C-u"
|
||||
print cls
|
||||
line.clear
|
||||
when "\C-d"
|
||||
return nil if line.empty?
|
||||
line << c
|
||||
when "\C-p"
|
||||
HISTORY.pos -= 1
|
||||
line = HISTORY.current
|
||||
print cls
|
||||
print line
|
||||
when "\C-n"
|
||||
HISTORY.pos += 1
|
||||
line = HISTORY.current
|
||||
print cls
|
||||
print line
|
||||
else
|
||||
if c >= " "
|
||||
print c
|
||||
line << c
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
HISTORY = []
|
||||
def HISTORY.<<(val)
|
||||
HISTORY.push(val)
|
||||
@pos = self.size
|
||||
self
|
||||
end
|
||||
def HISTORY.pos
|
||||
@pos ||= 0
|
||||
end
|
||||
def HISTORY.pos=(val)
|
||||
@pos = val
|
||||
if @pos < 0
|
||||
@pos = -1
|
||||
elsif @pos >= self.size
|
||||
@pos = self.size
|
||||
end
|
||||
end
|
||||
def HISTORY.current
|
||||
@pos ||= 0
|
||||
if @pos < 0 || @pos >= self.size
|
||||
''
|
||||
else
|
||||
self[@pos]
|
||||
end
|
||||
end
|
||||
end unless defined?(Readline.readline)
|
||||
|
||||
def find_svn_log(pattern)
|
||||
`svn log --xml --stop-on-copy --search="#{pattern}" #{RUBY_REPO_PATH}`
|
||||
end
|
||||
|
||||
def find_git_log(pattern)
|
||||
`git #{RUBY_REPO_PATH ? "-C #{RUBY_REPO_PATH.shellescape}" : ""} log --grep="#{pattern}"`
|
||||
end
|
||||
|
@ -276,10 +191,12 @@ def backport_command_string
|
|||
|
||||
# check if the Git revision is included in master
|
||||
has_commit(c, "master")
|
||||
end.sort_by do |changeset|
|
||||
Integer(IO.popen(%W[git show -s --format=%ct #{changeset}], &:read))
|
||||
end
|
||||
@changesets.define_singleton_method(:validated){true}
|
||||
end
|
||||
" #{merger_path} --ticket=#{@issue} #{@changesets.sort.join(',')}"
|
||||
"#{merger_path} --ticket=#{@issue} #{@changesets.join(',')}"
|
||||
end
|
||||
|
||||
def status_char(obj)
|
||||
|
@ -294,7 +211,7 @@ end
|
|||
console = IO.console
|
||||
row, = console.winsize
|
||||
@query['limit'] = row - 2
|
||||
puts "Backporter #{VERSION}".color(bold: true) + " for #{TARGET_VERSION}"
|
||||
puts "Redmine Backporter".color(bold: true) + " for Ruby #{TARGET_VERSION}"
|
||||
|
||||
class CommandSyntaxError < RuntimeError; end
|
||||
commands = {
|
||||
|
@ -306,10 +223,11 @@ commands = {
|
|||
@issues = issues = res["issues"]
|
||||
from = res["offset"] + 1
|
||||
total = res["total_count"]
|
||||
closed = issues.count { |x, _| x["status"]["name"] == "Closed" }
|
||||
to = from + issues.size - 1
|
||||
puts "#{from}-#{to} / #{total}"
|
||||
puts "#{from}-#{to} / #{total} (closed: #{closed})"
|
||||
issues.each_with_index do |x, i|
|
||||
id = "##{x["id"]}".color(*PRIORITIES[x["priority"]["name"]])
|
||||
id = "##{x["id"]}".color(*PRIORITIES[x["priority"]["name"]], bold: x["status"]["name"] == "Closed")
|
||||
puts "#{'%2d' % i} #{id} #{x["priority"]["name"][0]} #{status_char(x["status"])} #{x["subject"][0,80]}"
|
||||
end
|
||||
},
|
||||
|
@ -376,9 +294,6 @@ eom
|
|||
"rel" => proc{|args|
|
||||
# this feature requires custom redmine which allows add_related_issue API
|
||||
case args
|
||||
when /\Ar?(\d+)\z/ # SVN
|
||||
rev = $1
|
||||
uri = URI("#{REDMINE_BASE}/projects/ruby-master/repository/trunk/revisions/#{rev}/issues.json")
|
||||
when /\A\h{7,40}\z/ # Git
|
||||
rev = args
|
||||
uri = URI("#{REDMINE_BASE}/projects/ruby-master/repository/git/revisions/#{rev}/issues.json")
|
||||
|
@ -422,7 +337,7 @@ eom
|
|||
},
|
||||
|
||||
"done" => proc{|args|
|
||||
raise CommandSyntaxError unless /\A(\d+)?(?: by (\h+))?(?:\s*-- +(.*))?\z/ =~ args
|
||||
raise CommandSyntaxError unless /\A(\d+)?(?: *by (\h+))?(?:\s*-- +(.*))?\z/ =~ args
|
||||
notes = $3
|
||||
notes.strip! if notes
|
||||
rev = $2
|
||||
|
@ -436,23 +351,17 @@ eom
|
|||
next
|
||||
end
|
||||
|
||||
if rev
|
||||
elsif system("svn info #{RUBY_REPO_PATH&.shellescape}", %i(out err) => IO::NULL) # SVN
|
||||
if (log = find_svn_log("##@issue]")) && (/revision="(?<rev>\d+)/ =~ log)
|
||||
rev = "r#{rev}"
|
||||
end
|
||||
else # Git
|
||||
if log = find_git_log("##@issue]")
|
||||
/^commit (?<rev>\h{40})$/ =~ log
|
||||
end
|
||||
if rev.nil? && log = find_git_log("##@issue]")
|
||||
/^commit (?<rev>\h{40})$/ =~ log
|
||||
end
|
||||
if log && rev
|
||||
str = log[/merge revision\(s\) ([^:]+)(?=:)/]
|
||||
if str
|
||||
str.insert(5, "d")
|
||||
str = "ruby_#{TARGET_VERSION.tr('.','_')} #{rev} #{str}."
|
||||
str.sub!(/\Amerge/, 'merged')
|
||||
str.gsub!(/\h{40}/, 'commit:\0')
|
||||
str = "ruby_#{TARGET_VERSION.tr('.','_')} commit:#{rev} #{str}."
|
||||
else
|
||||
str = "ruby_#{TARGET_VERSION.tr('.','_')} #{rev}."
|
||||
str = "ruby_#{TARGET_VERSION.tr('.','_')} commit:#{rev}."
|
||||
end
|
||||
if notes
|
||||
str << "\n"
|
||||
|
@ -571,7 +480,7 @@ list = Abbrev.abbrev(commands.keys)
|
|||
@changesets = nil
|
||||
while true
|
||||
begin
|
||||
l = Readline.readline "#{('#' + @issue.to_s).color(bold: true) if @issue}> "
|
||||
l = Reline.readline "#{('#' + @issue.to_s).color(bold: true) if @issue}> "
|
||||
rescue Interrupt
|
||||
break
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue