standard 1.37.0 → 1.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +5 -1
- data/.standard.yml +1 -1
- data/CHANGELOG.md +17 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +10 -1
- data/config/default.yml +1 -2
- data/config/ruby-3.2.yml +1 -1
- data/config/ruby-3.3.yml +4 -0
- data/lib/ruby_lsp/standard/addon.rb +58 -0
- data/lib/ruby_lsp/standard/wraps_built_in_lsp_standardizer.rb +36 -0
- data/lib/standard/base/plugin.rb +2 -0
- data/lib/standard/lsp/diagnostic.rb +168 -0
- data/lib/standard/lsp/logger.rb +3 -2
- data/lib/standard/lsp/routes.rb +1 -34
- data/lib/standard/lsp/server.rb +2 -1
- data/lib/standard/lsp/standardizer.rb +19 -54
- data/lib/standard/lsp/stdin_rubocop_runner.rb +61 -0
- data/lib/standard/plugin/merges_plugins_into_rubocop_config.rb +1 -1
- data/lib/standard/version.rb +1 -1
- data/standard.gemspec +1 -1
- metadata +9 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b15a7085baa8421e82fec821f8562214b001cfe17bd6a02f7a061bc892f047fa
|
|
4
|
+
data.tar.gz: f67e28527faebd95dc452a57f8994523c11f2f3e5be6c28da458d374852c5f9e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d6040219e08da54f2ccfff731e787228e9226b20ba0380530513a41b0f29946eecf1503e41cd93e8f6beca3259258a713ad2f6815099325074a11ec2fcaf8915
|
|
7
|
+
data.tar.gz: 6749ee4c00f5cad2c52b774e96048f82769046a9527dccc6515e0ee75ed274987d72f11d6422407c747ceed15c8b9c12a884c94573657af07811d7f013889135
|
data/.github/workflows/test.yml
CHANGED
data/.standard.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
## 1.39.0
|
|
6
|
+
|
|
7
|
+
* Add support for LSP Code Actions / Quick Fix under Ruby LSP [#636](https://github.com/standardrb/standard/pull/636)
|
|
8
|
+
|
|
9
|
+
## 1.38.0
|
|
10
|
+
|
|
11
|
+
* Update minimum Ruby version to 3.0
|
|
12
|
+
* @koic backported a line column bug in our LSP
|
|
13
|
+
[#635](https://github.com/standardrb/standard/pull/635)
|
|
14
|
+
* Implement a basic [Ruby LSP
|
|
15
|
+
add-on](https://github.com/Shopify/ruby-lsp/blob/main/ADDONS.md), which means
|
|
16
|
+
users would no longer need to install [our custom VS Code
|
|
17
|
+
extension](https://marketplace.visualstudio.com/items?itemName=testdouble.vscode-standard-ruby)
|
|
18
|
+
[#630](https://github.com/standardrb/standard/pull/630)
|
|
19
|
+
|
|
3
20
|
## 1.37.0
|
|
4
21
|
|
|
5
22
|
* Updates rubocop to [1.64.1](https://github.com/rubocop/rubocop/releases/tag/v1.64.1)
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
standard (1.
|
|
4
|
+
standard (1.39.0)
|
|
5
5
|
language_server-protocol (~> 3.17.0.2)
|
|
6
6
|
lint_roller (~> 1.0)
|
|
7
7
|
rubocop (~> 1.64.0)
|
|
@@ -21,10 +21,12 @@ GEM
|
|
|
21
21
|
rake (>= 0.9.2.2)
|
|
22
22
|
method_source (1.0.0)
|
|
23
23
|
minitest (5.20.0)
|
|
24
|
+
mutex_m (0.2.0)
|
|
24
25
|
parallel (1.23.0)
|
|
25
26
|
parser (3.3.0.5)
|
|
26
27
|
ast (~> 2.4.1)
|
|
27
28
|
racc
|
|
29
|
+
prism (0.27.0)
|
|
28
30
|
racc (1.7.1)
|
|
29
31
|
rainbow (3.1.1)
|
|
30
32
|
rake (13.0.6)
|
|
@@ -46,6 +48,10 @@ GEM
|
|
|
46
48
|
rubocop-performance (1.21.0)
|
|
47
49
|
rubocop (>= 1.48.1, < 2.0)
|
|
48
50
|
rubocop-ast (>= 1.31.1, < 2.0)
|
|
51
|
+
ruby-lsp (0.16.6)
|
|
52
|
+
language_server-protocol (~> 3.17.0)
|
|
53
|
+
prism (>= 0.23.0, < 0.28)
|
|
54
|
+
sorbet-runtime (>= 0.5.10782)
|
|
49
55
|
ruby-progressbar (1.13.0)
|
|
50
56
|
simplecov (0.22.0)
|
|
51
57
|
docile (~> 1.1)
|
|
@@ -53,6 +59,7 @@ GEM
|
|
|
53
59
|
simplecov_json_formatter (~> 0.1)
|
|
54
60
|
simplecov-html (0.12.3)
|
|
55
61
|
simplecov_json_formatter (0.1.4)
|
|
62
|
+
sorbet-runtime (0.5.11385)
|
|
56
63
|
standard-custom (1.0.2)
|
|
57
64
|
lint_roller (~> 1.0)
|
|
58
65
|
rubocop (~> 1.50)
|
|
@@ -69,7 +76,9 @@ DEPENDENCIES
|
|
|
69
76
|
bundler
|
|
70
77
|
m
|
|
71
78
|
minitest (~> 5.0)
|
|
79
|
+
mutex_m
|
|
72
80
|
rake (~> 13.0)
|
|
81
|
+
ruby-lsp
|
|
73
82
|
simplecov
|
|
74
83
|
standard!
|
|
75
84
|
|
data/config/default.yml
CHANGED
data/config/ruby-3.2.yml
CHANGED
data/config/ruby-3.3.yml
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require "standard"
|
|
2
|
+
require_relative "wraps_built_in_lsp_standardizer"
|
|
3
|
+
|
|
4
|
+
module RubyLsp
|
|
5
|
+
module Standard
|
|
6
|
+
class Addon < ::RubyLsp::Addon
|
|
7
|
+
def name
|
|
8
|
+
"Standard Ruby"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def activate(global_state, message_queue)
|
|
12
|
+
@logger = ::Standard::Lsp::Logger.new(prefix: "[Standard Ruby]")
|
|
13
|
+
@logger.puts "Activating Standard Ruby LSP addon v#{::Standard::VERSION}"
|
|
14
|
+
RuboCop::LSP.enable
|
|
15
|
+
@wraps_built_in_lsp_standardizer = WrapsBuiltinLspStandardizer.new
|
|
16
|
+
global_state.register_formatter("standard", @wraps_built_in_lsp_standardizer)
|
|
17
|
+
register_additional_file_watchers(global_state, message_queue)
|
|
18
|
+
@logger.puts "Initialized Standard Ruby LSP addon #{::Standard::VERSION}"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def deactivate
|
|
22
|
+
@wraps_built_in_lsp_standardizer = nil
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def register_additional_file_watchers(global_state, message_queue)
|
|
26
|
+
return unless global_state.supports_watching_files
|
|
27
|
+
|
|
28
|
+
message_queue << Request.new(
|
|
29
|
+
id: "standard-file-watcher",
|
|
30
|
+
method: "client/registerCapability",
|
|
31
|
+
params: Interface::RegistrationParams.new(
|
|
32
|
+
registrations: [
|
|
33
|
+
Interface::Registration.new(
|
|
34
|
+
id: "workspace/didChangeWatchedFilesStandard",
|
|
35
|
+
method: "workspace/didChangeWatchedFiles",
|
|
36
|
+
register_options: Interface::DidChangeWatchedFilesRegistrationOptions.new(
|
|
37
|
+
watchers: [
|
|
38
|
+
Interface::FileSystemWatcher.new(
|
|
39
|
+
glob_pattern: "**/.standard.yml",
|
|
40
|
+
kind: Constant::WatchKind::CREATE | Constant::WatchKind::CHANGE | Constant::WatchKind::DELETE
|
|
41
|
+
)
|
|
42
|
+
]
|
|
43
|
+
)
|
|
44
|
+
)
|
|
45
|
+
]
|
|
46
|
+
)
|
|
47
|
+
)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def workspace_did_change_watched_files(changes)
|
|
51
|
+
if changes.any? { |change| change[:uri].end_with?(".standard.yml") }
|
|
52
|
+
@wraps_built_in_lsp_standardizer.init!
|
|
53
|
+
@logger.puts "Re-initialized Standard Ruby LSP addon #{::Standard::VERSION} due to .standard.yml file change"
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module RubyLsp
|
|
2
|
+
module Standard
|
|
3
|
+
class WrapsBuiltinLspStandardizer
|
|
4
|
+
include RubyLsp::Requests::Support::Formatter
|
|
5
|
+
def initialize
|
|
6
|
+
init!
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def init!
|
|
10
|
+
@standardizer = ::Standard::Lsp::Standardizer.new(
|
|
11
|
+
::Standard::BuildsConfig.new.call([])
|
|
12
|
+
)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def run_formatting(uri, document)
|
|
16
|
+
@standardizer.format(uri_to_path(uri), document.source)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def run_diagnostic(uri, document)
|
|
20
|
+
@standardizer.offenses(uri_to_path(uri), document.source, document.encoding)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
# duplicated from: lib/standard/lsp/routes.rb
|
|
26
|
+
# modified to incorporate Ruby LSP's to_standardized_path method
|
|
27
|
+
def uri_to_path(uri)
|
|
28
|
+
if uri.respond_to?(:to_standardized_path) && !(standardized_path = uri.to_standardized_path).nil?
|
|
29
|
+
standardized_path
|
|
30
|
+
else
|
|
31
|
+
uri.to_s.sub(%r{^file://}, "")
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
data/lib/standard/base/plugin.rb
CHANGED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
module Standard
|
|
2
|
+
module Lsp
|
|
3
|
+
class Diagnostic
|
|
4
|
+
Constant = LanguageServer::Protocol::Constant
|
|
5
|
+
Interface = LanguageServer::Protocol::Interface
|
|
6
|
+
|
|
7
|
+
RUBOCOP_TO_LSP_SEVERITY = {
|
|
8
|
+
info: Constant::DiagnosticSeverity::HINT,
|
|
9
|
+
refactor: Constant::DiagnosticSeverity::INFORMATION,
|
|
10
|
+
convention: Constant::DiagnosticSeverity::INFORMATION,
|
|
11
|
+
warning: Constant::DiagnosticSeverity::WARNING,
|
|
12
|
+
error: Constant::DiagnosticSeverity::ERROR,
|
|
13
|
+
fatal: Constant::DiagnosticSeverity::ERROR
|
|
14
|
+
}.freeze
|
|
15
|
+
|
|
16
|
+
def initialize(document_encoding, offense, uri, cop_class)
|
|
17
|
+
@document_encoding = document_encoding
|
|
18
|
+
@offense = offense
|
|
19
|
+
@uri = uri
|
|
20
|
+
@cop_class = cop_class
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def to_lsp_code_actions
|
|
24
|
+
code_actions = []
|
|
25
|
+
|
|
26
|
+
code_actions << autocorrect_action if correctable?
|
|
27
|
+
code_actions << disable_line_action
|
|
28
|
+
|
|
29
|
+
code_actions
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def to_lsp_diagnostic(config)
|
|
33
|
+
highlighted = @offense.highlighted_area
|
|
34
|
+
Interface::Diagnostic.new(
|
|
35
|
+
message: message,
|
|
36
|
+
source: "Standard Ruby",
|
|
37
|
+
code: @offense.cop_name,
|
|
38
|
+
code_description: code_description(config),
|
|
39
|
+
severity: severity,
|
|
40
|
+
range: Interface::Range.new(
|
|
41
|
+
start: Interface::Position.new(
|
|
42
|
+
line: @offense.line - 1,
|
|
43
|
+
character: highlighted.begin_pos
|
|
44
|
+
),
|
|
45
|
+
end: Interface::Position.new(
|
|
46
|
+
line: @offense.line - 1,
|
|
47
|
+
character: highlighted.end_pos
|
|
48
|
+
)
|
|
49
|
+
),
|
|
50
|
+
data: {
|
|
51
|
+
correctable: correctable?,
|
|
52
|
+
code_actions: to_lsp_code_actions
|
|
53
|
+
}
|
|
54
|
+
)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
def message
|
|
60
|
+
message = @offense.message
|
|
61
|
+
message += "\n\nThis offense is not auto-correctable.\n" unless correctable?
|
|
62
|
+
message
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def severity
|
|
66
|
+
RUBOCOP_TO_LSP_SEVERITY[@offense.severity.name]
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def code_description(config)
|
|
70
|
+
return unless @cop_class
|
|
71
|
+
|
|
72
|
+
if (doc_url = @cop_class.documentation_url(config))
|
|
73
|
+
Interface::CodeDescription.new(href: doc_url)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def autocorrect_action
|
|
78
|
+
Interface::CodeAction.new(
|
|
79
|
+
title: "Autocorrect #{@offense.cop_name}",
|
|
80
|
+
kind: Constant::CodeActionKind::QUICK_FIX,
|
|
81
|
+
edit: Interface::WorkspaceEdit.new(
|
|
82
|
+
document_changes: [
|
|
83
|
+
Interface::TextDocumentEdit.new(
|
|
84
|
+
text_document: Interface::OptionalVersionedTextDocumentIdentifier.new(
|
|
85
|
+
uri: @uri.to_s,
|
|
86
|
+
version: nil
|
|
87
|
+
),
|
|
88
|
+
edits: correctable? ? offense_replacements : []
|
|
89
|
+
)
|
|
90
|
+
]
|
|
91
|
+
),
|
|
92
|
+
is_preferred: true
|
|
93
|
+
)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def offense_replacements
|
|
97
|
+
@offense.corrector.as_replacements.map do |range, replacement|
|
|
98
|
+
Interface::TextEdit.new(
|
|
99
|
+
range: Interface::Range.new(
|
|
100
|
+
start: Interface::Position.new(line: range.line - 1, character: range.column),
|
|
101
|
+
end: Interface::Position.new(line: range.last_line - 1, character: range.last_column)
|
|
102
|
+
),
|
|
103
|
+
new_text: replacement
|
|
104
|
+
)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def disable_line_action
|
|
109
|
+
Interface::CodeAction.new(
|
|
110
|
+
title: "Disable #{@offense.cop_name} for this line",
|
|
111
|
+
kind: Constant::CodeActionKind::QUICK_FIX,
|
|
112
|
+
edit: Interface::WorkspaceEdit.new(
|
|
113
|
+
document_changes: [
|
|
114
|
+
Interface::TextDocumentEdit.new(
|
|
115
|
+
text_document: Interface::OptionalVersionedTextDocumentIdentifier.new(
|
|
116
|
+
uri: @uri.to_s,
|
|
117
|
+
version: nil
|
|
118
|
+
),
|
|
119
|
+
edits: line_disable_comment
|
|
120
|
+
)
|
|
121
|
+
]
|
|
122
|
+
)
|
|
123
|
+
)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def line_disable_comment
|
|
127
|
+
new_text = if @offense.source_line.include?(" # standard:disable ")
|
|
128
|
+
",#{@offense.cop_name}"
|
|
129
|
+
else
|
|
130
|
+
" # standard:disable #{@offense.cop_name}"
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
eol = Interface::Position.new(
|
|
134
|
+
line: @offense.line - 1,
|
|
135
|
+
character: length_of_line(@offense.source_line)
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
# TODO: fails for multiline strings - may be preferable to use block
|
|
139
|
+
# comments to disable some offenses
|
|
140
|
+
inline_comment = Interface::TextEdit.new(
|
|
141
|
+
range: Interface::Range.new(start: eol, end: eol),
|
|
142
|
+
new_text: new_text
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
[inline_comment]
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def length_of_line(line)
|
|
149
|
+
if @document_encoding == Encoding::UTF_16LE
|
|
150
|
+
line_length = 0
|
|
151
|
+
line.codepoints.each do |codepoint|
|
|
152
|
+
line_length += 1
|
|
153
|
+
if codepoint > RubyLsp::Document::Scanner::SURROGATE_PAIR_START
|
|
154
|
+
line_length += 1
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
line_length
|
|
158
|
+
else
|
|
159
|
+
line.length
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def correctable?
|
|
164
|
+
!@offense.corrector.nil?
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
end
|
data/lib/standard/lsp/logger.rb
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
module Standard
|
|
2
2
|
module Lsp
|
|
3
3
|
class Logger
|
|
4
|
-
def initialize
|
|
4
|
+
def initialize(prefix: "[server]")
|
|
5
|
+
@prefix = prefix
|
|
5
6
|
@puts_onces = []
|
|
6
7
|
end
|
|
7
8
|
|
|
8
9
|
def puts(message)
|
|
9
|
-
warn
|
|
10
|
+
warn [@prefix, message].compact.join(" ")
|
|
10
11
|
end
|
|
11
12
|
|
|
12
13
|
def puts_once(message)
|
data/lib/standard/lsp/routes.rb
CHANGED
|
@@ -154,45 +154,12 @@ module Standard
|
|
|
154
154
|
|
|
155
155
|
def diagnostic(file_uri, text)
|
|
156
156
|
@text_cache[file_uri] = text
|
|
157
|
-
offenses = @standardizer.offenses(uri_to_path(file_uri), text)
|
|
158
|
-
|
|
159
|
-
lsp_diagnostics = offenses.map { |o|
|
|
160
|
-
code = o[:cop_name]
|
|
161
|
-
|
|
162
|
-
msg = o[:message].delete_prefix(code)
|
|
163
|
-
loc = o[:location]
|
|
164
|
-
|
|
165
|
-
severity = case o[:severity]
|
|
166
|
-
when "error", "fatal"
|
|
167
|
-
SEV::ERROR
|
|
168
|
-
when "warning"
|
|
169
|
-
SEV::WARNING
|
|
170
|
-
when "convention"
|
|
171
|
-
SEV::INFORMATION
|
|
172
|
-
when "refactor", "info"
|
|
173
|
-
SEV::HINT
|
|
174
|
-
else # the above cases fully cover what RuboCop sends at this time
|
|
175
|
-
logger.puts "Unknown severity: #{severity.inspect}"
|
|
176
|
-
SEV::HINT
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
{
|
|
180
|
-
code: code,
|
|
181
|
-
message: msg,
|
|
182
|
-
range: {
|
|
183
|
-
start: {character: loc[:start_column] - 1, line: loc[:start_line] - 1},
|
|
184
|
-
end: {character: loc[:last_column] - 1, line: loc[:last_line] - 1}
|
|
185
|
-
},
|
|
186
|
-
severity: severity,
|
|
187
|
-
source: "standard"
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
157
|
|
|
191
158
|
{
|
|
192
159
|
method: "textDocument/publishDiagnostics",
|
|
193
160
|
params: {
|
|
194
161
|
uri: file_uri,
|
|
195
|
-
diagnostics:
|
|
162
|
+
diagnostics: @standardizer.offenses(uri_to_path(file_uri), text)
|
|
196
163
|
}
|
|
197
164
|
}
|
|
198
165
|
end
|
data/lib/standard/lsp/server.rb
CHANGED
|
@@ -13,11 +13,12 @@ module Standard
|
|
|
13
13
|
@writer = Proto::Transport::Io::Writer.new($stdout)
|
|
14
14
|
@reader = Proto::Transport::Io::Reader.new($stdin)
|
|
15
15
|
@logger = Logger.new
|
|
16
|
-
@standardizer = Standard::Lsp::Standardizer.new(config
|
|
16
|
+
@standardizer = Standard::Lsp::Standardizer.new(config)
|
|
17
17
|
@routes = Routes.new(@writer, @logger, @standardizer)
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
def start
|
|
21
|
+
RuboCop::LSP.enable
|
|
21
22
|
@reader.read do |request|
|
|
22
23
|
if !request.key?(:method)
|
|
23
24
|
@routes.handle_method_missing(request)
|
|
@@ -1,68 +1,33 @@
|
|
|
1
|
-
require_relative "
|
|
1
|
+
require_relative "stdin_rubocop_runner"
|
|
2
|
+
require_relative "diagnostic"
|
|
2
3
|
|
|
3
4
|
module Standard
|
|
4
5
|
module Lsp
|
|
5
6
|
class Standardizer
|
|
6
|
-
def initialize(config
|
|
7
|
-
@
|
|
8
|
-
@
|
|
9
|
-
|
|
7
|
+
def initialize(config)
|
|
8
|
+
@diagnostic_runner = ::Standard::Lsp::StdinRubocopRunner.new(config)
|
|
9
|
+
@format_runner = ::Standard::Lsp::StdinRubocopRunner.new(config.dup.tap { |c|
|
|
10
|
+
c.rubocop_options[:autocorrect] = true
|
|
11
|
+
})
|
|
12
|
+
@cop_registry = RuboCop::Cop::Registry.global.to_h
|
|
10
13
|
end
|
|
11
14
|
|
|
12
|
-
# This abuses the --stdin option of rubocop and reads the formatted text
|
|
13
|
-
# from the options[:stdin] that rubocop mutates. This depends on
|
|
14
|
-
# parallel: false as well as the fact that rubocop doesn't otherwise dup
|
|
15
|
-
# or reassign that options object. Risky business!
|
|
16
|
-
#
|
|
17
|
-
# Reassigning options[:stdin] is done here:
|
|
18
|
-
# https://github.com/rubocop/rubocop/blob/master/lib/rubocop/cop/team.rb#L131
|
|
19
|
-
# Printing options[:stdin]
|
|
20
|
-
# https://github.com/rubocop/rubocop/blob/master/lib/rubocop/cli/command/execute_runner.rb#L95
|
|
21
|
-
# Setting `parallel: true` would break this here:
|
|
22
|
-
# https://github.com/rubocop/rubocop/blob/master/lib/rubocop/runner.rb#L72
|
|
23
15
|
def format(path, text)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
ad_hoc_config.rubocop_options[:stdin]
|
|
16
|
+
@format_runner.run(path, text)
|
|
17
|
+
@format_runner.formatted_source
|
|
27
18
|
end
|
|
28
19
|
|
|
29
|
-
def offenses(path, text)
|
|
30
|
-
|
|
31
|
-
capture_rubocop_stdout(fork_config(path, text, format: false)),
|
|
32
|
-
symbolize_names: true
|
|
33
|
-
)
|
|
34
|
-
if results[:files].empty?
|
|
35
|
-
@logger.puts_once "Ignoring file, per configuration: #{path}"
|
|
36
|
-
[]
|
|
37
|
-
else
|
|
38
|
-
results.dig(:files, 0, :offenses)
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
private
|
|
20
|
+
def offenses(path, text, document_encoding = nil)
|
|
21
|
+
@diagnostic_runner.run(path, text)
|
|
43
22
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
options = if format
|
|
52
|
-
{stdin: text, autocorrect: true, safe_autocorrect: true, formatters: []}
|
|
53
|
-
else
|
|
54
|
-
{stdin: text, autocorrect: false, safe_autocorrect: false, formatters: [["json"]], format: "json"}
|
|
23
|
+
@diagnostic_runner.offenses.map do |offense|
|
|
24
|
+
Diagnostic.new(
|
|
25
|
+
document_encoding,
|
|
26
|
+
offense,
|
|
27
|
+
path,
|
|
28
|
+
@cop_registry[offense.cop_name]&.first
|
|
29
|
+
).to_lsp_diagnostic(@diagnostic_runner.config_for_working_directory)
|
|
55
30
|
end
|
|
56
|
-
Standard::Config.new(@config.runner, [path], BASE_OPTIONS.merge(options), @config.rubocop_config_store)
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def capture_rubocop_stdout(config)
|
|
60
|
-
redir = StringIO.new
|
|
61
|
-
$stdout = redir
|
|
62
|
-
@rubocop_runner.call(config)
|
|
63
|
-
redir.string
|
|
64
|
-
ensure
|
|
65
|
-
$stdout = STDOUT
|
|
66
31
|
end
|
|
67
32
|
end
|
|
68
33
|
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
module Standard
|
|
2
|
+
module Lsp
|
|
3
|
+
# Originally lifted from:
|
|
4
|
+
# https://github.com/Shopify/ruby-lsp/blob/8d4c17efce4e8ecc8e7c557ab2981db6b22c0b6d/lib/ruby_lsp/requests/support/rubocop_runner.rb#L20
|
|
5
|
+
class StdinRubocopRunner < ::RuboCop::Runner
|
|
6
|
+
class ConfigurationError < StandardError; end
|
|
7
|
+
|
|
8
|
+
attr_reader :offenses
|
|
9
|
+
|
|
10
|
+
attr_reader :config_for_working_directory
|
|
11
|
+
|
|
12
|
+
DEFAULT_RUBOCOP_OPTIONS = {
|
|
13
|
+
stderr: true,
|
|
14
|
+
force_exclusion: true,
|
|
15
|
+
format: "RuboCop::Formatter::BaseFormatter",
|
|
16
|
+
raise_cop_error: true
|
|
17
|
+
}.freeze
|
|
18
|
+
|
|
19
|
+
def initialize(config)
|
|
20
|
+
@options = {}
|
|
21
|
+
@offenses = []
|
|
22
|
+
@errors = []
|
|
23
|
+
@warnings = []
|
|
24
|
+
|
|
25
|
+
@config_for_working_directory = config.rubocop_config_store.for_pwd
|
|
26
|
+
|
|
27
|
+
super(
|
|
28
|
+
config.rubocop_options.merge(DEFAULT_RUBOCOP_OPTIONS),
|
|
29
|
+
config.rubocop_config_store
|
|
30
|
+
)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def run(path, contents)
|
|
34
|
+
@errors = []
|
|
35
|
+
@warnings = []
|
|
36
|
+
@offenses = []
|
|
37
|
+
@options[:stdin] = contents
|
|
38
|
+
|
|
39
|
+
super([path])
|
|
40
|
+
|
|
41
|
+
raise Interrupt if aborting?
|
|
42
|
+
rescue ::RuboCop::Runner::InfiniteCorrectionLoop => error
|
|
43
|
+
raise RubyLsp::Requests::Formatting::Erro, error.message
|
|
44
|
+
rescue ::RuboCop::ValidationError => error
|
|
45
|
+
raise ConfigurationError, error.message
|
|
46
|
+
rescue => error
|
|
47
|
+
raise ::RubyLsp::Requests::Support::InternalRuboCopError, error
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def formatted_source
|
|
51
|
+
@options[:stdin]
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
private
|
|
55
|
+
|
|
56
|
+
def file_finished(_file, offenses)
|
|
57
|
+
@offenses = offenses
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
data/lib/standard/version.rb
CHANGED
data/standard.gemspec
CHANGED
|
@@ -7,7 +7,7 @@ Gem::Specification.new do |spec|
|
|
|
7
7
|
spec.version = Standard::VERSION
|
|
8
8
|
spec.authors = ["Justin Searls"]
|
|
9
9
|
spec.email = ["searls@gmail.com"]
|
|
10
|
-
spec.required_ruby_version = ">=
|
|
10
|
+
spec.required_ruby_version = ">= 3.0.0"
|
|
11
11
|
|
|
12
12
|
spec.summary = "Ruby Style Guide, with linter & automatic code fixer"
|
|
13
13
|
spec.homepage = "https://github.com/standardrb/standard"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: standard
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.39.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Justin Searls
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2024-06-
|
|
11
|
+
date: 2024-06-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rubocop
|
|
@@ -117,11 +117,14 @@ files:
|
|
|
117
117
|
- config/ruby-3.0.yml
|
|
118
118
|
- config/ruby-3.1.yml
|
|
119
119
|
- config/ruby-3.2.yml
|
|
120
|
+
- config/ruby-3.3.yml
|
|
120
121
|
- docs/ARCHITECTURE.md
|
|
121
122
|
- docs/NEW_RUBIES.md
|
|
122
123
|
- docs/RELEASE.md
|
|
123
124
|
- docs/UPGRADING.md
|
|
124
125
|
- exe/standardrb
|
|
126
|
+
- lib/ruby_lsp/standard/addon.rb
|
|
127
|
+
- lib/ruby_lsp/standard/wraps_built_in_lsp_standardizer.rb
|
|
125
128
|
- lib/standard.rb
|
|
126
129
|
- lib/standard/base.rb
|
|
127
130
|
- lib/standard/base/plugin.rb
|
|
@@ -136,11 +139,13 @@ files:
|
|
|
136
139
|
- lib/standard/formatter.rb
|
|
137
140
|
- lib/standard/loads_runner.rb
|
|
138
141
|
- lib/standard/loads_yaml_config.rb
|
|
142
|
+
- lib/standard/lsp/diagnostic.rb
|
|
139
143
|
- lib/standard/lsp/kills_server.rb
|
|
140
144
|
- lib/standard/lsp/logger.rb
|
|
141
145
|
- lib/standard/lsp/routes.rb
|
|
142
146
|
- lib/standard/lsp/server.rb
|
|
143
147
|
- lib/standard/lsp/standardizer.rb
|
|
148
|
+
- lib/standard/lsp/stdin_rubocop_runner.rb
|
|
144
149
|
- lib/standard/merges_settings.rb
|
|
145
150
|
- lib/standard/plugin.rb
|
|
146
151
|
- lib/standard/plugin/combines_plugin_configs.rb
|
|
@@ -176,14 +181,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
176
181
|
requirements:
|
|
177
182
|
- - ">="
|
|
178
183
|
- !ruby/object:Gem::Version
|
|
179
|
-
version:
|
|
184
|
+
version: 3.0.0
|
|
180
185
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
181
186
|
requirements:
|
|
182
187
|
- - ">="
|
|
183
188
|
- !ruby/object:Gem::Version
|
|
184
189
|
version: '0'
|
|
185
190
|
requirements: []
|
|
186
|
-
rubygems_version: 3.
|
|
191
|
+
rubygems_version: 3.5.9
|
|
187
192
|
signing_key:
|
|
188
193
|
specification_version: 4
|
|
189
194
|
summary: Ruby Style Guide, with linter & automatic code fixer
|