class Resquire::Analyzer

Attributes

gems[R]

gem dependencies, as an array

Public Class Methods

new(args = {}) click to toggle source

When we create a new Analyzer, we can specifiy the gems we want to work with, but it must be passed in as an array in the args hash.

Typical Usage

analyzer = Resquire::Analyzer.new(:gems => ['packetfu', 'pcaprub'])
# File lib/resquire/analyzer.rb, line 15
def initialize(args = {})
  @gems = []
  @redundant_gems = []
  if args[:gems]
    if args[:gems].is_a? Array
      add_gems(args[:gems])
    else
      raise Resquire::ResquireError.new('Dependencies must be initialized as an array!')
    end
  end
  true
end

Public Instance Methods

add_gem(gem) click to toggle source

We can add one gem at a time as a string.

Typical Usage

analyzer = Resquire::Analyzer.new
analyzer.add_gem('packetfu')
analyzer.add_gem('pcaprub')
# File lib/resquire/analyzer.rb, line 48
def add_gem(gem)
  @gems << gem
  @gems = @gems.uniq
  true
end
add_gems(gems = []) click to toggle source

We can add gems specified from an array.

Typical Usage

analyzer = Resquire::Analyzer.new
analyzer.add_gems(['packetfu', 'pcaprub'])
# File lib/resquire/analyzer.rb, line 35
def add_gems(gems = [])
  gems.uniq.each { |gem| @gems << gem } 
  true
end
optimized_gems() click to toggle source

Once we have figured out the redundant gems, we can easily check out our optimized gem list which we can now use.

Typical Usage

analyzer = Resquire::Analyzer.new(:gems => ['packetfu', 'pcaprub'])
analyzer.redundant_gems
# => ['pcaprub']
analyzer.optimized_gems
# => ['packetfu']
# File lib/resquire/analyzer.rb, line 99
def optimized_gems
  optimized_gems = @gems.reject { |gem| @redundant_gems.include? gem }
  optimized_gems.empty? ? false : optimized_gems.uniq.sort
end
permutations(gems = @gems) click to toggle source

We can check the given permutations that we will need to cycle through to find gems that are redundant.

Typical Usage

analyzer = Resquire::Analyzer.new(:gems => ['packetfu', 'pcaprub'])
analyzer.permutations
# File lib/resquire/analyzer.rb, line 63
def permutations(gems = @gems)
  (1..gems.count).reduce(:*) || 1
end
redundant_gems(args = {}) click to toggle source

We can find the redundant gems from the the analyzer has to work with, iterating over the possible permutations and returning an array of redundant gems.

Typical Usage

analyzer = Resquire::Analyzer.new(:gems => ['packetfu', 'pcaprub'])
analyzer.permutations
# => 2
# File lib/resquire/analyzer.rb, line 77
def redundant_gems(args = {})
  find_redundant_gems_with_gem(args)
  @count = 0
  @permutation_count = permutations
  @progress_bar = args[:progress_bar] || true
  gems = args[:gems] || @gems
  redundant = args[:redundant_gems] || @redundant_gems
  find_redundant_gems(args).empty? ? false : @redundant_gems
end

Private Instance Methods

find_redundant_gems(args = {}) click to toggle source

Used to find redundant gems.

# File lib/resquire/analyzer.rb, line 107
def find_redundant_gems(args = {})
  gems = @gems.reject { |gem| @redundant_gems.include? gem }
  permutation_count = permutations(gems)
  @count = 0
  # shuffle method by default
  shuffle = args[:shuffle] || true
  iterate = args[:iterate] || false
  if shuffle
    shuffle_permutations(args)   
  elsif iterate
    shuffle_permutations(args) 
  else
    iterate_permutations(args)
  end 
  @redundant_gems
end
find_redundant_gems_with_gem(args = {}) click to toggle source

Help find redundant gems using the gem command.

# File lib/resquire/analyzer.rb, line 125
def find_redundant_gems_with_gem(args = {})
  gems = args[:gems] || @gems
  gems_with_deps = {}
  gems.each do |gem|
    output, status = Open3.capture2e("gem dependency #{gem}")
    next unless status.success?
    deps = output.split("\n").map(&:strip)
    deps = deps.reject { |g| g.include? ', development' or g.include? 'Gem ' }
    deps = deps.map { |x| x.gsub(/\s\(.+\)/, '') }
    gems_with_deps[gem] = deps
  end
  redundant_gems = []
  gems_with_deps.keys.each do |gem|
    next if gems_with_deps[gem].empty?
    gems_with_deps[gem].each do |g|
      redundant_gems << g if gems_with_deps.keys.include?(g)
    end
  end
  redundant_gems.uniq.each { |gem| @redundant_gems << gem unless @redundant_gems.include?(gem) }
  @redundant_gems
end
iterate_permutations(args = {}) click to toggle source

We can iterate over the permutations, which can make things faster.

# File lib/resquire/analyzer.rb, line 166
def iterate_permutations(args = {})
  gems = @gems.reject { |gem| @redundant_gems.include? gem }
  permutation_count = permutations(gems)
  count = 0
  template_location = File.dirname(Open3.capture2e("gem which resquire")[0]) + '/template.rb'
  gems.permutation.each do |gem_group|
    print "#{count}/#{permutation_count}\r" if @progress_bar
    redundant_gem, status = Open3.capture2e("ruby #{template_location} #{gem_group.join(',')}")
    @redundant_gems << redundant_gem unless status.success?
    break unless status.success?
    count += 1
  end
  find_redundant_gems(args) unless count == permutation_count
  @redundant_gems
end
shuffle_permutations(args = {}) click to toggle source

We can shuffle the permutations, which can make things faster.

# File lib/resquire/analyzer.rb, line 148
def shuffle_permutations(args = {})
  gems = @gems.reject { |gem| @redundant_gems.include? gem }
  permutation_count = permutations(gems)
  count = 0
  gems = gems.permutation.to_a.shuffle
  template_location = File.dirname(Open3.capture2e("gem which resquire")[0]) + '/template.rb'
  gems.each do |gem_group|
    print "#{count}/#{permutation_count}\r" if @progress_bar
    redundant_gem, status = Open3.capture2e("ruby #{template_location} #{gem_group.join(',')}")
    @redundant_gems << redundant_gem unless status.success?
    break unless status.success?
    count += 1
  end
  find_redundant_gems(args) unless count == permutation_count
  @redundant_gems
end