1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
# frozen_string_literal: true
require 'shellwords'
require 'stringio'
require 'aruba/processes/basic_process'
require 'aruba/platform'
# Aruba
module Aruba
# Platforms
module Processes
# Run command in your ruby process
#
# `InProcess` is not meant for direct use - `InProcess.new` - by
# users. Only it's public methods are part of the public API of aruba, e.g.
# `#stdin`, `#stdout`.
#
# @private
class InProcess < BasicProcess
# Use only if mode is in_process
def self.match?(mode)
mode == :in_process || (mode.is_a?(Class) && mode <= InProcess)
end
attr_reader :exit_status
# Fake Kernel module of ruby
#
# @private
class FakeKernel
attr_reader :exitstatus
def initialize
@exitstatus = 0
end
def exit(exitstatus)
@exitstatus =
case exitstatus
when Numeric then Integer(exitstatus)
when TrueClass then 0
when FalseClass then 1
else raise TypeError, "no implicit conversion of #{exitstatus.class} into Integer"
end
end
end
# @private
attr_reader :main_class
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)
@cmd = cmd
@argv = arguments
@stdin = StringIO.new
@stdout = StringIO.new
@stderr = StringIO.new
@kernel = FakeKernel.new
super
end
# Start command
def start
raise 'You need to call aruba.config.main_class = YourMainClass' unless main_class
@started = true
Dir.chdir @working_directory do
before_run
new_env = environment.merge('PWD' => @working_directory)
Aruba.platform.with_replaced_environment new_env do
main_class.new(@argv, @stdin, @stdout, @stderr, @kernel).execute!
end
after_run
yield self if block_given?
end
end
# Stop command
def stop(*)
@started = false
@exit_status = @kernel.exitstatus
end
# Access stdin
def stdin
@stdin.string
end
# Access stdout
def stdout(*)
@stdout.string
end
# Access stderr
def stderr(*)
@stderr.string
end
# Write strint to stdin
#
# @param [String] input
# Write string to stdin in
def write(input)
@stdin.write input
end
# Close io
def close_io(name)
unless %i[stdin stdout stderr].include? name
raise ArgumentError, 'Only stdin stdout and stderr are allowed to close'
end
get_instance_variable(name.to_sym).close
end
# Terminate program
def terminate
stop
end
# Output pid of process
#
# This is the PID of the ruby process! So be careful
def pid
$PROCESS_ID
end
def interactive?
false
end
end
end
end
|