diff options
author | The Bundler Bot <bot@bundler.io> | 2018-07-22 16:08:23 +0000 |
---|---|---|
committer | Colby Swandale <me@colby.fyi> | 2018-10-05 13:48:27 +1000 |
commit | 93a4a1c2b550ffc2b8eef7b4d013a29966188414 (patch) | |
tree | 57e78076afdc8ce6d91ecd19c291e1d5c2c6ca83 | |
parent | a232cd4ecf54894ea84b9e69dca7673cd65695c3 (diff) | |
download | bundler-93a4a1c2b550ffc2b8eef7b4d013a29966188414.tar.gz |
Auto merge of #6495 - bundler:segiddins/6491-extra-gem-platform-in-lockfile, r=segiddins
[Definition] Filter out unneeded gem platforms after resolving
### What was the end-user problem that led to this PR?
The problem was the lockfile would contain platform-specific gems that it didn't need
Closes https://github.com/bundler/bundler/issues/6491
### What was your diagnosis of the problem?
My diagnosis was the resolver sometimes activates platforms it doesn't need, since it can't know it won't need them
### What is your fix for the problem, implemented in this PR?
My fix is to use `SpecSet#for` to filter out gems that won't ever be used
### Why did you choose this fix out of the possible options?
I chose this fix because it isn't re-inventing the wheel!
(cherry picked from commit 7b603f39e32a466cb1a8235a963968b2103e665e)
-rw-r--r-- | lib/bundler/definition.rb | 27 | ||||
-rw-r--r-- | lib/bundler/resolver/spec_group.rb | 4 | ||||
-rw-r--r-- | spec/install/gemfile/platform_spec.rb | 143 |
3 files changed, 159 insertions, 15 deletions
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index 0a02547f0d..89ae1ce926 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -246,17 +246,22 @@ module Bundler def resolve @resolve ||= begin last_resolve = converge_locked_specs - if Bundler.frozen_bundle? - Bundler.ui.debug "Frozen, using resolution from the lockfile" - last_resolve - elsif !unlocking? && nothing_changed? - Bundler.ui.debug("Found no changes, using resolution from the lockfile") - last_resolve - else - # Run a resolve against the locally available gems - Bundler.ui.debug("Found changes from the lockfile, re-resolving dependencies because #{change_reason}") - last_resolve.merge Resolver.resolve(expanded_dependencies, index, source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve, platforms) - end + resolve = + if Bundler.frozen_bundle? + Bundler.ui.debug "Frozen, using resolution from the lockfile" + last_resolve + elsif !unlocking? && nothing_changed? + Bundler.ui.debug("Found no changes, using resolution from the lockfile") + last_resolve + else + # Run a resolve against the locally available gems + Bundler.ui.debug("Found changes from the lockfile, re-resolving dependencies because #{change_reason}") + last_resolve.merge Resolver.resolve(expanded_dependencies, index, source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve, platforms) + end + + # filter out gems that _can_ be installed on multiple platforms, but don't need + # to be + resolve.for(expand_dependencies(dependencies, true), [], false, false, false) end end diff --git a/lib/bundler/resolver/spec_group.rb b/lib/bundler/resolver/spec_group.rb index 40d5460643..34d043aed7 100644 --- a/lib/bundler/resolver/spec_group.rb +++ b/lib/bundler/resolver/spec_group.rb @@ -54,10 +54,6 @@ module Bundler dependencies.concat(metadata_dependencies).flatten end - def platforms_for_dependency_named(dependency) - __dependencies.select {|_, deps| deps.map(&:name).include? dependency }.keys - end - def ==(other) return unless other.is_a?(SpecGroup) name == other.name && diff --git a/spec/install/gemfile/platform_spec.rb b/spec/install/gemfile/platform_spec.rb index d7d4e0a53c..5858c3af0a 100644 --- a/spec/install/gemfile/platform_spec.rb +++ b/spec/install/gemfile/platform_spec.rb @@ -73,6 +73,149 @@ RSpec.describe "bundle install across platforms" do expect(the_bundle).not_to include_gems "weakling" end + it "does not keep unneeded platforms for gems that are used" do + build_repo4 do + build_gem "empyrean", "0.1.0" + build_gem "coderay", "1.1.2" + build_gem "method_source", "0.9.0" + build_gem("spoon", "0.0.6") {|s| s.add_runtime_dependency "ffi" } + build_gem "pry", "0.11.3" do |s| + s.platform = "java" + s.add_runtime_dependency "coderay", "~> 1.1.0" + s.add_runtime_dependency "method_source", "~> 0.9.0" + s.add_runtime_dependency "spoon", "~> 0.0" + end + build_gem "pry", "0.11.3" do |s| + s.add_runtime_dependency "coderay", "~> 1.1.0" + s.add_runtime_dependency "method_source", "~> 0.9.0" + end + build_gem("ffi", "1.9.23") {|s| s.platform = "java" } + build_gem("ffi", "1.9.23") + end + + simulate_platform java + + install_gemfile! <<-G + source "file://localhost/#{gem_repo4}" + + gem "empyrean", "0.1.0" + gem "pry" + G + + expect(the_bundle.lockfile).to read_as strip_whitespace(<<-L) + GEM + remote: file://localhost/#{gem_repo4}/ + specs: + coderay (1.1.2) + empyrean (0.1.0) + ffi (1.9.23-java) + method_source (0.9.0) + pry (0.11.3-java) + coderay (~> 1.1.0) + method_source (~> 0.9.0) + spoon (~> 0.0) + spoon (0.0.6) + ffi + + PLATFORMS + java + + DEPENDENCIES + empyrean (= 0.1.0) + pry + + BUNDLED WITH + #{Bundler::VERSION} + L + + bundle! "lock --add-platform ruby" + + good_lockfile = strip_whitespace(<<-L) + GEM + remote: file://localhost/#{gem_repo4}/ + specs: + coderay (1.1.2) + empyrean (0.1.0) + ffi (1.9.23-java) + method_source (0.9.0) + pry (0.11.3) + coderay (~> 1.1.0) + method_source (~> 0.9.0) + pry (0.11.3-java) + coderay (~> 1.1.0) + method_source (~> 0.9.0) + spoon (~> 0.0) + spoon (0.0.6) + ffi + + PLATFORMS + java + ruby + + DEPENDENCIES + empyrean (= 0.1.0) + pry + + BUNDLED WITH + #{Bundler::VERSION} + L + + expect(the_bundle.lockfile).to read_as good_lockfile + + bad_lockfile = strip_whitespace <<-L + GEM + remote: file://localhost/#{gem_repo4}/ + specs: + coderay (1.1.2) + empyrean (0.1.0) + ffi (1.9.23) + ffi (1.9.23-java) + method_source (0.9.0) + pry (0.11.3) + coderay (~> 1.1.0) + method_source (~> 0.9.0) + pry (0.11.3-java) + coderay (~> 1.1.0) + method_source (~> 0.9.0) + spoon (~> 0.0) + spoon (0.0.6) + ffi + + PLATFORMS + java + ruby + + DEPENDENCIES + empyrean (= 0.1.0) + pry + + BUNDLED WITH + #{Bundler::VERSION} + L + + aggregate_failures do + lockfile bad_lockfile + bundle! :install + expect(the_bundle.lockfile).to read_as good_lockfile + + lockfile bad_lockfile + bundle! :update, :all => true + expect(the_bundle.lockfile).to read_as good_lockfile + + lockfile bad_lockfile + bundle! "update ffi" + expect(the_bundle.lockfile).to read_as good_lockfile + + lockfile bad_lockfile + bundle! "update empyrean" + expect(the_bundle.lockfile).to read_as good_lockfile + + lockfile bad_lockfile + bundle! :lock + expect(the_bundle.lockfile).to read_as good_lockfile + end + end + it "works the other way with gems that have different dependencies" do simulate_platform "ruby" install_gemfile <<-G |