class Rexe::Main
Attributes
Public Class Methods
# File exe/rexe, line 431 def initialize @lookups = Lookups.new @start_time = DateTime.now end
Public Instance Methods
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
# File exe/rexe, line 484 def create_callable eval("Proc.new { #{user_source_code} }") end
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
# 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
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
# File exe/rexe, line 437 def load_global_config_if_exists filespec = File.join(Dir.home, '.rexerc') load(filespec) if File.exists?(filespec) end
# 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
# 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
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