From 7775e261be952d3eb5aeb067932e98472fdd4d77 Mon Sep 17 00:00:00 2001 From: Samuel Giddins Date: Fri, 31 Mar 2017 12:43:39 -0500 Subject: [Runtime] Suggest `bundle install` instead of just `bundle` --- lib/bundler/runtime.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bundler/runtime.rb b/lib/bundler/runtime.rb index 45f445aec1..fdd3d227e3 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 -- cgit v1.2.1 From 3d2a6fe2b38c5f01c6352bc356091845a1435a5b Mon Sep 17 00:00:00 2001 From: Samuel Giddins Date: Fri, 31 Mar 2017 12:44:18 -0500 Subject: [Definition] Only print change reason if it is non-empty --- lib/bundler/definition.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index a4aebe95ed..8d8e50aead 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -464,7 +464,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? -- cgit v1.2.1 From 9d18ac9c83f2922a3833796b5a98872af86fbf7a Mon Sep 17 00:00:00 2001 From: Samuel Giddins Date: Fri, 31 Mar 2017 12:47:24 -0500 Subject: [Definition] Move #fixup_dependency_types! into #converge_dependencies --- lib/bundler/definition.rb | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index 8d8e50aead..d6bbb97606 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -119,23 +119,6 @@ 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 @@ -697,16 +680,24 @@ 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 + + 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 -- cgit v1.2.1 From c91e77cab2d29f3e0ecb721430ee93c7c86f0859 Mon Sep 17 00:00:00 2001 From: Samuel Giddins Date: Fri, 31 Mar 2017 13:06:25 -0500 Subject: [LockfileParser] Use a single name-version regexp --- lib/bundler/lockfile_parser.rb | 66 +++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/lib/bundler/lockfile_parser.rb b/lib/bundler/lockfile_parser.rb index 8d89b8b4a3..344f3a58ae 100644 --- a/lib/bundler/lockfile_parser.rb +++ b/lib/bundler/lockfile_parser.rb @@ -171,43 +171,45 @@ 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}$/ + NAME_VERSION = /^( {2}| {4}| {6})(?! )(.*?)(?: \(([^-]*)(?:-(.*))?\))?(!)?$/ 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 +218,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 -- cgit v1.2.1 From 6e25694cafeb697c200d981d5bced45e8b693cca Mon Sep 17 00:00:00 2001 From: Samuel Giddins Date: Fri, 31 Mar 2017 13:17:07 -0500 Subject: [Runtime] Avoid re-locking when not unlocking and nothing has changed --- lib/bundler/definition.rb | 16 ++++++++++------ lib/bundler/runtime.rb | 1 + 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index d6bbb97606..99cf1ee4e5 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -123,7 +123,7 @@ module Bundler 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. @@ -226,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 @@ -295,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] @@ -526,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 diff --git a/lib/bundler/runtime.rb b/lib/bundler/runtime.rb index fdd3d227e3..6ccb0d89b5 100644 --- a/lib/bundler/runtime.rb +++ b/lib/bundler/runtime.rb @@ -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 -- cgit v1.2.1 From 47959cf97ca82292fc037f5118c89820446f4a35 Mon Sep 17 00:00:00 2001 From: Samuel Giddins Date: Mon, 3 Apr 2017 21:10:20 -0500 Subject: [LockfileParser] Add comments to NAME_PATTERN --- lib/bundler/lockfile_parser.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/bundler/lockfile_parser.rb b/lib/bundler/lockfile_parser.rb index 344f3a58ae..dbf8926690 100644 --- a/lib/bundler/lockfile_parser.rb +++ b/lib/bundler/lockfile_parser.rb @@ -171,7 +171,15 @@ module Bundler end end - NAME_VERSION = /^( {2}| {4}| {6})(?! )(.*?)(?: \(([^-]*)(?:-(.*))?\))?(!)?$/ + 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) return unless line =~ NAME_VERSION -- cgit v1.2.1 From 3d518b56a8ed9b357428afd3d252302bd0df06a8 Mon Sep 17 00:00:00 2001 From: Samuel Giddins Date: Mon, 3 Apr 2017 21:11:46 -0500 Subject: [Definition] Add comment explaining why we need to override a deps type --- lib/bundler/definition.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index 99cf1ee4e5..e31de3d38a 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -694,6 +694,12 @@ module Bundler 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 -- cgit v1.2.1