class MultiRubyRunner

Allows calling of Ruby code in various Ruby environments.

Constants

VERSION

Public Class Methods

new() click to toggle source
# File lib/multi_ruby_runner.rb, line 10
def initialize
end

Public Instance Methods

execute_command_in_directory(command_string, directory, options = {}) click to toggle source

Executes a command in a directory. Command will be executed in the ruby environment specified in `.ruby-version` file in `directory`. Returns stdout in the blocking form and pid of child process in the non-blocking form.

@param command_string [String] the shell command to run in directory @param directory [String] the dir containing the “.ruby-version” file @param options [Hash, optional] @option options [String, optional] shell_invocation what shell to use, defaults to bash @option options [Boolean, optional] blocking defaults to true. @option options [String, optional] ruby_engine_invocation_override

Can be used when no Ruby version manager is present, e.g., in a docker install.
Example: "jruby -S "

@return [String, Integer, Nil] STDOUT output when blocking, pid when non-blocking.

# File lib/multi_ruby_runner.rb, line 27
def execute_command_in_directory(command_string, directory, options = {})
  shell_path = ENV['SHELL'] || '/bin/bash'
  options = {
    blocking: true,
    shell_invocation: "#{ shell_path } -c",
  }.merge(options)
  process_args = ruby_version_manager.compute_process_args(
    command_string,
    directory,
    options
  )
  execute_command(process_args)
end
ruby_version_manager() click to toggle source

Returns the ruby version manager used @return [MultiRubyRunner::VersionManager] 'rbenv', 'rvm', 'none'

# File lib/multi_ruby_runner.rb, line 43
def ruby_version_manager
  VersionManager.detect
end

Protected Instance Methods

execute_blocking_command(process_args) click to toggle source
# File lib/multi_ruby_runner.rb, line 66
def execute_blocking_command(process_args)
  stdout_str = stderr_str = status = nil
  Bundler.with_unbundled_env do
    stdout_str, stderr_str, status = Open3.capture3(
      process_args[:environment_overrides],
      process_args[:entire_command]
    )
  end
  if 0 == status
    # return stdout
    stdout_str
  else
    # Raise exception
    raise "Command failed with status #{ status.inspect }. stderr: #{ stderr_str.inspect }"
  end
end
execute_command(process_args) click to toggle source

@param process_args [Hash]

{
  entire_command: includes shell invocation,
                  ruby version manager activation and command
  blocking: Boolean
  environment_overrides: {}
}
# File lib/multi_ruby_runner.rb, line 56
def execute_command(process_args)
  if process_args[:blocking]
    # Wait for command to complete
    execute_blocking_command(process_args)
  else
    # Spawn new process, execute command there and return immediately to caller.
    execute_non_blocking_command(process_args)
  end
end
execute_non_blocking_command(process_args) click to toggle source
# File lib/multi_ruby_runner.rb, line 83
def execute_non_blocking_command(process_args)
  pid = nil
  Bundler.with_unbundled_env do
    pid = Process.spawn(
      process_args[:environment_overrides],
      process_args[:entire_command]
    )
  end
  Process.detach(pid) # Avoid zombie process
  pid # return spawned process' pid
end