From 87928722f5245e8da1bac11ccbda7ed07cf1c387 Mon Sep 17 00:00:00 2001 From: Vinicius Stock Date: Mon, 6 Jan 2025 10:58:01 -0500 Subject: [PATCH] Handle missing specs when listing transitive dependencies (#3012) ### Motivation This PR fixes a mistake made in #2937. We cannot invoke `to_spec` without rescuing `Gem::MissingSpecError` because that gets raised whenever there's a gem that doesn't match platform constraints. ### Implementation Added the missing rescue. ### Automated Tests Added a test that fails before the fix so that we catch this next time. --- .../lib/ruby_indexer/configuration.rb | 8 ++++- lib/ruby_indexer/test/configuration_test.rb | 31 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/lib/ruby_indexer/lib/ruby_indexer/configuration.rb b/lib/ruby_indexer/lib/ruby_indexer/configuration.rb index 2c9a65871..434c58b76 100644 --- a/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +++ b/lib/ruby_indexer/lib/ruby_indexer/configuration.rb @@ -273,7 +273,13 @@ def initial_excluded_gems end others.concat(this_gem.to_spec.dependencies) if this_gem - others.concat(others.filter_map { |d| d.to_spec&.dependencies }.flatten) + others.concat( + others.filter_map do |d| + d.to_spec&.dependencies + rescue Gem::MissingSpecError + nil + end.flatten, + ) others.uniq! others.map!(&:name) diff --git a/lib/ruby_indexer/test/configuration_test.rb b/lib/ruby_indexer/test/configuration_test.rb index 13f525c9a..a4b648702 100644 --- a/lib/ruby_indexer/test/configuration_test.rb +++ b/lib/ruby_indexer/test/configuration_test.rb @@ -204,5 +204,36 @@ def test_transitive_dependencies_for_non_dev_gems_are_not_excluded end end end + + def test_does_not_fail_if_there_are_missing_specs_due_to_platform_constraints + Dir.mktmpdir do |dir| + Dir.chdir(dir) do + File.write(File.join(dir, "Gemfile"), <<~RUBY) + source "https://rubygems.org" + gem "ruby-lsp", path: "#{Bundler.root}" + + platforms :windows do + gem "tzinfo" + gem "tzinfo-data" + end + RUBY + + Bundler.with_unbundled_env do + capture_subprocess_io { system("bundle install") } + + _stdout, stderr = capture_subprocess_io do + script = [ + "require \"ruby_lsp/internal\"", + "RubyIndexer::Configuration.new.indexable_uris", + ].join(";") + + system("bundle exec ruby -e '#{script}'") + end + + assert_empty(stderr) + end + end + end + end end end