diff options
author | The Bundler Bot <bot@bundler.io> | 2017-04-15 16:29:05 +0000 |
---|---|---|
committer | The Bundler Bot <bot@bundler.io> | 2017-04-15 16:29:05 +0000 |
commit | a181b12ccd66d667dbb5de48023c7b55f220693b (patch) | |
tree | cde93c9e83f68027006ac966555ddd58c3c9a7a9 | |
parent | 7ce45d7702479542975a98762cc33982d8fb6ee7 (diff) | |
parent | 0a516eaf5bb7a9bb50189012e2552d4d3087ae60 (diff) | |
download | bundler-a181b12ccd66d667dbb5de48023c7b55f220693b.tar.gz |
Auto merge of #5585 - bundler:seg-spec-set-perf, r=segiddins
Speed up spec sets
Nothing major, but why not ¯\_(ツ)_/¯
Closes #5057
-rw-r--r-- | lib/bundler/definition.rb | 3 | ||||
-rw-r--r-- | lib/bundler/index.rb | 12 | ||||
-rw-r--r-- | lib/bundler/rubygems_ext.rb | 11 | ||||
-rw-r--r-- | lib/bundler/spec_set.rb | 22 | ||||
-rw-r--r-- | spec/support/builders.rb | 2 |
5 files changed, 31 insertions, 19 deletions
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index 6d3ad4f63a..3e5b1bc447 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -669,11 +669,12 @@ module Bundler end def converge_dependencies + frozen = Bundler.settings[:frozen] (@dependencies + @locked_deps.values).each do |dep| locked_source = @locked_deps[dep.name] # This is to make sure that if bundler is installing in deployment mode and # after locked_source and sources don't match, we still use locked_source. - if Bundler.settings[:frozen] && !locked_source.nil? && + if frozen && !locked_source.nil? && locked_source.respond_to?(:source) && locked_source.source.instance_of?(Source::Path) && locked_source.source.path.exist? dep.source = locked_source.source elsif dep.source diff --git a/lib/bundler/index.rb b/lib/bundler/index.rb index 373f6132af..5f54796fa2 100644 --- a/lib/bundler/index.rb +++ b/lib/bundler/index.rb @@ -58,17 +58,23 @@ module Bundler # Search this index's specs, and any source indexes that this index knows # about, returning all of the results. def search(query, base = nil) + sort_specs(unsorted_search(query, base)) + end + + def unsorted_search(query, base) results = local_search(query, base) - seen = results.map(&:full_name).to_set + + seen = results.map(&:full_name).to_set unless @sources.empty? @sources.each do |source| - source.search(query, base).each do |spec| + source.unsorted_search(query, base).each do |spec| results << spec if seen.add?(spec.full_name) end end - sort_specs(results) + results end + protected :unsorted_search def self.sort_specs(specs) specs.sort_by do |s| diff --git a/lib/bundler/rubygems_ext.rb b/lib/bundler/rubygems_ext.rb index 7293e7cfc7..a0f8fa848b 100644 --- a/lib/bundler/rubygems_ext.rb +++ b/lib/bundler/rubygems_ext.rb @@ -151,7 +151,7 @@ module Gem def to_lock out = String.new(" #{name}") - unless requirement == Gem::Requirement.default + unless requirement.none? reqs = requirement.requirements.map {|o, v| "#{o} #{v}" }.sort.reverse out << " (#{reqs.join(", ")})" end @@ -169,11 +169,16 @@ module Gem end class Requirement - # Backport of performance enhancement added to Rubygems 1.4 + # Backport of performance enhancement added to RubyGems 1.4 def none? - @none ||= (to_s == ">= 0") + # note that it might be tempting to replace with with RubyGems 2.0's + # improved implementation. Don't. It requires `DefaultRequirement` to be + # defined, and more importantantly, these overrides are not used when the + # running RubyGems defines these methods + to_s == ">= 0" end unless allocate.respond_to?(:none?) + # Backport of performance enhancement added to RubyGems 2.2 def exact? return false unless @requirements.size == 1 @requirements[0][0] == "=" diff --git a/lib/bundler/spec_set.rb b/lib/bundler/spec_set.rb index 67bbe3060c..5fd6bd606f 100644 --- a/lib/bundler/spec_set.rb +++ b/lib/bundler/spec_set.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require "tsort" require "forwardable" +require "set" module Bundler class SpecSet @@ -11,20 +12,18 @@ module Bundler def_delegators :sorted, :each def initialize(specs) - @specs = specs.sort_by(&:name) + @specs = specs end def for(dependencies, skip = [], check = false, match_current_platform = false, raise_on_missing = true) - handled = {} + handled = Set.new deps = dependencies.dup specs = [] skip += ["bundler"] loop do break unless dep = deps.shift - next if handled[dep] || skip.include?(dep.name) - - handled[dep] = true + next if !handled.add?(dep) || skip.include?(dep.name) if spec = spec_for_dependency(dep, match_current_platform) specs << spec @@ -83,14 +82,15 @@ module Bundler next s unless s.is_a?(LazySpecification) s.source.dependency_names = deps if s.source.respond_to?(:dependency_names=) spec = s.__materialize__ - if missing_specs - missing_specs << s unless spec - else - raise GemNotFound, "Could not find #{s.full_name} in any of the sources" unless spec + unless spec + unless missing_specs + raise GemNotFound, "Could not find #{s.full_name} in any of the sources" + end + missing_specs << s end - spec if spec + spec end - SpecSet.new(materialized.compact) + SpecSet.new(missing_specs ? materialized.compact : materialized) end # Materialize for all the specs in the spec set, regardless of what platform they're for diff --git a/spec/support/builders.rb b/spec/support/builders.rb index bda808c0b2..75aed0e7ee 100644 --- a/spec/support/builders.rb +++ b/spec/support/builders.rb @@ -205,7 +205,7 @@ module Spec else specs = Gem.source_index.find_name('') end - specs.each do |gem| + specs.sort_by(&:name).each do |gem| puts gem.full_name end Y |