class Komenda::Process

Attributes

output[R]

Public Class Methods

new(process_builder) click to toggle source

@param [ProcessBuilder] process_builder

# File lib/komenda/process.rb, line 8
def initialize(process_builder)
  @process_builder = process_builder
  @output = { stdout: '', stderr: '', combined: '' }
  @exit_status = @thread = @pid = nil

  on(:stdout) { |data| @output[:stdout] += data }
  on(:stderr) { |data| @output[:stderr] += data }
  on(:output) { |data| @output[:combined] += data }
  process_builder.events.each do |event|
    on(event[:type], &event[:listener])
  end
end

Public Instance Methods

kill(signal = 'TERM') click to toggle source

@param [Integer, String]

# File lib/komenda/process.rb, line 50
def kill(signal = 'TERM')
  ::Process.kill(signal, pid)
end
pid() click to toggle source

@return [Integer]

# File lib/komenda/process.rb, line 44
def pid
  raise 'No PID available' if @pid.nil?
  @pid
end
result() click to toggle source

@return [Komenda::Result]

# File lib/komenda/process.rb, line 63
def result
  raise 'Process not started' unless started?
  raise 'Process not finished' unless finished?
  Komenda::Result.new(@output, @exit_status)
end
run() click to toggle source

@return [Komenda::Result]

# File lib/komenda/process.rb, line 38
def run
  start unless started?
  wait_for
end
running?() click to toggle source

@return [TrueClass, FalseClass]

# File lib/komenda/process.rb, line 55
def running?
  return false if @pid.nil?
  1 == ::Process.kill(0, @pid)
rescue Errno::ESRCH
  false
end
start() click to toggle source

@return [Thread]

# File lib/komenda/process.rb, line 22
def start
  raise 'Already started' if started?
  @thread = Thread.new { run_process(@process_builder) }
end
wait_for() click to toggle source

@return [Komenda::Result]

# File lib/komenda/process.rb, line 28
def wait_for
  raise 'Process not started' unless started?
  @thread.join
  if @process_builder.fail_on_fail && result.error?
    raise "Process failed with exit status `#{result.exitstatus}` and output:\n#{result.output}"
  end
  result
end

Private Instance Methods

finished?() click to toggle source

@return [TrueClass, FalseClass]

# File lib/komenda/process.rb, line 77
def finished?
  !@exit_status.nil?
end
read_streams(streams) { |data, stream| ... } click to toggle source

@param [Array<IO>] streams

# File lib/komenda/process.rb, line 110
def read_streams(streams)
  select_streams(streams) do |stream|
    if stream.eof?
      stream.close
    else
      data = stream.readpartial(4096)
      yield(data, stream)
    end
  end
end
run_popen3(env, command, opts) click to toggle source

@param [Hash] env @param [Array<String>] command @param [Hash] opts

# File lib/komenda/process.rb, line 95
def run_popen3(env, command, opts)
  Open3.popen3(env, *command, opts) do |stdin, stdout, stderr, wait_thr|
    @pid = wait_thr.pid
    stdin.close
    read_streams([stdout, stderr]) do |data, stream|
      emit(:output, data)
      emit(:stdout, data) if stdout == stream
      emit(:stderr, data) if stderr == stream
    end
    @exit_status = wait_thr.value
    emit(:exit, result)
  end
end
run_process(process_builder) click to toggle source

@param [ProcessBuilder] process_builder

# File lib/komenda/process.rb, line 82
def run_process(process_builder)
  opts = {}
  opts[:chdir] = process_builder.cwd unless process_builder.cwd.nil?
  opts[:unsetenv_others] = true
  run_popen3(process_builder.env_final, process_builder.command, opts)
rescue Exception => exception
  emit(:error, exception)
  raise exception
end
select_streams(streams) { |stream| ... } click to toggle source

@param [Array<IO>] streams

# File lib/komenda/process.rb, line 122
def select_streams(streams)
  loop do
    streams_available, = IO.select(streams)
    streams_available.each do |stream|
      yield(stream)
    end
    streams.reject!(&:closed?)
    break if streams.empty?
  end
end
started?() click to toggle source

@return [TrueClass, FalseClass]

# File lib/komenda/process.rb, line 72
def started?
  !@thread.nil?
end