module DeadGems

Constants

GemInstance
VERSION

Public Class Methods

find(project_root, exerciser, opts = {}) click to toggle source
# File lib/dead_gems.rb, line 9
def find(project_root, exerciser, opts = {})
  test_helper = opts[:test_helper] || 'test/test_helper.rb'
  begin_dir = Dir.pwd
  logger = Logger.new($stdout)
  change_directory_to project_root
  bundle_install
  gems = find_all_gems.map do |name|
    path = find_gem_path(name)
    GemInstance.new(name, path)
  end
  apply_environment_patch(gems, test_helper) do |outfile|
    run(exerciser, gems, outfile)
  end
ensure
  change_directory_to begin_dir
end

Private Class Methods

apply_environment_patch(gems, test_helper) { |outfile| ... } click to toggle source
# File lib/dead_gems.rb, line 57
    def apply_environment_patch(gems, test_helper)
      outfile = Tempfile.new('deadgems')
      prepatch = File.read(test_helper)
      patch = <<-END
gem_paths = #{gems.map(&:path)}
trace = TracePoint.new(:call) do |tp|
  # Gem is used
  # Print to file
  if path = gem_paths.detect {|p| tp.path.include?(p)}
    puts "Gem used: \#{tp.defined_class} called with \#{tp.method_id} in \#{tp.path}"
    File.open('#{outfile.path}', 'a') {|f| f.puts path}
    gem_paths.delete(path)
  end
end
trace.enable
      END
      File.open(test_helper, 'w') { |f| f.write([prepatch, patch].join("\n")) }
      yield outfile
    ensure
      File.open(test_helper, 'w') { |f| f.write(prepatch) }
      outfile.close
      outfile.unlink
    end
bundle_install() click to toggle source
# File lib/dead_gems.rb, line 45
def bundle_install
  Bundler.with_clean_env do
    `bundle install`
  end
end
change_directory_to(dir) click to toggle source
# File lib/dead_gems.rb, line 28
def change_directory_to(dir)
  Dir.chdir(dir)
end
find_all_gems() click to toggle source
# File lib/dead_gems.rb, line 32
def find_all_gems
  Bundler.with_clean_env do
    gem_lines = File.read('Gemfile.lock').split("DEPENDENCIES\n").last.split("\n\n").first
    gem_lines.each_line.reduce([]) do |arr, line|
      begin
        arr << line.match(/\s*([^\s!]+)/).captures.first
      rescue => e
        raise "Encountered #{e} on line: #{line}"
      end
    end
  end
end
find_gem_path(gem) click to toggle source
# File lib/dead_gems.rb, line 51
def find_gem_path(gem)
  Bundler.with_clean_env do
    `bundle list #{gem}`.chomp
  end
end
run(exerciser, gems, outfile) click to toggle source
# File lib/dead_gems.rb, line 81
def run(exerciser, gems, outfile)
  Bundler.with_clean_env do
    # If all tests pass then the gem is unused.
    # Otherwise it would've have exited on-call.
    system exerciser
    outfile.read.each_line do |line|
      path = line.chomp
      gems.delete_if {|g| g.path == path}
    end
    gems.map(&:name)
  end
end