class Departure::Command

Executes the given command returning it's status and errors

Constants

COMMAND_NOT_FOUND

Attributes

command_line[R]
error_log_path[R]
logger[R]
status[R]

Public Class Methods

new(command_line, error_log_path, logger) click to toggle source

Constructor

@param command_line [String] @param error_log_path [String] @param logger [#write_no_newline]

# File lib/departure/command.rb, line 11
def initialize(command_line, error_log_path, logger)
  @command_line = command_line
  @error_log_path = error_log_path
  @logger = logger
end

Public Instance Methods

run() click to toggle source

Executes the command returning its status. It also prints its stdout to the logger and its stderr to the file specified in error_log_path.

@raise [NoStatusError] if the spawned process' status can't be retrieved @raise [SignalError] if the spawned process received a signal @raise [CommandNotFoundError] if pt-online-schema-change can't be found

@return [Process::Status]

# File lib/departure/command.rb, line 25
def run
  log_started

  run_in_process

  log_finished

  validate_status!
  status
end

Private Instance Methods

error_message() click to toggle source

Returns the error message that appeared in the process' stderr

@return [String]

# File lib/departure/command.rb, line 80
def error_message
  File.read(error_log_path)
end
full_command() click to toggle source

Builds the actual command including stderr redirection to the specified log file

@return [String]

# File lib/departure/command.rb, line 62
def full_command
  "#{command_line} 2> #{error_log_path}"
end
log_finished() click to toggle source

Prints a line break to keep the logs separate from the execution time print by the migration

# File lib/departure/command.rb, line 92
def log_finished
  logger.write("\n")
end
log_started() click to toggle source

Logs when the execution started

# File lib/departure/command.rb, line 85
def log_started
  logger.write("\n")
  logger.say("Running #{command_line}\n\n", true)
end
run_in_process() click to toggle source

Runs the command in a separate process, capturing its stdout and execution status

# File lib/departure/command.rb, line 42
def run_in_process
  Open3.popen3(full_command) do |_stdin, stdout, _stderr, waith_thr|
    begin
      loop do
        IO.select([stdout])
        data = stdout.read_nonblock(8192)
        logger.write_no_newline(data)
      end
    rescue EOFError # rubocop:disable Lint/HandleExceptions
      # noop
    ensure
      @status = waith_thr.value
    end
  end
end
validate_status!() click to toggle source

Validates the status of the execution

@raise [NoStatusError] if the spawned process' status can't be retrieved @raise [SignalError] if the spawned process received a signal @raise [CommandNotFoundError] if pt-online-schema-change can't be found

# File lib/departure/command.rb, line 71
def validate_status!
  raise SignalError.new(status) if status.signaled? # rubocop:disable Style/RaiseArgs
  raise CommandNotFoundError if status.exitstatus == COMMAND_NOT_FOUND
  raise Error, error_message unless status.success?
end