module Ridley module Mixin # A Ruby platform agnostic way of executing shell commands on the local system module ShellOut class Response extend Forwardable # @return [String] attr_reader :stdout # @return [String] attr_reader :stderr def_delegator :process_status, :exitstatus def_delegator :process_status, :pid def_delegator :process_status, :success? def_delegator :process_status, :exited? def_delegator :process_status, :stopped? # @param [Process::Status] process_status # @param [String] stdout # @param [String] stderr def initialize(process_status, stdout, stderr) @process_status = process_status @stdout = stdout @stderr = stderr end def error? !success? end alias_method :failure?, :error? private # @return [Process::Status] attr_reader :process_status end include Chozo::RubyEngine extend self # Executes the given shell command on the local system # # @param [String] command # The command to execute # # @return [ShellOut::Response] def shell_out(command) process_status, out, err = jruby? ? jruby_out(command) : mri_out(command) Response.new(process_status, out, err) end private # @param [String] command # The command to execute def mri_out(command) out, err = Tempfile.new('ridley.shell_out.stdout'), Tempfile.new('ridley.shell_out.stderr') begin pid = Process.spawn(command, out: out.to_i, err: err.to_i) Process.waitpid(pid) rescue Errno::ENOENT out.write("") err.write("command not found: #{command}") end out.close err.close [ $?, File.read(out), File.read(err) ] end # @param [String] command # The command to execute def jruby_out(command) out, err = StringIO.new, StringIO.new $stdout, $stderr = out, err system(command) out.rewind err.rewind [ $?, out.read, err.read ] ensure $stdout, $stderr = STDOUT, STDERR end end end end