class Bundler::SpecSet
Attributes
incomplete_specs[R]
Public Class Methods
new(specs, incomplete_specs = [])
click to toggle source
# File bundler/spec_set.rb, line 12 def initialize(specs, incomplete_specs = []) @specs = specs @incomplete_specs = incomplete_specs end
Public Instance Methods
-(other)
click to toggle source
# File bundler/spec_set.rb, line 147 def -(other) SpecSet.new(to_a - other.to_a) end
<<(spec)
click to toggle source
# File bundler/spec_set.rb, line 174 def <<(spec) @specs << spec end
[](key)
click to toggle source
# File bundler/spec_set.rb, line 85 def [](key) key = key.name if key.respond_to?(:name) lookup[key]&.reverse || [] end
[]=(key, value)
click to toggle source
# File bundler/spec_set.rb, line 90 def []=(key, value) @specs << value reset! end
add_extra_platforms!(platforms)
click to toggle source
# File bundler/spec_set.rb, line 55 def add_extra_platforms!(platforms) return platforms.concat([Gem::Platform::RUBY]).uniq if @specs.empty? new_platforms = all_platforms.select do |platform| next if platforms.include?(platform) next unless GemHelpers.generic(platform) == Gem::Platform::RUBY complete_platform(platform) end return platforms if new_platforms.empty? platforms.concat(new_platforms) less_specific_platform = new_platforms.find {|platform| platform != Gem::Platform::RUBY && Bundler.local_platform === platform && platform === Bundler.local_platform } platforms.delete(Bundler.local_platform) if less_specific_platform platforms end
delete(specs)
click to toggle source
# File bundler/spec_set.rb, line 96 def delete(specs) specs.each {|spec| @specs.delete(spec) } reset! end
delete_by_name(name)
click to toggle source
# File bundler/spec_set.rb, line 161 def delete_by_name(name) @specs.reject! {|spec| spec.name == name } reset! end
each(&b)
click to toggle source
# File bundler/spec_set.rb, line 190 def each(&b) sorted.each(&b) end
empty?()
click to toggle source
# File bundler/spec_set.rb, line 186 def empty? @specs.empty? end
find_by_name_and_platform(name, platform)
click to toggle source
# File bundler/spec_set.rb, line 151 def find_by_name_and_platform(name, platform) @specs.detect {|spec| spec.name == name && spec.match_platform(platform) } end
for(dependencies, check = false, platforms = [nil])
click to toggle source
# File bundler/spec_set.rb, line 17 def for(dependencies, check = false, platforms = [nil]) handled = ["bundler"].product(platforms).map {|k| [k, true] }.to_h deps = dependencies.product(platforms) specs = [] loop do break unless dep = deps.shift name = dep[0].name platform = dep[1] incomplete = false key = [name, platform] next if handled.key?(key) handled[key] = true specs_for_dep = specs_for_dependency(*dep) if specs_for_dep.any? specs.concat(specs_for_dep) specs_for_dep.first.dependencies.each do |d| next if d.type == :development incomplete = true if d.name != "bundler" && lookup[d.name].nil? deps << [d, dep[1]] end else incomplete = true end if incomplete && check @incomplete_specs += lookup[name] || [LazySpecification.new(name, nil, nil)] end end specs.uniq end
incomplete_for_platform?(deps, platform)
click to toggle source
# File bundler/spec_set.rb, line 133 def incomplete_for_platform?(deps, platform) return false if @specs.empty? @incomplete_specs = [] self.for(deps, true, [platform]) @incomplete_specs.any? end
length()
click to toggle source
# File bundler/spec_set.rb, line 178 def length @specs.length end
materialize(deps)
click to toggle source
# File bundler/spec_set.rb, line 114 def materialize(deps) materialized = self.for(deps, true) SpecSet.new(materialized, incomplete_specs) end
materialized_for_all_platforms()
click to toggle source
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>]
# File bundler/spec_set.rb, line 123 def materialized_for_all_platforms @specs.map do |s| next s unless s.is_a?(LazySpecification) s.source.remote! spec = s.materialize_for_installation raise GemNotFound, "Could not find #{s.full_name} in any of the sources" unless spec spec end end
missing_specs()
click to toggle source
# File bundler/spec_set.rb, line 143 def missing_specs @specs.select {|s| s.is_a?(LazySpecification) } end
names()
click to toggle source
# File bundler/spec_set.rb, line 194 def names lookup.keys end
size()
click to toggle source
# File bundler/spec_set.rb, line 182 def size @specs.size end
sort!()
click to toggle source
# File bundler/spec_set.rb, line 102 def sort! self end
specs_compatible_with(other)
click to toggle source
# File bundler/spec_set.rb, line 155 def specs_compatible_with(other) select do |spec| other.valid?(spec) end end
to_a()
click to toggle source
# File bundler/spec_set.rb, line 106 def to_a sorted.dup end
to_hash()
click to toggle source
# File bundler/spec_set.rb, line 110 def to_hash lookup.dup end
valid?(s)
click to toggle source
# File bundler/spec_set.rb, line 198 def valid?(s) s.matches_current_metadata? && valid_dependencies?(s) end
validate_deps(s)
click to toggle source
# File bundler/spec_set.rb, line 74 def validate_deps(s) s.runtime_dependencies.each do |dep| next if dep.name == "bundler" return :missing unless names.include?(dep.name) return :invalid if none? {|spec| dep.matches_spec?(spec) } end :valid end
what_required(spec)
click to toggle source
# File bundler/spec_set.rb, line 167 def what_required(spec) unless req = find {|s| s.runtime_dependencies.any? {|d| d.name == spec.name } } return [spec] end what_required(req) << spec end
Private Instance Methods
all_platforms()
click to toggle source
# File bundler/spec_set.rb, line 236 def all_platforms @specs.flat_map {|spec| spec.source.specs.search([spec.name, spec.version]).map(&:platform) }.uniq end
complete_platform(platform)
click to toggle source
# File bundler/spec_set.rb, line 209 def complete_platform(platform) new_specs = [] valid_platform = lookup.all? do |_, specs| spec = specs.first matching_specs = spec.source.specs.search([spec.name, spec.version]) platform_spec = GemHelpers.select_best_platform_match(matching_specs, platform).find do |s| valid?(s) end if platform_spec new_specs << LazySpecification.from_spec(platform_spec) unless specs.include?(platform_spec) true else false end end if valid_platform && new_specs.any? @specs.concat(new_specs) reset! end valid_platform end
extract_circular_gems(error)
click to toggle source
# File bundler/spec_set.rb, line 256 def extract_circular_gems(error) error.message.scan(/@name="(.*?)"/).flatten end
lookup()
click to toggle source
# File bundler/spec_set.rb, line 260 def lookup @lookup ||= begin lookup = {} @specs.each do |s| lookup[s.name] ||= [] lookup[s.name] << s end lookup end end
reset!()
click to toggle source
# File bundler/spec_set.rb, line 204 def reset! @sorted = nil @lookup = nil end
sorted()
click to toggle source
# File bundler/spec_set.rb, line 244 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[0]}' or gem '#{cgems[1]}' and try again." end end
specs_for_dependency(dep, platform)
click to toggle source
# File bundler/spec_set.rb, line 276 def specs_for_dependency(dep, platform) specs_for_name = lookup[dep.name] return [] unless specs_for_name if platform GemHelpers.select_best_platform_match(specs_for_name, platform, force_ruby: dep.force_ruby_platform) else GemHelpers.select_best_local_platform_match(specs_for_name, force_ruby: dep.force_ruby_platform) end end
tsort_each_child(s) { |s2| ... }
click to toggle source
# File bundler/spec_set.rb, line 287 def tsort_each_child(s) s.dependencies.sort_by(&:name).each do |d| next if d.type == :development specs_for_name = lookup[d.name] next unless specs_for_name specs_for_name.each {|s2| yield s2 } end end
tsort_each_node() { |s| ... }
click to toggle source
# File bundler/spec_set.rb, line 271 def tsort_each_node # MUST sort by name for backwards compatibility @specs.sort_by(&:name).each {|s| yield s } end
valid_dependencies?(s)
click to toggle source
# File bundler/spec_set.rb, line 240 def valid_dependencies?(s) validate_deps(s) == :valid end