class JetBlack::TerminalSession

Constants

DEFAULT_TIMEOUT

Attributes

exit_status[RW]
input[R]
output[R]
pid[R]
raw_std_err[RW]
raw_stdout[RW]
stderr_reader[R]
stderr_writer[R]

Public Class Methods

new(raw_command, env:, directory:) click to toggle source
# File lib/jet_black/terminal_session.rb, line 11
def initialize(raw_command, env:, directory:)
  @stderr_reader, @stderr_writer = IO.pipe
  @output, @input, @pid = PTY.spawn(env, raw_command, chdir: directory, err: stderr_writer.fileno)
  self.raw_stdout = []
end

Public Instance Methods

end_session(signal: "INT") click to toggle source
# File lib/jet_black/terminal_session.rb, line 48
def end_session(signal: "INT")
  Process.kill(signal, pid)
  finalize_io

  self.exit_status = wait_for_exit_status
end
expect(expected_value, reply: nil, timeout: DEFAULT_TIMEOUT, signal_on_timeout: "KILL") click to toggle source
# File lib/jet_black/terminal_session.rb, line 17
def expect(expected_value, reply: nil, timeout: DEFAULT_TIMEOUT, signal_on_timeout: "KILL")
  output_matches = output.expect(expected_value, timeout)

  if output_matches.nil?
    end_session(signal: signal_on_timeout)
    raise TerminalSessionTimeoutError.new(self, expected_value, timeout)
  end

  raw_stdout.concat(output_matches)

  if reply != nil
    input.puts(reply)
  end
end
finished?() click to toggle source
# File lib/jet_black/terminal_session.rb, line 55
def finished?
  !exit_status.nil?
end
stderr() click to toggle source
# File lib/jet_black/terminal_session.rb, line 36
def stderr
  raw_std_err
end
stdout() click to toggle source
# File lib/jet_black/terminal_session.rb, line 32
def stdout
  raw_stdout.join.gsub("\r", "")
end
wait_for_finish() click to toggle source
# File lib/jet_black/terminal_session.rb, line 40
def wait_for_finish
  return if finished?

  finalize_io

  self.exit_status = wait_for_exit_status
end

Private Instance Methods

drain_stderr() click to toggle source
# File lib/jet_black/terminal_session.rb, line 86
def drain_stderr
  stderr_writer.close
  self.raw_std_err = stderr_reader.read
  stderr_reader.close
end
drain_stdout() click to toggle source
# File lib/jet_black/terminal_session.rb, line 75
def drain_stdout
  until output.eof? do
    raw_stdout << output.readline
  end

  input.close
  output.close
rescue Errno::EIO => e # https://github.com/ruby/ruby/blob/57fb2199059cb55b632d093c2e64c8a3c60acfbb/ext/pty/pty.c#L521
  warn("Rescued #{e.message}") if ENV.key?("DEBUG")
end
finalize_io() click to toggle source
# File lib/jet_black/terminal_session.rb, line 65
def finalize_io
  drain_stdout
  drain_stderr
end
wait_for_exit_status() click to toggle source
# File lib/jet_black/terminal_session.rb, line 70
def wait_for_exit_status
  _, pty_status = Process.waitpid2(pid)
  pty_status.exitstatus || pty_status.termsig
end