SvnRunner.run_svn should be a class method
This commit is contained in:
parent
50529580c0
commit
94c38ade8f
@ -4,87 +4,91 @@ module Svi
|
|||||||
# Exception class to indicate an error with executing svn.
|
# Exception class to indicate an error with executing svn.
|
||||||
class SvnExecError < RuntimeError; end
|
class SvnExecError < RuntimeError; end
|
||||||
|
|
||||||
# Run Subversion and yield results linewise.
|
class << self
|
||||||
#
|
|
||||||
# @param subcommand [String, nil]
|
|
||||||
# The svn subcommand to execute (e.g. "ls").
|
|
||||||
# @param args [Array<String>]
|
|
||||||
# The svn subcommand arguments.
|
|
||||||
# @param options [Hash]
|
|
||||||
# Optional arguments.
|
|
||||||
# @option options [Array<String>] :global_args
|
|
||||||
# Global svn arguments to place before the subcommand.
|
|
||||||
#
|
|
||||||
# @yield [line]
|
|
||||||
# If a block is given, each line that the Subversion command writes to
|
|
||||||
# standard output will be yielded to the calling block.
|
|
||||||
# @yieldparam line [String]
|
|
||||||
# Line of standard output.
|
|
||||||
# @return [String]
|
|
||||||
# The standard output from svn.
|
|
||||||
# @raise [SvnExecError]
|
|
||||||
# If the svn command errors out this exception is raised.
|
|
||||||
def run_svn(subcommand, args, options = {}, &block)
|
|
||||||
command = [
|
|
||||||
"svn",
|
|
||||||
*(options[:global_args] || []),
|
|
||||||
subcommand,
|
|
||||||
*args,
|
|
||||||
].compact
|
|
||||||
|
|
||||||
# Create pipes for standard output and standard error.
|
# Run Subversion and yield results linewise.
|
||||||
stdout_rd, stdout_wr = IO.pipe
|
#
|
||||||
stderr_rd, stderr_wr = IO.pipe
|
# @param subcommand [String, nil]
|
||||||
|
# The svn subcommand to execute (e.g. "ls").
|
||||||
|
# @param args [Array<String>]
|
||||||
|
# The svn subcommand arguments.
|
||||||
|
# @param options [Hash]
|
||||||
|
# Optional arguments.
|
||||||
|
# @option options [Array<String>] :global_args
|
||||||
|
# Global svn arguments to place before the subcommand.
|
||||||
|
#
|
||||||
|
# @yield [line]
|
||||||
|
# If a block is given, each line that the Subversion command writes to
|
||||||
|
# standard output will be yielded to the calling block.
|
||||||
|
# @yieldparam line [String]
|
||||||
|
# Line of standard output.
|
||||||
|
# @return [String]
|
||||||
|
# The standard output from svn.
|
||||||
|
# @raise [SvnExecError]
|
||||||
|
# If the svn command errors out this exception is raised.
|
||||||
|
def run_svn(subcommand, args, options = {}, &block)
|
||||||
|
command = [
|
||||||
|
"svn",
|
||||||
|
*(options[:global_args] || []),
|
||||||
|
subcommand,
|
||||||
|
*args,
|
||||||
|
].compact
|
||||||
|
|
||||||
# Launch the svn subprocess using the pipes.
|
# Create pipes for standard output and standard error.
|
||||||
spawn_options = {
|
stdout_rd, stdout_wr = IO.pipe
|
||||||
out: stdout_wr,
|
stderr_rd, stderr_wr = IO.pipe
|
||||||
err: stderr_wr,
|
|
||||||
close_others: true,
|
|
||||||
}
|
|
||||||
spawn_options[:in] = :close unless options[:allow_interactive]
|
|
||||||
svn_pid = Process.spawn(*command, spawn_options)
|
|
||||||
|
|
||||||
# Close write side of the pipes in the parent process.
|
# Launch the svn subprocess using the pipes.
|
||||||
stdout_wr.close
|
spawn_options = {
|
||||||
stderr_wr.close
|
out: stdout_wr,
|
||||||
|
err: stderr_wr,
|
||||||
|
close_others: true,
|
||||||
|
}
|
||||||
|
spawn_options[:in] = :close unless options[:allow_interactive]
|
||||||
|
svn_pid = Process.spawn(*command, spawn_options)
|
||||||
|
|
||||||
stdout = ""
|
# Close write side of the pipes in the parent process.
|
||||||
stderr = ""
|
stdout_wr.close
|
||||||
stdout_yield = ""
|
stderr_wr.close
|
||||||
|
|
||||||
loop do
|
stdout = ""
|
||||||
so = stdout_rd.read_nonblock(exception: false)
|
stderr = ""
|
||||||
if so.is_a?(String)
|
stdout_yield = ""
|
||||||
stdout += so
|
|
||||||
stdout_yield += so
|
loop do
|
||||||
end
|
so = stdout_rd.read_nonblock(100000, exception: false)
|
||||||
se = stderr_rd.read_nonblock(exception: false)
|
if so.is_a?(String)
|
||||||
if se.is_a?(String)
|
stdout += so
|
||||||
stderr += se
|
stdout_yield += so
|
||||||
end
|
|
||||||
if so.nil? and se.nil?
|
|
||||||
break
|
|
||||||
end
|
|
||||||
if block
|
|
||||||
loop do
|
|
||||||
index = stdout_yield.index("\n")
|
|
||||||
break unless index
|
|
||||||
line = stdout_yield[0, index]
|
|
||||||
block[line]
|
|
||||||
stdout_yield = stdout_yield[index + 1, stdout_yield.size]
|
|
||||||
end
|
end
|
||||||
|
se = stderr_rd.read_nonblock(100000, exception: false)
|
||||||
|
if se.is_a?(String)
|
||||||
|
stderr += se
|
||||||
|
end
|
||||||
|
if so.nil? and se.nil?
|
||||||
|
break
|
||||||
|
end
|
||||||
|
if block
|
||||||
|
loop do
|
||||||
|
index = stdout_yield.index("\n")
|
||||||
|
break unless index
|
||||||
|
line = stdout_yield[0, index]
|
||||||
|
block[line]
|
||||||
|
stdout_yield = stdout_yield[index + 1, stdout_yield.size]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
IO.select([stdout_rd, stderr_rd])
|
||||||
end
|
end
|
||||||
IO.select([stdout_rd, stderr_rd])
|
|
||||||
|
Process.waitpid(svn_pid)
|
||||||
|
|
||||||
|
if stderr != ""
|
||||||
|
raise SvnExecError.new(stderr)
|
||||||
|
end
|
||||||
|
|
||||||
|
stdout
|
||||||
end
|
end
|
||||||
|
|
||||||
Process.waitpid(svn_pid)
|
|
||||||
|
|
||||||
if stderr != ""
|
|
||||||
raise SvnExecError.new(stderr)
|
|
||||||
end
|
|
||||||
|
|
||||||
stdout
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user