diff --git a/bundler/lib/bundler/resolver.rb b/bundler/lib/bundler/resolver.rb index 1dbf565d4676..3c361d8ea51a 100644 --- a/bundler/lib/bundler/resolver.rb +++ b/bundler/lib/bundler/resolver.rb @@ -353,9 +353,27 @@ def raise_not_found!(package) message << "\n#{other_specs_matching_message(specs, matching_part)}" end + if specs_matching_requirement.any? && (hint = platform_mismatch_hint) + message << "\n\n#{hint}" + end + raise GemNotFound, message end + def platform_mismatch_hint + locked_platforms = Bundler.locked_gems&.platforms + return unless locked_platforms + + local_platform = Bundler.local_platform + return if locked_platforms.include?(local_platform) + return if locked_platforms.any? {|p| p == Gem::Platform::RUBY } + + "Your current platform (#{local_platform}) is not included in the lockfile's platforms (#{locked_platforms.join(", ")}). " \ + "Add the current platform to the lockfile with\n`bundle lock --add-platform #{local_platform}` and try again." + rescue GemfileNotFound + nil + end + def filtered_versions_for(package) @gem_version_promoter.filter_versions(package, @all_versions[package]) end diff --git a/spec/install/gemfile/specific_platform_spec.rb b/spec/install/gemfile/specific_platform_spec.rb index 2c811a666d18..97b1d233bfaf 100644 --- a/spec/install/gemfile/specific_platform_spec.rb +++ b/spec/install/gemfile/specific_platform_spec.rb @@ -535,6 +535,41 @@ expect(err).to include(error_message).once end + it "shows a platform mismatch hint when the current platform is not in the lockfile's platforms" do + build_repo4 do + build_gem("sorbet-static", "0.5.6433") {|s| s.platform = "x86_64-linux-musl" } + end + + gemfile <<~G + source "https://gem.repo4" + + gem "sorbet-static", "0.5.6433" + G + + lockfile <<~L + GEM + remote: https://gem.repo4/ + specs: + sorbet-static (0.5.6433-x86_64-linux-musl) + + PLATFORMS + x86_64-linux-musl + + DEPENDENCIES + sorbet-static (= 0.5.6433) + + BUNDLED WITH + #{Bundler::VERSION} + L + + simulate_platform "x86_64-linux" do + bundle "install", raise_on_error: false + end + + expect(err).to include("Your current platform (x86_64-linux) is not included in the lockfile's platforms (x86_64-linux-musl)") + expect(err).to include("bundle lock --add-platform x86_64-linux") + end + it "does not resolve if the current platform does not match any of available platform specific variants for a transitive dependency" do build_repo4 do build_gem("sorbet", "0.5.6433") {|s| s.add_dependency "sorbet-static", "= 0.5.6433" } diff --git a/spec/install/gems/resolving_spec.rb b/spec/install/gems/resolving_spec.rb index f59bb70c7b3f..e6a395a66963 100644 --- a/spec/install/gems/resolving_spec.rb +++ b/spec/install/gems/resolving_spec.rb @@ -440,7 +440,9 @@ The source contains the following gems matching 'sorbet-static (= 0.5.10554)': * sorbet-static-0.5.10554-universal-darwin-21 E - expect(err).to end_with(nice_error) + expect(err).to include(nice_error) + expect(err).to include("Your current platform (aarch64-linux) is not included in the lockfile's platforms (arm64-darwin-21)") + expect(err).to include("bundle lock --add-platform aarch64-linux") end end