class Datacenter::Shell::Local

Public Class Methods

new() click to toggle source
# File lib/datacenter/shell/local.rb, line 18
def initialize
  @mutex = Mutex.new
end
open(*args) { |shell| ... } click to toggle source
# File lib/datacenter/shell/local.rb, line 38
def self.open(*args)
  shell = new *args
  yield shell
end

Public Instance Methods

run(command, options={}) click to toggle source
# File lib/datacenter/shell/local.rb, line 22
def run(command, options={})
  Datacenter.logger.debug(self.class) { command }

  opts = {
    chdir: options[:chdir] || Dir.pwd,
    out: options[:out] || StringIO.new,
    err: options[:err] || StringIO.new
  }

  if RUBY_ENGINE == 'jruby' && JRUBY_VERSION < '9.0.0.0'
    run_system command, opts
  else
    run_open3 command, opts
  end
end

Private Instance Methods

run_open3(command, options) click to toggle source
# File lib/datacenter/shell/local.rb, line 45
def run_open3(command, options)
  status = nil
  result = nil
  error = nil

  begin
    Open3.popen3("#{command}", chdir: options[:chdir]) do |stdin, stdout, stderr, wait_thr|
      status = wait_thr.value
      result = stdout.read
      error = stderr.read

      options[:out] << result
      options[:err] << error
    end
  rescue => ex
    raise CommandError.new(command, ex.message)
  end

  raise CommandError.new(command, error) unless status.success?

  result
end
run_system(command, options) click to toggle source
# File lib/datacenter/shell/local.rb, line 68
def run_system(command, options)
  @mutex.synchronize do
    begin
      stdout = $stdout
      stderr = $stderr

      $stdout = SafeIO.new options[:out]
      $stderr = SafeIO.new options[:err]

      Dir.chdir(options[:chdir]) { system "#{command}" }

      status = $?

      $stdout.rewind
      $stderr.rewind
      
      result = $stdout.read.force_encoding('UTF-8')
      error = $stderr.read.force_encoding('UTF-8')

      raise CommandError.new(command, error) unless status.success?

      result

    ensure
      $stdout = stdout
      $stderr = stderr
    end
  end
end