class Bundler::SpecSet

Parent:
Object
Included modules:
Enumerable, TSort

Public Class Methods

new(specs) Show source
# File lib/bundler/spec_set.rb, line 11
def initialize(specs)
  @specs = specs
end

Public Instance Methods

<<(spec) Show source
# File lib/bundler/spec_set.rb, line 130
def <<(spec)
  @specs << spec
end
[](key) Show source
# File lib/bundler/spec_set.rb, line 54
def [](key)
  key = key.name if key.respond_to?(:name)
  lookup[key].reverse
end
[]=(key, value) Show source
# File lib/bundler/spec_set.rb, line 59
def []=(key, value)
  @specs << value
  @lookup = nil
  @sorted = nil
end
each(&b) Show source
# File lib/bundler/spec_set.rb, line 146
def each(&b)
  sorted.each(&b)
end
empty?() Show source
# File lib/bundler/spec_set.rb, line 142
def empty?
  @specs.empty?
end
find_by_name_and_platform(name, platform) Show source
# File lib/bundler/spec_set.rb, line 119
def find_by_name_and_platform(name, platform)
  @specs.detect {|spec| spec.name == name && spec.match_platform(platform) }
end
for(dependencies, skip = [], check = false, match_current_platform = false, raise_on_missing = true) Show source
# File lib/bundler/spec_set.rb, line 15
def for(dependencies, skip = [], check = false, match_current_platform = false, raise_on_missing = true)
  handled = Set.new
  deps = dependencies.dup
  specs = []
  skip += ["bundler"]

  loop do
    break unless dep = deps.shift
    next if !handled.add?(dep) || skip.include?(dep.name)

    if spec = spec_for_dependency(dep, match_current_platform)
      specs << spec

      spec.dependencies.each do |d|
        next if d.type == :development
        d = DepProxy.new(d, dep.__platform) unless match_current_platform
        deps << d
      end
    elsif check
      return false
    elsif raise_on_missing
      others = lookup[dep.name] if match_current_platform
      message = "Unable to find a spec satisfying #{dep} in the set. Perhaps the lockfile is corrupted?"
      message += " Found #{others.join(", ")} that did not match the current platform." if others && !others.empty?
      raise GemNotFound, message
    end
  end

  if spec = lookup["bundler"].first
    specs << spec
  end

  check ? true : SpecSet.new(specs)
end
length() Show source
# File lib/bundler/spec_set.rb, line 134
def length
  @specs.length
end
materialize(deps, missing_specs = nil) Show source
# File lib/bundler/spec_set.rb, line 77
def materialize(deps, missing_specs = nil)
  materialized = self.for(deps, [], false, true, !missing_specs).to_a
  deps = materialized.map(&:name).uniq
  materialized.map! do |s|
    next s unless s.is_a?(LazySpecification)
    s.source.dependency_names = deps if s.source.respond_to?(:dependency_names=)
    spec = s.__materialize__
    unless spec
      unless missing_specs
        raise GemNotFound, "Could not find #{s.full_name} in any of the sources"
      end
      missing_specs << s
    end
    spec
  end
  SpecSet.new(missing_specs ? materialized.compact : materialized)
end
materialized_for_all_platforms() Show source
# File lib/bundler/spec_set.rb, line 98
def materialized_for_all_platforms
  names = @specs.map(&:name).uniq
  @specs.map do |s|
    next s unless s.is_a?(LazySpecification)
    s.source.dependency_names = names if s.source.respond_to?(:dependency_names=)
    spec = s.__materialize__
    raise GemNotFound, "Could not find #{s.full_name} in any of the sources" unless spec
    spec
  end
end

Materialize for all the specs in the spec set, regardless of what platform they're for This is in contrast to how for does platform filtering (and specifically different from how `materialize` calls `for` only for the current platform) @return [Array<Gem::Specification>]

merge(set) Show source
# File lib/bundler/spec_set.rb, line 109
def merge(set)
  arr = sorted.dup
  set.each do |set_spec|
    full_name = set_spec.full_name
    next if arr.any? {|spec| spec.full_name == full_name }
    arr << set_spec
  end
  SpecSet.new(arr)
end
size() Show source
# File lib/bundler/spec_set.rb, line 138
def size
  @specs.size
end
sort!() Show source
# File lib/bundler/spec_set.rb, line 65
def sort!
  self
end
to_a() Show source
# File lib/bundler/spec_set.rb, line 69
def to_a
  sorted.dup
end
to_hash() Show source
# File lib/bundler/spec_set.rb, line 73
def to_hash
  lookup.dup
end
valid_for?(deps) Show source
# File lib/bundler/spec_set.rb, line 50
def valid_for?(deps)
  self.for(deps, [], true)
end
what_required(spec) Show source
# File lib/bundler/spec_set.rb, line 123
def what_required(spec)
  unless req = find {|s| s.dependencies.any? {|d| d.type == :runtime && d.name == spec.name } }
    return [spec]
  end
  what_required(req) << spec
end

Private Instance Methods

extract_circular_gems(error) Show source
# File lib/bundler/spec_set.rb, line 164
def extract_circular_gems(error)
  error.message.scan(/@name="(.*?)"/).flatten
end
lookup() Show source
# File lib/bundler/spec_set.rb, line 168
def lookup
  @lookup ||= begin
    lookup = Hash.new {|h, k| h[k] = [] }
    Index.sort_specs(@specs).reverse_each do |s|
      lookup[s.name] << s
    end
    lookup
  end
end
sorted() Show source
# File lib/bundler/spec_set.rb, line 152
def sorted
  rake = @specs.find {|s| s.name == "rake" }
  begin
    @sorted ||= ([rake] + tsort).compact.uniq
  rescue TSort::Cyclic => error
    cgems = extract_circular_gems(error)
    raise CyclicDependencyError, "Your bundle requires gems that depend" \
      " on each other, creating an infinite loop. Please remove either" \
      " gem '#{cgems[1]}' or gem '#{cgems[0]}' and try again."
  end
end
spec_for_dependency(dep, match_current_platform) Show source
# File lib/bundler/spec_set.rb, line 183
def spec_for_dependency(dep, match_current_platform)
  specs_for_platforms = lookup[dep.name]
  if match_current_platform
    Bundler.rubygems.platforms.reverse_each do |pl|
      match = GemHelpers.select_best_platform_match(specs_for_platforms, pl)
      return match if match
    end
    nil
  else
    GemHelpers.select_best_platform_match(specs_for_platforms, dep.__platform)
  end
end
tsort_each_child(s) { |s2| ... } Show source
# File lib/bundler/spec_set.rb, line 196
def tsort_each_child(s)
  s.dependencies.sort_by(&:name).each do |d|
    next if d.type == :development
    lookup[d.name].each {|s2| yield s2 }
  end
end
tsort_each_node() { |s| ... } Show source
# File lib/bundler/spec_set.rb, line 178
def tsort_each_node
  # MUST sort by name for backwards compatibility
  @specs.sort_by(&:name).each {|s| yield s }
end

Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.