class Aruba::Processes::SpawnProcess
Spawn a process for command
‘SpawnProcess` is not meant for direct use - `SpawnProcess.new` - by users. Only it’s public methods are part of the public API of aruba, e.g. ‘#stdin`, `#stdout`.
@private
Public Class Methods
Use as default launcher
# File lib/aruba/processes/spawn_process.rb, line 100 def self.match?(_mode) true end
Create process
@param [String] cmd
Command string
@param [Numeric] exit_timeout
The timeout until we expect the command to be finished
@param [Numeric] io_wait_timeout
The timeout until we expect the io to be finished
@param [String] working_directory
The directory where the command will be executed
@param [Hash] environment
Environment variables
@param [Class] main_class
E.g. Cli::App::Runner
@param [String] stop_signal
Name of signal to send to stop process. E.g. 'HUP'.
@param [Numeric] startup_wait_time
The amount of seconds to wait after Aruba has started a command.
Aruba::Processes::BasicProcess::new
# File lib/aruba/processes/spawn_process.rb, line 129 def initialize(cmd, exit_timeout, io_wait_timeout, working_directory, # rubocop:disable Metrics/ParameterLists environment = Aruba.platform.environment_variables.hash_from_env, main_class = nil, stop_signal = nil, startup_wait_time = 0) super @process = nil @stdout_cache = nil @stderr_cache = nil end
Public Instance Methods
Close io
# File lib/aruba/processes/spawn_process.rb, line 243 def close_io(name) return if stopped? @process.public_send(name.to_sym).close end
Content of command
@return [String]
The content of the script/command. This might be binary output as string if your command is a binary executable.
# File lib/aruba/processes/spawn_process.rb, line 325 def content File.read command_path end
Return file system stats for the given command
@return [Aruba::Platforms::FilesystemStatus]
This returns a File::Stat-object
# File lib/aruba/processes/spawn_process.rb, line 316 def filesystem_status Aruba.platform.filesystem_status.new(command_path) end
# File lib/aruba/processes/spawn_process.rb, line 329 def interactive? true end
Output pid of process
This is the PID of the spawned process.
# File lib/aruba/processes/spawn_process.rb, line 295 def pid @process.pid end
Send command a signal
@param [String] signal
The signal, i.e. 'TERM'
# File lib/aruba/processes/spawn_process.rb, line 303 def send_signal(signal) error_message = %(Command "#{commandline}" with PID "#{pid}" has already stopped.) raise CommandAlreadyStoppedError, error_message if @process.exited? Process.kill signal, pid rescue Errno::ESRCH raise CommandAlreadyStoppedError, error_message end
Run the command
@yield [SpawnProcess]
Run code for process which was started
# File lib/aruba/processes/spawn_process.rb, line 144 def start if started? error_message = "Command \"#{commandline}\" has already been started." \ " Please `#stop` the command first and `#start` it again." \ " Alternatively use `#restart`." raise CommandAlreadyStartedError, error_message end @started = true @process = ProcessRunner.new(command_string.to_a) @stdout_file = Tempfile.new("aruba-stdout-") @stderr_file = Tempfile.new("aruba-stderr-") @stdout_file.sync = true @stderr_file.sync = true @stdout_file.set_encoding("ASCII-8BIT") @stderr_file.set_encoding("ASCII-8BIT") @exit_status = nil before_run @process.stdout = @stdout_file @process.stderr = @stderr_file @process.cwd = @working_directory @process.environment = environment begin @process.start sleep startup_wait_time rescue SystemCallError => e raise LaunchError, "It tried to start #{commandline}. " + e.message end after_run yield self if block_given? end
Access to stderr of process
@param [Hash] opts
Options
@option [Integer] wait_for_io
Wait for IO to be finished
@return [String]
The content of stderr
# File lib/aruba/processes/spawn_process.rb, line 224 def stderr(opts = {}) return @stderr_cache if stopped? wait_for_io opts.fetch(:wait_for_io, io_wait_timeout) do @process.stderr.flush open(@stderr_file.path).read end end
Access to stdin of process
# File lib/aruba/processes/spawn_process.rb, line 189 def stdin return if @process.exited? @process.io.stdin end
Access to stdout of process
@param [Hash] opts
Options
@option [Integer] wait_for_io
Wait for IO to be finished
@return [String]
The content of stdout
# File lib/aruba/processes/spawn_process.rb, line 205 def stdout(opts = {}) return @stdout_cache if stopped? wait_for_io opts.fetch(:wait_for_io, io_wait_timeout) do @process.stdout.flush open(@stdout_file.path).read end end
Stop command
# File lib/aruba/processes/spawn_process.rb, line 250 def stop(*) return @exit_status if stopped? @process.poll_for_exit(@exit_timeout) or @timed_out = true terminate end
Terminate command
# File lib/aruba/processes/spawn_process.rb, line 264 def terminate return @exit_status if stopped? unless @process.exited? if @stop_signal # send stop signal ... send_signal @stop_signal # ... and set the exit status wait else begin @process.stop rescue Errno::EPERM # This can occur on MacOS nil end end end @exit_status = @process.exit_code @stdout_cache = read_temporary_output_file @stdout_file @stderr_cache = read_temporary_output_file @stderr_file @started = false @exit_status end
Wait for command to finish
# File lib/aruba/processes/spawn_process.rb, line 259 def wait @process.wait end
# File lib/aruba/processes/spawn_process.rb, line 233 def write(input) return if stopped? @process.stdin.write(input) @process.stdin.flush self end
Private Instance Methods
# File lib/aruba/processes/spawn_process.rb, line 344 def command_path @command_path ||= if Aruba.platform.builtin_shell_commands.include?(command) command else Aruba.platform.which(command, environment["PATH"]) end end
# File lib/aruba/processes/spawn_process.rb, line 335 def command_string if command_path.nil? raise LaunchError, %(Command "#{command}" not found in PATH-variable "#{environment['PATH']}".) end Aruba.platform.command_string.new(command_path, *arguments) end
# File lib/aruba/processes/spawn_process.rb, line 358 def read_temporary_output_file(file) file.flush file.rewind data = file.read file.close data.force_encoding("UTF-8") end
# File lib/aruba/processes/spawn_process.rb, line 353 def wait_for_io(time_to_wait) sleep time_to_wait yield end