Skip to content

Commit

Permalink
Allow config to be passed into Indexer (#1814)
Browse files Browse the repository at this point in the history
* Allow config to be passed into Indexer

* Update lib/ruby_lsp/server.rb

Co-authored-by: Vinicius Stock <vinistock@users.noreply.github.com>

* Update lib/ruby_lsp/server.rb

Co-authored-by: Vinicius Stock <vinistock@users.noreply.github.com>

* Adjust error message

---------

Co-authored-by: Andy Waite <andyw8@users.noreply.github.com>
Co-authored-by: Vinicius Stock <vinistock@users.noreply.github.com>
  • Loading branch information
3 people authored Mar 25, 2024
1 parent 4e66f62 commit 81c81d3
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 38 deletions.
34 changes: 11 additions & 23 deletions lib/ruby_indexer/lib/ruby_indexer/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,20 +43,6 @@ def initialize
)
end

sig { void }
def load_config
return unless File.exist?(".index.yml")

config = YAML.parse_file(".index.yml")
return unless config

config_hash = config.to_ruby
validate_config!(config_hash)
apply_config(config_hash)
rescue Psych::SyntaxError => e
raise e, "Syntax error while loading .index.yml configuration: #{e.message}"
end

sig { returns(T::Array[IndexablePath]) }
def indexables
excluded_gems = @excluded_gems - @included_gems
Expand Down Expand Up @@ -158,6 +144,17 @@ def magic_comment_regex
@magic_comment_regex ||= T.let(/^#\s*#{@excluded_magic_comments.join("|")}/, T.nilable(Regexp))
end

sig { params(config: T::Hash[String, T.untyped]).void }
def apply_config(config)
validate_config!(config)

@excluded_gems.concat(config["excluded_gems"]) if config["excluded_gems"]
@included_gems.concat(config["included_gems"]) if config["included_gems"]
@excluded_patterns.concat(config["excluded_patterns"]) if config["excluded_patterns"]
@included_patterns.concat(config["included_patterns"]) if config["included_patterns"]
@excluded_magic_comments.concat(config["excluded_magic_comments"]) if config["excluded_magic_comments"]
end

private

sig { params(config: T::Hash[String, T.untyped]).void }
Expand All @@ -175,15 +172,6 @@ def validate_config!(config)
raise ArgumentError, errors.join("\n") if errors.any?
end

sig { params(config: T::Hash[String, T.untyped]).void }
def apply_config(config)
@excluded_gems.concat(config["excluded_gems"]) if config["excluded_gems"]
@included_gems.concat(config["included_gems"]) if config["included_gems"]
@excluded_patterns.concat(config["excluded_patterns"]) if config["excluded_patterns"]
@included_patterns.concat(config["included_patterns"]) if config["included_patterns"]
@excluded_magic_comments.concat(config["excluded_magic_comments"]) if config["excluded_magic_comments"]
end

sig { returns(T::Array[String]) }
def initial_excluded_gems
excluded, others = Bundler.definition.dependencies.partition do |dependency|
Expand Down
13 changes: 2 additions & 11 deletions lib/ruby_indexer/test/configuration_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def setup
end

def test_load_configuration_executes_configure_block
@config.load_config
@config.apply_config({ "excluded_patterns" => ["**/test/fixtures/**/*.rb"] })
indexables = @config.indexables

assert(indexables.none? { |indexable| indexable.full_path.include?("test/fixtures") })
Expand All @@ -21,7 +21,6 @@ def test_load_configuration_executes_configure_block
end

def test_indexables_only_includes_gem_require_paths
@config.load_config
indexables = @config.indexables

Bundler.locked_gems.specs.each do |lazy_spec|
Expand All @@ -35,7 +34,6 @@ def test_indexables_only_includes_gem_require_paths
end

def test_indexables_does_not_include_default_gem_path_when_in_bundle
@config.load_config
indexables = @config.indexables

assert(
Expand All @@ -44,7 +42,6 @@ def test_indexables_does_not_include_default_gem_path_when_in_bundle
end

def test_indexables_includes_default_gems
@config.load_config
indexables = @config.indexables.map(&:full_path)

assert_includes(indexables, "#{RbConfig::CONFIG["rubylibdir"]}/pathname.rb")
Expand All @@ -53,7 +50,6 @@ def test_indexables_includes_default_gems
end

def test_indexables_includes_project_files
@config.load_config
indexables = @config.indexables.map(&:full_path)

Dir.glob("#{Dir.pwd}/lib/**/*.rb").each do |path|
Expand All @@ -66,15 +62,13 @@ def test_indexables_includes_project_files
def test_indexables_avoids_duplicates_if_bundle_path_is_inside_project
Bundler.settings.set_global("path", "vendor/bundle")
config = Configuration.new
config.load_config

assert_includes(config.instance_variable_get(:@excluded_patterns), "#{Dir.pwd}/vendor/bundle/**/*.rb")
ensure
Bundler.settings.set_global("path", nil)
end

def test_indexables_does_not_include_gems_own_installed_files
@config.load_config
indexables = @config.indexables

assert(
Expand All @@ -95,17 +89,14 @@ def test_indexables_does_not_include_non_ruby_files_inside_rubylibdir
end

def test_paths_are_unique
@config.load_config
indexables = @config.indexables

assert_equal(indexables.uniq.length, indexables.length)
end

def test_configuration_raises_for_unknown_keys
Psych::Nodes::Document.any_instance.expects(:to_ruby).returns({ "unknown_config" => 123 })

assert_raises(ArgumentError) do
@config.load_config
@config.apply_config({ "unknown_config" => 123 })
end
end

Expand Down
30 changes: 26 additions & 4 deletions lib/ruby_lsp/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,29 @@ def run_initialized

RubyVM::YJIT.enable if defined?(RubyVM::YJIT.enable)

perform_initial_indexing
indexing_config = {}

# Need to use the workspace URI, otherwise, this will fail for people working on a project that is a symlink.
index_path = File.join(@store.workspace_uri.to_standardized_path, ".index.yml")

if File.exist?(index_path)
begin
indexing_config = YAML.parse_file(index_path).to_ruby
rescue Psych::SyntaxError => e
message = "Syntax error while loading configuration: #{e.message}"
send_message(
Notification.new(
method: "window/showMessage",
params: Interface::ShowMessageParams.new(
type: Constant::MessageType::WARNING,
message: message,
),
),
)
end
end

perform_initial_indexing(indexing_config)
check_formatter_is_available
end

Expand Down Expand Up @@ -639,11 +661,11 @@ def shutdown
Addon.addons.each(&:deactivate)
end

sig { void }
def perform_initial_indexing
sig { params(config_hash: T::Hash[String, T.untyped]).void }
def perform_initial_indexing(config_hash)
# The begin progress invocation happens during `initialize`, so that the notification is sent before we are
# stuck indexing files
RubyIndexer.configuration.load_config
RubyIndexer.configuration.apply_config(config_hash)

Thread.new do
begin
Expand Down
15 changes: 15 additions & 0 deletions test/server_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,21 @@ def test_initialize_features_with_enable_all_configuration
assert(store.features_configuration.dig(:inlayHint).enabled?(:implicitHashValue))
end

def test_handles_invalid_configuration
FileUtils.mv(".index.yml", ".index.yml.tmp")
File.write(".index.yml", "} invalid yaml")

@server.process_message({ method: "initialized" })
notification = @server.pop_response
assert_equal("window/showMessage", notification.method)
assert_match(
/Syntax error while loading configuration/,
T.cast(notification.params, RubyLsp::Interface::ShowMessageParams).message,
)
ensure
FileUtils.mv(".index.yml.tmp", ".index.yml")
end

def test_detects_rubocop_if_direct_dependency
stub_dependencies(rubocop: true, syntax_tree: false)

Expand Down

0 comments on commit 81c81d3

Please sign in to comment.