summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThe Bundler Bot <bot@bundler.io>2018-07-22 16:08:23 +0000
committerColby Swandale <me@colby.fyi>2018-10-05 13:48:27 +1000
commit93a4a1c2b550ffc2b8eef7b4d013a29966188414 (patch)
tree57e78076afdc8ce6d91ecd19c291e1d5c2c6ca83
parenta232cd4ecf54894ea84b9e69dca7673cd65695c3 (diff)
downloadbundler-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.rb27
-rw-r--r--lib/bundler/resolver/spec_group.rb4
-rw-r--r--spec/install/gemfile/platform_spec.rb143
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