class Devpack::GemSpec

Locates relevant gemspec for a given gem and provides a full list of paths for all `require_paths` listed in gemspec.

Public Class Methods

new(glob, name, requirement) click to toggle source
# File lib/devpack/gem_spec.rb, line 7
def initialize(glob, name, requirement)
  @name = name
  @glob = glob
  @requirement = requirement
  @dependency = Gem::Dependency.new(@name, @requirement)
end

Public Instance Methods

gemspec() click to toggle source
# File lib/devpack/gem_spec.rb, line 20
def gemspec
  @gemspec ||= gemspecs.find do |spec|
    next false if spec.nil?

    @dependency.requirement.satisfied_by?(spec.version) && compatible?(spec)
  end
end
require_paths(visited = Set.new) click to toggle source
# File lib/devpack/gem_spec.rb, line 14
def require_paths(visited = Set.new)
  raise GemNotFoundError, @requirement.nil? ? '-' : required_version if gemspec.nil?

  (immediate_require_paths + dependency_require_paths(visited)).compact.flatten.uniq
end

Private Instance Methods

candidates() click to toggle source
# File lib/devpack/gem_spec.rb, line 100
def candidates
  @candidates ||= @glob.find(@name)
end
compatible?(spec) click to toggle source
# File lib/devpack/gem_spec.rb, line 30
def compatible?(spec)
  return false if spec.nil?
  return false if incompatible_version_loaded?(spec)

  compatible_specs?(Gem.loaded_specs.values, [@dependency] + spec.runtime_dependencies)
end
compatible_dependencies?(dependencies, spec) click to toggle source
# File lib/devpack/gem_spec.rb, line 52
def compatible_dependencies?(dependencies, spec)
  dependencies.all? { |dependency| compatible_dependency?(dependency, spec) }
end
compatible_dependency?(dependency, spec) click to toggle source
# File lib/devpack/gem_spec.rb, line 56
def compatible_dependency?(dependency, spec)
  return false if spec.nil?
  return true unless dependency.name == spec.name

  dependency.requirement.satisfied_by?(spec.version)
end
compatible_specs?(specs, dependencies) click to toggle source
# File lib/devpack/gem_spec.rb, line 48
def compatible_specs?(specs, dependencies)
  specs.all? { |spec| compatible_dependencies?(dependencies, spec) }
end
dependencies() click to toggle source
# File lib/devpack/gem_spec.rb, line 76
def dependencies
  gemspec.runtime_dependencies
end
dependency_require_paths(visited) click to toggle source
# File lib/devpack/gem_spec.rb, line 67
def dependency_require_paths(visited)
  dependencies.map do |dependency|
    next nil if visited.include?(dependency)

    visited << dependency
    GemSpec.new(@glob, dependency.name, dependency.requirement).require_paths(visited)
  end
end
gem_paths() click to toggle source
# File lib/devpack/gem_spec.rb, line 80
def gem_paths
  return nil if candidates.empty?

  candidates.map { |candidate| Pathname.new(candidate) }
end
gemspec_paths() click to toggle source
# File lib/devpack/gem_spec.rb, line 86
def gemspec_paths
  return [] if gem_paths.nil?

  gem_paths.map do |path|
    path.join('..', '..', 'specifications', "#{path.basename}.gemspec").expand_path
  end
end
gemspecs() click to toggle source
# File lib/devpack/gem_spec.rb, line 63
def gemspecs
  @gemspecs ||= gemspec_paths.map { |path| Gem::Specification.load(path.to_s) }
end
immediate_require_paths() click to toggle source
# File lib/devpack/gem_spec.rb, line 94
def immediate_require_paths
  gemspec
    .require_paths
    .map { |path| File.join(gemspec.full_gem_path, path) }
end
incompatible_version_loaded?(spec) click to toggle source
# File lib/devpack/gem_spec.rb, line 37
def incompatible_version_loaded?(spec)
  matched = Gem.loaded_specs[spec.name]
  return false if matched.nil?

  matched.version != spec.version
end
required_version() click to toggle source
# File lib/devpack/gem_spec.rb, line 44
def required_version
  @requirement.requirements.first.last.version
end