class GemFootprintAnalyzer::ChildContext

A class that is loaded by the child process to faciliate require tracing. When `start_child_context` env is passed, it is instantiated and start is called automatically on require.

Constants

CHILD_FIFO
PARENT_FIFO

Attributes

transport[R]

Public Class Methods

new() click to toggle source

Prints the process pid, so it can be grabbed by the supervisor process, inits tranport fifos and requires requested libraries.

# File lib/gem_footprint_analyzer/child_context.rb, line 14
def initialize
  output Process.pid
  init_transport
  require_rubygems_if_needed
  require_bundler_if_needed
end

Public Instance Methods

start() click to toggle source

Installs the require-spying code and starts requiring

# File lib/gem_footprint_analyzer/child_context.rb, line 22
def start
  RequireSpy.spy_require(transport)
  error = try_require(require_string)
  return transport.done_and_wait_for_ack unless error

  transport.exit_with_error(error)
  exit(1)
end

Private Instance Methods

analyze_gemfile() click to toggle source
# File lib/gem_footprint_analyzer/child_context.rb, line 47
def analyze_gemfile
  ENV['analyze_gemfile']
end
child_fifo() click to toggle source
# File lib/gem_footprint_analyzer/child_context.rb, line 35
def child_fifo
  ENV['child_fifo']
end
init_transport() click to toggle source
# File lib/gem_footprint_analyzer/child_context.rb, line 67
def init_transport
  write_stream = File.open(child_fifo, 'w')
  read_stream = File.open(parent_fifo, 'r')

  @transport = Transport.new(read_stream: read_stream, write_stream: write_stream)
end
output(message) click to toggle source
# File lib/gem_footprint_analyzer/child_context.rb, line 74
def output(message)
  STDOUT.puts(message)
  STDOUT.flush
end
parent_fifo() click to toggle source
# File lib/gem_footprint_analyzer/child_context.rb, line 39
def parent_fifo
  ENV['parent_fifo']
end
require_bundler_if_needed() click to toggle source
# File lib/gem_footprint_analyzer/child_context.rb, line 85
def require_bundler_if_needed
  return unless analyze_gemfile

  require 'bundler/setup'
end
require_rubygems() click to toggle source
# File lib/gem_footprint_analyzer/child_context.rb, line 51
def require_rubygems
  ENV['require_rubygems']
end
require_rubygems_if_needed() click to toggle source
# File lib/gem_footprint_analyzer/child_context.rb, line 79
def require_rubygems_if_needed
  return unless require_rubygems

  require 'rubygems'
end
require_string() click to toggle source
# File lib/gem_footprint_analyzer/child_context.rb, line 43
def require_string
  ENV['require_string']
end
try_require(require_string) click to toggle source
# File lib/gem_footprint_analyzer/child_context.rb, line 55
def try_require(require_string)
  error = nil
  begin
    analyze_gemfile ? Bundler.require : require(require_string)
  rescue LoadError => error
    warn_about_load_error(error)
  rescue Exception => error # rubocop:disable Lint/RescueException
    warn_about_error(error)
  end
  error
end
warn_about_error(error) click to toggle source
# File lib/gem_footprint_analyzer/child_context.rb, line 100
def warn_about_error(error)
  STDERR.puts error.backtrace
  STDERR.flush
end
warn_about_load_error(error) click to toggle source
# File lib/gem_footprint_analyzer/child_context.rb, line 91
def warn_about_load_error(error)
  possible_gem = error.message.split.last
  STDERR.puts "Cannot load '#{possible_gem}', this might be an issue with implicit require in" \
    " the '#{require_string}'"
  STDERR.puts "If '#{possible_gem}' is a gem, you can try adding it to the Gemfile explicitly" \
    ", running `bundle install` and trying again\n\n"
  warn_about_error(error)
end