diff options
author | The Bundler Bot <bot@bundler.io> | 2017-04-04 02:16:06 +0000 |
---|---|---|
committer | The Bundler Bot <bot@bundler.io> | 2017-04-04 02:16:06 +0000 |
commit | 324e72d5579c4ef2ff5f7b068cf01f324cc26fe1 (patch) | |
tree | d1f5981aa2b776372bab9455ceb8244568de174d | |
parent | e6b9688d6eb087babf9a8a20d4d6c09c67745cb3 (diff) | |
parent | 3d518b56a8ed9b357428afd3d252302bd0df06a8 (diff) | |
download | bundler-324e72d5579c4ef2ff5f7b068cf01f324cc26fe1.tar.gz |
Auto merge of #5556 - bundler:seg-zoom-zoom, r=indirect
Sam tries to make bundler fast part 4372894632785
-rw-r--r-- | lib/bundler/definition.rb | 58 | ||||
-rw-r--r-- | lib/bundler/lockfile_parser.rb | 74 | ||||
-rw-r--r-- | lib/bundler/runtime.rb | 3 |
3 files changed, 73 insertions, 62 deletions
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index a4aebe95ed..e31de3d38a 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -119,28 +119,11 @@ module Bundler @local_changes = converge_locals @requires = compute_requires - - fixup_dependency_types! - end - - def fixup_dependency_types! - # XXX This is a temporary workaround for a bug when using rubygems 1.8.15 - # where Gem::Dependency#== matches Gem::Dependency#type. As the lockfile - # doesn't carry a notion of the dependency type, if you use - # add_development_dependency in a gemspec that's loaded with the gemspec - # directive, the lockfile dependencies and resolved dependencies end up - # with a mismatch on #type. - # Test coverage to catch a regression on this is in gemspec_spec.rb - @dependencies.each do |d| - if ld = @locked_deps[d.name] - ld.instance_variable_set(:@type, d.type) - end - end end def create_gem_version_promoter locked_specs = - if @unlocking && @locked_specs.empty? && !@lockfile_contents.empty? + if unlocking? && @locked_specs.empty? && !@lockfile_contents.empty? # Definition uses an empty set of locked_specs to indicate all gems # are unlocked, but GemVersionPromoter needs the locked_specs # for conservative comparison. @@ -243,7 +226,7 @@ module Bundler def resolve @resolve ||= begin last_resolve = converge_locked_specs - if Bundler.settings[:frozen] || (!@unlocking && nothing_changed?) + if Bundler.settings[:frozen] || (!unlocking? && nothing_changed?) Bundler.ui.debug("Found no changes, using resolution from the lockfile") last_resolve else @@ -312,7 +295,7 @@ module Bundler end end - preserve_unknown_sections ||= !updating_major && (Bundler.settings[:frozen] || !@unlocking) + preserve_unknown_sections ||= !updating_major && (Bundler.settings[:frozen] || !unlocking?) return if lockfiles_equal?(@lockfile_contents, contents, preserve_unknown_sections) if Bundler.settings[:frozen] @@ -464,7 +447,8 @@ module Bundler changed << "* #{name} from `#{gemfile_source_name}` to `#{lockfile_source_name}`" end - msg << "\n\n#{change_reason.split(", ").join("\n")}\n" + reason = change_reason + msg << "\n\n#{reason.split(", ").join("\n")}\n" unless reason.strip.empty? msg << "\n\nYou have added to the Gemfile:\n" << added.join("\n") if added.any? msg << "\n\nYou have deleted from the Gemfile:\n" << deleted.join("\n") if deleted.any? msg << "\n\nYou have changed in the Gemfile:\n" << changed.join("\n") if changed.any? @@ -542,14 +526,18 @@ module Bundler attr_reader :sources private :sources - private - def nothing_changed? !@source_changes && !@dependency_changes && !@new_platform && !@path_changes && !@local_changes end + def unlocking? + @unlocking + end + + private + def change_reason - if @unlocking + if unlocking? unlock_reason = @unlock.reject {|_k, v| Array(v).empty? }.map do |k, v| if v == true k.to_s @@ -696,16 +684,30 @@ module Bundler end end + changes = false # We want to know if all match, but don't want to check all entries # This means we need to return false if any dependency doesn't match # the lock or doesn't exist in the lock. - @dependencies.any? do |dependency| - locked_dep = @locked_deps[dependency.name] - next true if locked_dep.nil? + @dependencies.each do |dependency| + unless locked_dep = @locked_deps[dependency.name] + changes = true + next + end + + # Gem::Dependency#== matches Gem::Dependency#type. As the lockfile + # doesn't carry a notion of the dependency type, if you use + # add_development_dependency in a gemspec that's loaded with the gemspec + # directive, the lockfile dependencies and resolved dependencies end up + # with a mismatch on #type. Work around that by setting the type on the + # dep from the lockfile. + locked_dep.instance_variable_set(:@type, dependency.type) + # We already know the name matches from the hash lookup # so we only need to check the requirement now - dependency.requirement != locked_dep.requirement + changes ||= dependency.requirement != locked_dep.requirement end + + changes end # Remove elements from the locked specs that are expired. This will most diff --git a/lib/bundler/lockfile_parser.rb b/lib/bundler/lockfile_parser.rb index 8d89b8b4a3..dbf8926690 100644 --- a/lib/bundler/lockfile_parser.rb +++ b/lib/bundler/lockfile_parser.rb @@ -171,43 +171,53 @@ module Bundler end end - NAME_VERSION = '(?! )(.*?)(?: \(([^-]*)(?:-(.*))?\))?'.freeze - NAME_VERSION_2 = /^ {2}#{NAME_VERSION}(!)?$/ - NAME_VERSION_4 = /^ {4}#{NAME_VERSION}$/ - NAME_VERSION_6 = /^ {6}#{NAME_VERSION}$/ + space = / / + NAME_VERSION = / + ^(#{space}{2}|#{space}{4}|#{space}{6})(?!#{space}) # Exactly 2, 4, or 6 spaces at the start of the line + (.*?) # Name + (?:#{space}\(([^-]*) # Space, followed by version + (?:-(.*))?\))? # Optional platform + (!)? # Optional pinned marker + $ # Line end + /xo def parse_dependency(line) - if line =~ NAME_VERSION_2 - name = $1 - version = $2 - pinned = $4 - version = version.split(",").map(&:strip) if version - - dep = Bundler::Dependency.new(name, version) - - if pinned && dep.name != "bundler" - spec = @specs.find {|_, v| v.name == dep.name } - dep.source = spec.last.source if spec - - # Path sources need to know what the default name / version - # to use in the case that there are no gemspecs present. A fake - # gemspec is created based on the version set on the dependency - # TODO: Use the version from the spec instead of from the dependency - if version && version.size == 1 && version.first =~ /^\s*= (.+)\s*$/ && dep.source.is_a?(Bundler::Source::Path) - dep.source.name = name - dep.source.version = $1 - end + return unless line =~ NAME_VERSION + spaces = $1 + return unless spaces.size == 2 + name = $2 + version = $3 + pinned = $5 + + version = version.split(",").map(&:strip) if version + + dep = Bundler::Dependency.new(name, version) + + if pinned && dep.name != "bundler" + spec = @specs.find {|_, v| v.name == dep.name } + dep.source = spec.last.source if spec + + # Path sources need to know what the default name / version + # to use in the case that there are no gemspecs present. A fake + # gemspec is created based on the version set on the dependency + # TODO: Use the version from the spec instead of from the dependency + if version && version.size == 1 && version.first =~ /^\s*= (.+)\s*$/ && dep.source.is_a?(Bundler::Source::Path) + dep.source.name = name + dep.source.version = $1 end - - @dependencies[dep.name] = dep end + + @dependencies[dep.name] = dep end def parse_spec(line) - if line =~ NAME_VERSION_4 - name = $1 - version = $2 - platform = $3 + return unless line =~ NAME_VERSION + spaces = $1 + name = $2 + version = $3 + platform = $4 + + if spaces.size == 4 version = Gem::Version.new(version) platform = platform ? Gem::Platform.new(platform) : Gem::Platform::RUBY @current_spec = LazySpecification.new(name, version, platform) @@ -216,9 +226,7 @@ module Bundler # Avoid introducing multiple copies of the same spec (caused by # duplicate GIT sections) @specs[@current_spec.identifier] ||= @current_spec - elsif line =~ NAME_VERSION_6 - name = $1 - version = $2 + elsif spaces.size == 6 version = version.split(",").map(&:strip) if version dep = Gem::Dependency.new(name, version) @current_spec.dependencies << dep diff --git a/lib/bundler/runtime.rb b/lib/bundler/runtime.rb index 45f445aec1..6ccb0d89b5 100644 --- a/lib/bundler/runtime.rb +++ b/lib/bundler/runtime.rb @@ -24,7 +24,7 @@ module Bundler # Activate the specs load_paths = specs.map do |spec| unless spec.loaded_from - raise GemNotFound, "#{spec.full_name} is missing. Run `bundle` to get it." + raise GemNotFound, "#{spec.full_name} is missing. Run `bundle install` to get it." end if (activated_spec = Bundler.rubygems.loaded_specs(spec.name)) && activated_spec.version != spec.version @@ -127,6 +127,7 @@ module Bundler definition_method :requires def lock(opts = {}) + return if @definition.nothing_changed? && !@definition.unlocking? @definition.lock(Bundler.default_lockfile, opts[:preserve_unknown_sections]) end |