summaryrefslogtreecommitdiff
path: root/tool/file2lastrev.rb
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-03-13 08:48:49 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-03-13 08:48:49 +0000
commit0e9620fd38d9bad8f0857e2ac031bf7b9f50a72d (patch)
tree0332f21950f301756657cfe0ed58230a2262e5ce /tool/file2lastrev.rb
parent05d4516145a19e2950c53cf39dd95f64f36cedae (diff)
* tool/file2lastrev.rb: refactord. fixed changed revision of git.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@26908 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'tool/file2lastrev.rb')
-rwxr-xr-xtool/file2lastrev.rb116
1 files changed, 76 insertions, 40 deletions
diff --git a/tool/file2lastrev.rb b/tool/file2lastrev.rb
index e913783..66a13b4 100755
--- a/tool/file2lastrev.rb
+++ b/tool/file2lastrev.rb
@@ -5,47 +5,77 @@ ENV.delete('PWD')
require 'optparse'
require 'pathname'
-SRCDIR = Pathname(File.dirname($0)).parent.freeze
-class VCSNotFoundError < RuntimeError; end
-
-def detect_vcs(path)
- path = SRCDIR
- return :svn, path.relative_path_from(SRCDIR) if File.directory?("#{path}/.svn")
- return :git_svn, path.relative_path_from(SRCDIR) if File.directory?("#{path}/.git/svn")
- return :git, path.relative_path_from(SRCDIR) if File.directory?("#{path}/.git")
- raise VCSNotFoundError, "does not seem to be under a vcs"
-end
+Program = Pathname($0)
+
+class VCS
+ class NotFoundError < RuntimeError; end
-# return a pair of strings, the last revision and the last revision in which
-# +path+ was modified.
-def get_revisions(path)
- vcs, path = detect_vcs(path)
+ @@dirs = []
+ def self.register(dir)
+ @@dirs << [dir, self]
+ end
+
+ def self.detect(path)
+ @@dirs.sort.reverse_each do |dir, klass|
+ return klass.new(path) if File.directory?("#{path}/#{dir}")
+ end
+ raise VCS::NotFoundError, "does not seem to be under a vcs: #{path}"
+ end
- info = case vcs
- when :svn
- info_xml = `cd "#{SRCDIR}" && svn info --xml "#{path}"`
- _, last, _, changed, _ = info_xml.split(/revision="(\d+)"/)
+ def initialize(path)
+ @srcdir = path
+ end
+
+ # return a pair of strings, the last revision and the last revision in which
+ # +path+ was modified.
+ def get_revisions(path)
+ path = relative_to(path)
+ last, changed = Dir.chdir(@srcdir) {yield path}
+ last or raise "last revision not found"
+ changed or raise "changed revision not found"
return last, changed
- when :git_svn
- `cd "#{SRCDIR}" && git svn info "#{path}"`
- when :git
- git_log = `cd "#{SRCDIR}" && git log HEAD~1..HEAD "#{path}"`
- git_log =~ /git-svn-id: .*?@(\d+)/
- return $1, $1
end
- if /^Revision: (\d+)/ =~ info
- last = $1
- else
- raise "last revision not found"
+ def relative_to(path)
+ path ? Pathname(path).relative_path_from(@srcdir) : '.'
end
- if /^Last Changed Rev: (\d+)/ =~ info
- changed = $1
- else
- raise "changed revision not found"
+
+ class SVN < self
+ register(".svn")
+
+ def get_revisions(path)
+ super do
+ info_xml = `svn info --xml "#{path}"`
+ _, last, _, changed, _ = info_xml.split(/revision="(\d+)"/)
+ [last, changed]
+ end
+ end
end
- return last, changed
+ class GIT_SVN < self
+ register(".git/svn")
+
+ def get_revisions(path)
+ super do
+ info = `git svn info "#{path}"`
+ [info[/^Revision: (\d+)/, 1], info[/^Last Changed Rev: (\d+)/, 1]]
+ end
+ end
+ end
+
+ class GIT < self
+ register(".git")
+
+ def get_revisions(path)
+ logcmd = %Q[git log -n1 --grep='^ *git-svn-id: .*@[0-9][0-9]* ']
+ idpat = /git-svn-id: .*?@(\d+) \S+\Z/
+ super do
+ last = `#{logcmd}`[idpat, 1]
+ changed = path ? `#{logcmd} "#{path}"`[idpat, 1] : last
+ [last, changed]
+ end
+ end
+ end
end
@output = nil
@@ -57,27 +87,33 @@ def self.output=(output)
end
@suppress_not_found = false
+srcdir = nil
parser = OptionParser.new {|opts|
+ opts.on("--srcdir=PATH", "use PATH as source directory") do |path|
+ srcdir = path
+ end
opts.on("--changed", "changed rev") do
self.output = :changed
end
- opts.on("--revision.h") do
+ opts.on("--revision.h", "RUBY_REVISION macro") do
self.output = :revision_h
end
- opts.on("--doxygen") do
+ opts.on("--doxygen", "Doxygen format") do
self.output = :doxygen
end
opts.on("-q", "--suppress_not_found") do
@suppress_not_found = true
end
}
-parser.parse!
-
+parser.parse! rescue abort "#{Program.basename}: #{$!}\n#{parser}"
+srcdir = (srcdir ? Pathname(srcdir) : Program.parent.parent).freeze
begin
- last, changed = get_revisions(ARGV.shift)
-rescue VCSNotFoundError
- raise unless @suppress_not_found
+ vcs = VCS.detect(srcdir)
+rescue VCS::NotFoundError => e
+ abort "#{Program.basename}: #{e.message}" unless @suppress_not_found
+else
+ last, changed = vcs.get_revisions(ARGV.shift)
end
case @output