summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThe Bundler Bot <bot@bundler.io>2017-04-04 02:16:06 +0000
committerThe Bundler Bot <bot@bundler.io>2017-04-04 02:16:06 +0000
commit324e72d5579c4ef2ff5f7b068cf01f324cc26fe1 (patch)
treed1f5981aa2b776372bab9455ceb8244568de174d
parente6b9688d6eb087babf9a8a20d4d6c09c67745cb3 (diff)
parent3d518b56a8ed9b357428afd3d252302bd0df06a8 (diff)
downloadbundler-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.rb58
-rw-r--r--lib/bundler/lockfile_parser.rb74
-rw-r--r--lib/bundler/runtime.rb3
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