class Rexe::Main

Attributes

callable[R]
input_parser[R]
log_formatter[R]
lookups[R]
options[R]
output_formatter[R]
start_time[R]
user_source_code[R]

Public Class Methods

new() click to toggle source
# File exe/rexe, line 431
def initialize
  @lookups = Lookups.new
  @start_time = DateTime.now
end

Public Instance Methods

call() click to toggle source

This class' entry point.

# File exe/rexe, line 527
def call

  try do

    @options = CommandLineParser.new.parse

    options.requires.each { |r| require!(r) }
    load_global_config_if_exists
    options.loads.each { |file| load(file) }

    @user_source_code = ARGV.join(' ')
    @user_source_code = 'self' if @user_source_code == ''

    @callable = create_callable

    init_rexe_context
    init_parser_and_formatters

    # This is where the user's source code will be executed; the action will in turn call `execute`.
    lookup_action(options.input_mode).call unless options.noop

    output_log_entry
  end
end

Private Instance Methods

create_callable() click to toggle source
# File exe/rexe, line 484
        def create_callable
  eval("Proc.new { #{user_source_code} }")
end
execute(eval_context_object, code) click to toggle source

Executes the user specified code in the manner appropriate to the input mode. Performs any optionally specified parsing on input and formatting on output.

# File exe/rexe, line 452
        def execute(eval_context_object, code)
  if options.input_format != :none && options.input_mode != :none
    eval_context_object = input_parser.(eval_context_object)
  end

  value = eval_context_object.instance_eval(&code)

  unless options.output_format == :none
    print output_formatter.(value)
  end
rescue Errno::EPIPE
  exit(-13)
end
init_parser_and_formatters() click to toggle source
# File exe/rexe, line 443
        def init_parser_and_formatters
  @input_parser     = lookups.input_parsers[options.input_format]
  @output_formatter = lookups.formatters[options.output_format]
  @log_formatter    = lookups.formatters[options.log_format]
end
init_rexe_context() click to toggle source

The global $RC (Rexe Context) OpenStruct is available in your user code. In order to make it possible to access this object in your loaded files, we are not creating it here; instead we add properties to it. This way, you can initialize an OpenStruct yourself in your loaded code and it will still work. If you do that, beware, any properties you add will be included in the log output. If the to_s of your added objects is large, that might be a pain.

# File exe/rexe, line 472
        def init_rexe_context
  $RC ||= OpenStruct.new
  $RC.count         = 0
  $RC.rexe_version  = VERSION
  $RC.start_time    = start_time.iso8601
  $RC.source_code   = user_source_code
  $RC.options       = options.to_h

  def $RC.i; count end  # `i` aliases `count` so you can more concisely get the count in your user code
end
load_global_config_if_exists() click to toggle source
# File exe/rexe, line 437
        def load_global_config_if_exists
  filespec = File.join(Dir.home, '.rexerc')
  load(filespec) if File.exists?(filespec)
end
lookup_action(mode) click to toggle source
# File exe/rexe, line 489
        def lookup_action(mode)
  input = options.input_filespec ? File.open(options.input_filespec) : STDIN
  {
      line:           -> { input.each { |l| execute(l.chomp, callable);            $RC.count += 1 } },
      enumerator:     -> { execute(input.each_line, callable);                     $RC.count += 1 },
      one_big_string: -> { big_string = input.read; execute(big_string, callable); $RC.count += 1 },
      none:           -> { execute(Object.new, callable) }
  }.fetch(mode)
end
output_log_entry() click to toggle source
# File exe/rexe, line 500
        def output_log_entry
  if options.log_format != :none
    $RC.duration_secs = Time.now - start_time.to_time
    STDERR.puts(log_formatter.($RC.to_h))
  end
end
require!(the_require) click to toggle source

Bypasses Bundler's restriction on loading gems (see stackoverflow.com/questions/55144094/bundler-doesnt-permit-using-gems-in-project-home-directory)

# File exe/rexe, line 510
        def require!(the_require)
  begin
    require the_require
  rescue LoadError => error
    gem_path = `gem which #{the_require}`
    if gem_path.chomp.strip.empty?
      raise error # re-raise the error, can't fix it
    else
      load_dir = File.dirname(gem_path)
      $LOAD_PATH += load_dir
      require the_require
    end
  end
end