зеркало из https://github.com/github/ruby.git
vcs.rb: split
* tool/vcs.rb: split from file2lastrev.rb. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43609 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
671707b546
Коммит
ae6f7929bd
|
@ -1,110 +1,10 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
ENV.delete('PWD')
|
||||
|
||||
require 'optparse'
|
||||
|
||||
unless File.respond_to? :realpath
|
||||
require 'pathname'
|
||||
def File.realpath(arg)
|
||||
Pathname(arg).realpath.to_s
|
||||
end
|
||||
end
|
||||
require File.expand_path('../vcs', __FILE__)
|
||||
|
||||
Program = $0
|
||||
|
||||
class VCS
|
||||
class NotFoundError < RuntimeError; end
|
||||
|
||||
@@dirs = []
|
||||
def self.register(dir)
|
||||
@@dirs << [dir, self]
|
||||
end
|
||||
|
||||
def self.detect(path)
|
||||
@@dirs.each do |dir, klass|
|
||||
return klass.new(path) if File.directory?(File.join(path, dir))
|
||||
prev = path
|
||||
loop {
|
||||
curr = File.realpath(File.join(prev, '..'))
|
||||
break if curr == prev # stop at the root directory
|
||||
return klass.new(path) if File.directory?(File.join(curr, dir))
|
||||
prev = curr
|
||||
}
|
||||
end
|
||||
raise VCS::NotFoundError, "does not seem to be under a vcs: #{path}"
|
||||
end
|
||||
|
||||
def initialize(path)
|
||||
@srcdir = path
|
||||
super()
|
||||
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, *rest = Dir.chdir(@srcdir) {self.class.get_revisions(path)}
|
||||
last or raise "last revision not found"
|
||||
changed or raise "changed revision not found"
|
||||
return last, changed, *rest
|
||||
end
|
||||
|
||||
def relative_to(path)
|
||||
if path
|
||||
srcdir = File.realpath(@srcdir)
|
||||
path = File.realpath(path)
|
||||
list1 = srcdir.split(%r{/})
|
||||
list2 = path.split(%r{/})
|
||||
while !list1.empty? && !list2.empty? && list1.first == list2.first
|
||||
list1.shift
|
||||
list2.shift
|
||||
end
|
||||
if list1.empty? && list2.empty?
|
||||
"."
|
||||
else
|
||||
([".."] * list1.length + list2).join("/")
|
||||
end
|
||||
else
|
||||
'.'
|
||||
end
|
||||
end
|
||||
|
||||
class SVN < self
|
||||
register(".svn")
|
||||
|
||||
def self.get_revisions(path)
|
||||
begin
|
||||
nulldevice = %w[/dev/null NUL NIL: NL:].find {|dev| File.exist?(dev)}
|
||||
if nulldevice
|
||||
save_stderr = STDERR.dup
|
||||
STDERR.reopen nulldevice, 'w'
|
||||
end
|
||||
info_xml = `svn info --xml "#{path}"`
|
||||
ensure
|
||||
if save_stderr
|
||||
STDERR.reopen save_stderr
|
||||
save_stderr.close
|
||||
end
|
||||
end
|
||||
_, last, _, changed, _ = info_xml.split(/revision="(\d+)"/)
|
||||
[last, changed]
|
||||
end
|
||||
end
|
||||
|
||||
class GIT < self
|
||||
register(".git")
|
||||
|
||||
def self.get_revisions(path)
|
||||
logcmd = %Q[git log -n1 --grep="^ *git-svn-id: .*@[0-9][0-9]* "]
|
||||
idpat = /git-svn-id: .*?@(\d+) \S+\Z/
|
||||
last = `#{logcmd}`[idpat, 1]
|
||||
changed = path ? `#{logcmd} "#{path}"`[idpat, 1] : last
|
||||
[last, changed]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@output = nil
|
||||
def self.output=(output)
|
||||
if @output and @output != output
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
# vcs
|
||||
|
||||
ENV.delete('PWD')
|
||||
|
||||
unless File.respond_to? :realpath
|
||||
require 'pathname'
|
||||
def File.realpath(arg)
|
||||
Pathname(arg).realpath.to_s
|
||||
end
|
||||
end
|
||||
|
||||
class VCS
|
||||
class NotFoundError < RuntimeError; end
|
||||
|
||||
@@dirs = []
|
||||
def self.register(dir)
|
||||
@@dirs << [dir, self]
|
||||
end
|
||||
|
||||
def self.detect(path)
|
||||
@@dirs.each do |dir, klass|
|
||||
return klass.new(path) if File.directory?(File.join(path, dir))
|
||||
prev = path
|
||||
loop {
|
||||
curr = File.realpath(File.join(prev, '..'))
|
||||
break if curr == prev # stop at the root directory
|
||||
return klass.new(path) if File.directory?(File.join(curr, dir))
|
||||
prev = curr
|
||||
}
|
||||
end
|
||||
raise VCS::NotFoundError, "does not seem to be under a vcs: #{path}"
|
||||
end
|
||||
|
||||
def initialize(path)
|
||||
@srcdir = path
|
||||
super()
|
||||
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, *rest = Dir.chdir(@srcdir) {self.class.get_revisions(path)}
|
||||
last or raise "last revision not found"
|
||||
changed or raise "changed revision not found"
|
||||
return last, changed, *rest
|
||||
end
|
||||
|
||||
def relative_to(path)
|
||||
if path
|
||||
srcdir = File.realpath(@srcdir)
|
||||
path = File.realpath(path)
|
||||
list1 = srcdir.split(%r{/})
|
||||
list2 = path.split(%r{/})
|
||||
while !list1.empty? && !list2.empty? && list1.first == list2.first
|
||||
list1.shift
|
||||
list2.shift
|
||||
end
|
||||
if list1.empty? && list2.empty?
|
||||
"."
|
||||
else
|
||||
([".."] * list1.length + list2).join("/")
|
||||
end
|
||||
else
|
||||
'.'
|
||||
end
|
||||
end
|
||||
|
||||
class SVN < self
|
||||
register(".svn")
|
||||
|
||||
def self.get_revisions(path)
|
||||
begin
|
||||
nulldevice = %w[/dev/null NUL NIL: NL:].find {|dev| File.exist?(dev)}
|
||||
if nulldevice
|
||||
save_stderr = STDERR.dup
|
||||
STDERR.reopen nulldevice, 'w'
|
||||
end
|
||||
info_xml = `svn info --xml "#{path}"`
|
||||
ensure
|
||||
if save_stderr
|
||||
STDERR.reopen save_stderr
|
||||
save_stderr.close
|
||||
end
|
||||
end
|
||||
_, last, _, changed, _ = info_xml.split(/revision="(\d+)"/)
|
||||
[last, changed]
|
||||
end
|
||||
end
|
||||
|
||||
class GIT < self
|
||||
register(".git")
|
||||
|
||||
def self.get_revisions(path)
|
||||
logcmd = %Q[git log -n1 --grep="^ *git-svn-id: .*@[0-9][0-9]* "]
|
||||
idpat = /git-svn-id: .*?@(\d+) \S+\Z/
|
||||
last = `#{logcmd}`[idpat, 1]
|
||||
changed = path ? `#{logcmd} "#{path}"`[idpat, 1] : last
|
||||
[last, changed]
|
||||
end
|
||||
end
|
||||
end
|
Загрузка…
Ссылка в новой задаче