Skip to content

Commit

Permalink
Show doc urls for extension cops
Browse files Browse the repository at this point in the history
RuboCop 1.64 added support for passing in a config, which will then construct
the correct url for non-buildin departments that have `DocumentationBaseURL` set.
  • Loading branch information
Earlopain committed May 20, 2024
1 parent 0d310e1 commit 97e289e
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 7 deletions.
20 changes: 14 additions & 6 deletions lib/ruby_lsp/requests/support/rubocop_diagnostic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,16 @@ def to_lsp_code_actions
code_actions
end

sig { returns(Interface::Diagnostic) }
def to_lsp_diagnostic
sig { params(config: RuboCop::Config).returns(Interface::Diagnostic) }
def to_lsp_diagnostic(config)
# highlighted_area contains the begin and end position of the first line
# This ensures that multiline offenses don't clutter the editor
highlighted = @offense.highlighted_area
Interface::Diagnostic.new(
message: message,
source: "RuboCop",
code: @offense.cop_name,
code_description: code_description,
code_description: code_description(config),
severity: severity,
range: Interface::Range.new(
start: Interface::Position.new(
Expand Down Expand Up @@ -80,9 +80,17 @@ def severity
RUBOCOP_TO_LSP_SEVERITY[@offense.severity.name]
end

sig { returns(T.nilable(Interface::CodeDescription)) }
def code_description
doc_url = RuboCopRunner.find_cop_by_name(@offense.cop_name)&.documentation_url
sig { params(config: RuboCop::Config).returns(T.nilable(Interface::CodeDescription)) }
def code_description(config)
cop = RuboCopRunner.find_cop_by_name(@offense.cop_name)
return unless cop

doc_url = if cop.method(:documentation_url).parameters.none?
# Rubocop < 1.64
cop.documentation_url
else
cop.documentation_url(config)
end
Interface::CodeDescription.new(href: doc_url) if doc_url
end

Expand Down
2 changes: 1 addition & 1 deletion lib/ruby_lsp/requests/support/rubocop_formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def run_diagnostic(uri, document)
@diagnostic_runner.run(filename, document.source)

@diagnostic_runner.offenses.map do |offense|
Support::RuboCopDiagnostic.new(document, offense, uri).to_lsp_diagnostic
Support::RuboCopDiagnostic.new(document, offense, uri).to_lsp_diagnostic(@diagnostic_runner.config_for_pwd)
end
end
end
Expand Down
4 changes: 4 additions & 0 deletions lib/ruby_lsp/requests/support/rubocop_runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ class ConfigurationError < StandardError; end
sig { returns(T::Array[RuboCop::Cop::Offense]) }
attr_reader :offenses

sig { returns(::RuboCop::Config) }
attr_reader :config_for_pwd

DEFAULT_ARGS = T.let(
[
"--stderr", # Print any output to stderr so that our stdout does not get polluted
Expand Down Expand Up @@ -78,6 +81,7 @@ def initialize(*args)
args += DEFAULT_ARGS
rubocop_options = ::RuboCop::Options.new.parse(args).first
config_store = ::RuboCop::ConfigStore.new
@config_for_pwd = T.let(config_store.for_pwd, ::RuboCop::Config)

super(rubocop_options, config_store)
end
Expand Down
100 changes: 100 additions & 0 deletions test/expectations/diagnostics/rubocop_extension_cop.exp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
{
"result": [
{
"range": {
"start": {
"line": 5,
"character": 4
},
"end": {
"line": 5,
"character": 25
}
},
"severity": 3,
"code": "Minitest/AssertEmptyLiteral",
"codeDescription": {
"href": "https://docs.rubocop.org/rubocop-minitest/cops_minitest.html#minitestassertemptyliteral"
},
"source": "RuboCop",
"message": "Minitest/AssertEmptyLiteral: Prefer using `assert_empty(foo)`.",
"data": {
"correctable": true,
"code_actions": [
{
"title": "Autocorrect Minitest/AssertEmptyLiteral",
"kind": "quickfix",
"isPreferred": true,
"edit": {
"documentChanges": [
{
"textDocument": {
"uri": "file:///fake",
"version": null
},
"edits": [
{
"range": {
"start": {
"line": 5,
"character": 4
},
"end": {
"line": 5,
"character": 16
}
},
"newText": "assert_empty"
},
{
"range": {
"start": {
"line": 5,
"character": 17
},
"end": {
"line": 5,
"character": 24
}
},
"newText": "foo"
}
]
}
]
}
},
{
"title": "Disable Minitest/AssertEmptyLiteral for this line",
"kind": "quickfix",
"edit": {
"documentChanges": [
{
"textDocument": {
"uri": "file:///fake",
"version": null
},
"edits": [
{
"range": {
"start": {
"line": 5,
"character": 25
},
"end": {
"line": 5,
"character": 25
}
},
"newText": " # rubocop:disable Minitest/AssertEmptyLiteral"
}
]
}
]
}
}
]
}
}
]
}
8 changes: 8 additions & 0 deletions test/fixtures/rubocop_extension_cop.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# typed: true
# frozen_string_literal: true

class ExampleTest < Minitest::Test
def test_public
assert_equal([], foo)
end
end

0 comments on commit 97e289e

Please sign in to comment.