From 30e770ace31174dc2483e2952b919d2add7a74fe Mon Sep 17 00:00:00 2001 From: Vinicius Stock Date: Tue, 29 Oct 2024 11:56:58 -0400 Subject: [PATCH] Add some necessary guards for operating with a partial bundle (#2797) --- lib/ruby_lsp/global_state.rb | 15 ++++++++++++--- lib/ruby_lsp/requests/support/rubocop_runner.rb | 12 +++++++++++- lib/ruby_lsp/server.rb | 4 ++-- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/lib/ruby_lsp/global_state.rb b/lib/ruby_lsp/global_state.rb index 9f2a32217..7f2348930 100644 --- a/lib/ruby_lsp/global_state.rb +++ b/lib/ruby_lsp/global_state.rb @@ -21,7 +21,7 @@ class GlobalState attr_reader :encoding sig { returns(T::Boolean) } - attr_reader :supports_watching_files, :experimental_features, :supports_request_delegation + attr_reader :supports_watching_files, :experimental_features, :supports_request_delegation, :top_level_bundle sig { returns(T::Array[String]) } attr_reader :supported_resource_operations @@ -46,6 +46,15 @@ def initialize @addon_settings = T.let({}, T::Hash[String, T.untyped]) @supports_request_delegation = T.let(false, T::Boolean) @supported_resource_operations = T.let([], T::Array[String]) + @top_level_bundle = T.let( + begin + Bundler.with_original_env { Bundler.default_gemfile } + true + rescue Bundler::GemfileNotFound, Bundler::GitError + false + end, + T::Boolean, + ) end sig { params(addon_name: String).returns(T.nilable(T::Hash[Symbol, T.untyped])) } @@ -240,7 +249,7 @@ def gather_direct_dependencies sig { returns(T::Array[String]) } def gemspec_dependencies - Bundler.locked_gems.sources + (Bundler.locked_gems&.sources || []) .grep(Bundler::Source::Gemspec) .flat_map { _1.gemspec&.dependencies&.map(&:name) } end @@ -248,7 +257,7 @@ def gemspec_dependencies sig { returns(T::Array[String]) } def gather_direct_and_indirect_dependencies Bundler.with_original_env { Bundler.default_gemfile } - Bundler.locked_gems.specs.map(&:name) + Bundler.locked_gems&.specs&.map(&:name) || [] rescue Bundler::GemfileNotFound [] end diff --git a/lib/ruby_lsp/requests/support/rubocop_runner.rb b/lib/ruby_lsp/requests/support/rubocop_runner.rb index cacbc3cf1..238e933b3 100644 --- a/lib/ruby_lsp/requests/support/rubocop_runner.rb +++ b/lib/ruby_lsp/requests/support/rubocop_runner.rb @@ -1,16 +1,26 @@ # typed: strict # frozen_string_literal: true +# If there's no top level Gemfile, don't load RuboCop from a global installation +begin + Bundler.with_original_env { Bundler.default_gemfile } +rescue Bundler::GemfileNotFound + return +end + +# Ensure that RuboCop is available begin require "rubocop" rescue LoadError return end +# Ensure that RuboCop is at least version 1.4.0 begin gem("rubocop", ">= 1.4.0") rescue LoadError - raise StandardError, "Incompatible RuboCop version. Ruby LSP requires >= 1.4.0" + $stderr.puts "Incompatible RuboCop version. Ruby LSP requires >= 1.4.0" + return end if RuboCop.const_defined?(:LSP) # This condition will be removed when requiring RuboCop >= 1.61. diff --git a/lib/ruby_lsp/server.rb b/lib/ruby_lsp/server.rb index 9fe2172ff..7e6b86a3c 100644 --- a/lib/ruby_lsp/server.rb +++ b/lib/ruby_lsp/server.rb @@ -1029,7 +1029,7 @@ def type_hierarchy_subtypes(message) sig { params(message: T::Hash[Symbol, T.untyped]).void } def workspace_dependencies(message) - response = begin + response = if @global_state.top_level_bundle Bundler.with_original_env do definition = Bundler.definition dep_keys = definition.locked_deps.keys.to_set @@ -1043,7 +1043,7 @@ def workspace_dependencies(message) } end end - rescue Bundler::GemfileNotFound, Bundler::GitError + else [] end