rubocop 1.59.0 → 1.65.1

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.
Files changed (255) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +3 -4
  4. data/assets/output.css.erb +159 -0
  5. data/assets/output.html.erb +1 -160
  6. data/config/default.yml +93 -17
  7. data/lib/rubocop/cached_data.rb +11 -3
  8. data/lib/rubocop/cli/command/auto_generate_config.rb +12 -3
  9. data/lib/rubocop/cli/command/lsp.rb +2 -2
  10. data/lib/rubocop/cli/command/show_docs_url.rb +2 -2
  11. data/lib/rubocop/cli.rb +10 -1
  12. data/lib/rubocop/config.rb +36 -12
  13. data/lib/rubocop/config_finder.rb +12 -2
  14. data/lib/rubocop/config_loader.rb +1 -2
  15. data/lib/rubocop/config_loader_resolver.rb +9 -3
  16. data/lib/rubocop/config_obsoletion.rb +1 -1
  17. data/lib/rubocop/config_validator.rb +14 -7
  18. data/lib/rubocop/cop/autocorrect_logic.rb +6 -1
  19. data/lib/rubocop/cop/base.rb +63 -16
  20. data/lib/rubocop/cop/bundler/gem_version.rb +3 -5
  21. data/lib/rubocop/cop/cop.rb +22 -4
  22. data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +4 -8
  23. data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +5 -13
  24. data/lib/rubocop/cop/documentation.rb +16 -6
  25. data/lib/rubocop/cop/exclude_limit.rb +1 -1
  26. data/lib/rubocop/cop/force.rb +12 -0
  27. data/lib/rubocop/cop/gemspec/add_runtime_dependency.rb +38 -0
  28. data/lib/rubocop/cop/gemspec/dependency_version.rb +3 -5
  29. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -2
  30. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +5 -1
  31. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +3 -3
  32. data/lib/rubocop/cop/internal_affairs/example_description.rb +6 -5
  33. data/lib/rubocop/cop/internal_affairs/method_name_end_with.rb +8 -6
  34. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +122 -28
  35. data/lib/rubocop/cop/internal_affairs/redundant_expect_offense_arguments.rb +34 -0
  36. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  37. data/lib/rubocop/cop/layout/assignment_indentation.rb +3 -2
  38. data/lib/rubocop/cop/layout/case_indentation.rb +1 -1
  39. data/lib/rubocop/cop/layout/comment_indentation.rb +1 -1
  40. data/lib/rubocop/cop/layout/condition_position.rb +0 -4
  41. data/lib/rubocop/cop/layout/empty_comment.rb +3 -1
  42. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +14 -7
  43. data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +1 -1
  44. data/lib/rubocop/cop/layout/end_alignment.rb +8 -2
  45. data/lib/rubocop/cop/layout/first_argument_indentation.rb +2 -2
  46. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +18 -1
  47. data/lib/rubocop/cop/layout/heredoc_indentation.rb +1 -1
  48. data/lib/rubocop/cop/layout/indentation_width.rb +1 -1
  49. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +1 -1
  50. data/lib/rubocop/cop/layout/line_length.rb +20 -20
  51. data/lib/rubocop/cop/layout/redundant_line_break.rb +14 -2
  52. data/lib/rubocop/cop/layout/space_around_operators.rb +3 -0
  53. data/lib/rubocop/cop/layout/space_before_block_braces.rb +19 -10
  54. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +1 -1
  55. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +3 -4
  56. data/lib/rubocop/cop/legacy/corrector.rb +12 -2
  57. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +0 -2
  58. data/lib/rubocop/cop/lint/ambiguous_operator.rb +0 -2
  59. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +0 -2
  60. data/lib/rubocop/cop/lint/assignment_in_condition.rb +2 -2
  61. data/lib/rubocop/cop/lint/boolean_symbol.rb +0 -2
  62. data/lib/rubocop/cop/lint/circular_argument_reference.rb +0 -13
  63. data/lib/rubocop/cop/lint/debugger.rb +27 -6
  64. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
  65. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +0 -10
  66. data/lib/rubocop/cop/lint/duplicate_case_condition.rb +1 -5
  67. data/lib/rubocop/cop/lint/duplicate_hash_key.rb +0 -4
  68. data/lib/rubocop/cop/lint/duplicate_methods.rb +0 -10
  69. data/lib/rubocop/cop/lint/each_with_object_argument.rb +0 -4
  70. data/lib/rubocop/cop/lint/else_layout.rb +0 -2
  71. data/lib/rubocop/cop/lint/empty_conditional_body.rb +2 -2
  72. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -11
  73. data/lib/rubocop/cop/lint/empty_interpolation.rb +0 -4
  74. data/lib/rubocop/cop/lint/empty_when.rb +1 -3
  75. data/lib/rubocop/cop/lint/ensure_return.rb +1 -6
  76. data/lib/rubocop/cop/lint/erb_new_arguments.rb +21 -14
  77. data/lib/rubocop/cop/lint/float_comparison.rb +3 -1
  78. data/lib/rubocop/cop/lint/float_out_of_range.rb +0 -4
  79. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +0 -10
  80. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +15 -12
  81. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +0 -7
  82. data/lib/rubocop/cop/lint/interpolation_check.rb +0 -4
  83. data/lib/rubocop/cop/lint/literal_as_condition.rb +1 -1
  84. data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +13 -6
  85. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +0 -4
  86. data/lib/rubocop/cop/lint/loop.rb +6 -12
  87. data/lib/rubocop/cop/lint/mixed_case_range.rb +9 -4
  88. data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -7
  89. data/lib/rubocop/cop/lint/next_without_accumulator.rb +0 -4
  90. data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +0 -5
  91. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +1 -1
  92. data/lib/rubocop/cop/lint/percent_string_array.rb +0 -4
  93. data/lib/rubocop/cop/lint/percent_symbol_array.rb +0 -4
  94. data/lib/rubocop/cop/lint/rand_one.rb +0 -4
  95. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +3 -1
  96. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +14 -9
  97. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +1 -1
  98. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +0 -4
  99. data/lib/rubocop/cop/lint/redundant_with_index.rb +4 -0
  100. data/lib/rubocop/cop/lint/require_parentheses.rb +0 -4
  101. data/lib/rubocop/cop/lint/rescue_exception.rb +0 -4
  102. data/lib/rubocop/cop/lint/rescue_type.rb +1 -3
  103. data/lib/rubocop/cop/lint/return_in_void_context.rb +0 -2
  104. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +0 -4
  105. data/lib/rubocop/cop/lint/script_permission.rb +3 -3
  106. data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -0
  107. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +6 -10
  108. data/lib/rubocop/cop/lint/syntax.rb +6 -3
  109. data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -3
  110. data/lib/rubocop/cop/lint/unified_integer.rb +0 -4
  111. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -0
  112. data/lib/rubocop/cop/lint/unreachable_code.rb +4 -7
  113. data/lib/rubocop/cop/lint/unreachable_loop.rb +8 -2
  114. data/lib/rubocop/cop/lint/useless_assignment.rb +1 -5
  115. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +0 -4
  116. data/lib/rubocop/cop/lint/useless_setter_call.rb +0 -4
  117. data/lib/rubocop/cop/lint/useless_times.rb +1 -1
  118. data/lib/rubocop/cop/lint/void.rb +11 -1
  119. data/lib/rubocop/cop/metrics/block_nesting.rb +19 -7
  120. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +5 -5
  121. data/lib/rubocop/cop/mixin/alignment.rb +5 -1
  122. data/lib/rubocop/cop/mixin/allowed_methods.rb +7 -1
  123. data/lib/rubocop/cop/mixin/allowed_pattern.rb +15 -3
  124. data/lib/rubocop/cop/mixin/code_length.rb +12 -1
  125. data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -0
  126. data/lib/rubocop/cop/mixin/configurable_max.rb +5 -1
  127. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +9 -2
  128. data/lib/rubocop/cop/mixin/method_complexity.rb +15 -6
  129. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
  130. data/lib/rubocop/cop/mixin/rescue_node.rb +4 -0
  131. data/lib/rubocop/cop/mixin/safe_assignment.rb +1 -1
  132. data/lib/rubocop/cop/naming/block_forwarding.rb +32 -5
  133. data/lib/rubocop/cop/naming/file_name.rb +2 -2
  134. data/lib/rubocop/cop/naming/inclusive_language.rb +1 -2
  135. data/lib/rubocop/cop/naming/predicate_name.rb +54 -28
  136. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +10 -1
  137. data/lib/rubocop/cop/registry.rb +1 -1
  138. data/lib/rubocop/cop/security/compound_hash.rb +2 -2
  139. data/lib/rubocop/cop/security/open.rb +2 -2
  140. data/lib/rubocop/cop/style/access_modifier_declarations.rb +50 -0
  141. data/lib/rubocop/cop/style/alias.rb +1 -0
  142. data/lib/rubocop/cop/style/arguments_forwarding.rb +89 -17
  143. data/lib/rubocop/cop/style/case_like_if.rb +1 -1
  144. data/lib/rubocop/cop/style/class_vars.rb +3 -3
  145. data/lib/rubocop/cop/style/collection_compact.rb +14 -5
  146. data/lib/rubocop/cop/style/commented_keyword.rb +5 -2
  147. data/lib/rubocop/cop/style/conditional_assignment.rb +6 -7
  148. data/lib/rubocop/cop/style/copyright.rb +31 -21
  149. data/lib/rubocop/cop/style/def_with_parentheses.rb +0 -2
  150. data/lib/rubocop/cop/style/documentation.rb +24 -24
  151. data/lib/rubocop/cop/style/documentation_method.rb +20 -0
  152. data/lib/rubocop/cop/style/each_for_simple_loop.rb +7 -8
  153. data/lib/rubocop/cop/style/eval_with_location.rb +15 -23
  154. data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -1
  155. data/lib/rubocop/cop/style/file_read.rb +2 -5
  156. data/lib/rubocop/cop/style/file_write.rb +2 -5
  157. data/lib/rubocop/cop/style/for.rb +2 -0
  158. data/lib/rubocop/cop/style/format_string.rb +9 -9
  159. data/lib/rubocop/cop/style/global_std_stream.rb +7 -1
  160. data/lib/rubocop/cop/style/hash_each_methods.rb +29 -8
  161. data/lib/rubocop/cop/style/hash_except.rb +8 -5
  162. data/lib/rubocop/cop/style/hash_syntax.rb +24 -2
  163. data/lib/rubocop/cop/style/identical_conditional_branches.rb +4 -1
  164. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +5 -4
  165. data/lib/rubocop/cop/style/inverse_methods.rb +8 -8
  166. data/lib/rubocop/cop/style/invertible_unless_condition.rb +46 -4
  167. data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +81 -50
  168. data/lib/rubocop/cop/style/map_into_array.rb +175 -0
  169. data/lib/rubocop/cop/style/map_to_hash.rb +10 -6
  170. data/lib/rubocop/cop/style/map_to_set.rb +1 -1
  171. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +18 -5
  172. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -4
  173. data/lib/rubocop/cop/style/missing_else.rb +0 -4
  174. data/lib/rubocop/cop/style/multiline_method_signature.rb +10 -1
  175. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +5 -3
  176. data/lib/rubocop/cop/style/multiline_when_then.rb +0 -4
  177. data/lib/rubocop/cop/style/nil_comparison.rb +2 -0
  178. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +1 -1
  179. data/lib/rubocop/cop/style/numeric_predicate.rb +10 -2
  180. data/lib/rubocop/cop/style/object_then.rb +5 -3
  181. data/lib/rubocop/cop/style/one_line_conditional.rb +1 -1
  182. data/lib/rubocop/cop/style/parallel_assignment.rb +3 -5
  183. data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -0
  184. data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
  185. data/lib/rubocop/cop/style/raise_args.rb +4 -1
  186. data/lib/rubocop/cop/style/redundant_argument.rb +25 -2
  187. data/lib/rubocop/cop/style/redundant_assignment.rb +10 -2
  188. data/lib/rubocop/cop/style/redundant_begin.rb +1 -1
  189. data/lib/rubocop/cop/style/redundant_condition.rb +0 -1
  190. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +5 -4
  191. data/lib/rubocop/cop/style/redundant_each.rb +7 -4
  192. data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +1 -1
  193. data/lib/rubocop/cop/style/redundant_filter_chain.rb +1 -1
  194. data/lib/rubocop/cop/style/redundant_line_continuation.rb +17 -2
  195. data/lib/rubocop/cop/style/redundant_parentheses.rb +18 -2
  196. data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -1
  197. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +8 -24
  198. data/lib/rubocop/cop/style/redundant_return.rb +6 -0
  199. data/lib/rubocop/cop/style/require_order.rb +1 -1
  200. data/lib/rubocop/cop/style/sample.rb +1 -3
  201. data/lib/rubocop/cop/style/send.rb +4 -4
  202. data/lib/rubocop/cop/style/send_with_literal_method_name.rb +104 -0
  203. data/lib/rubocop/cop/style/slicing_with_range.rb +76 -10
  204. data/lib/rubocop/cop/style/sole_nested_conditional.rb +21 -2
  205. data/lib/rubocop/cop/style/special_global_vars.rb +1 -2
  206. data/lib/rubocop/cop/style/super_arguments.rb +174 -0
  207. data/lib/rubocop/cop/style/symbol_proc.rb +75 -5
  208. data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -1
  209. data/lib/rubocop/cop/style/while_until_do.rb +0 -2
  210. data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
  211. data/lib/rubocop/cop/style/zero_length_predicate.rb +32 -24
  212. data/lib/rubocop/cop/team.rb +13 -0
  213. data/lib/rubocop/cop/util.rb +7 -1
  214. data/lib/rubocop/cop/utils/regexp_ranges.rb +1 -1
  215. data/lib/rubocop/cop/variable_force.rb +13 -1
  216. data/lib/rubocop/cops_documentation_generator.rb +16 -4
  217. data/lib/rubocop/core_ext/string.rb +2 -6
  218. data/lib/rubocop/directive_comment.rb +10 -8
  219. data/lib/rubocop/ext/regexp_node.rb +18 -35
  220. data/lib/rubocop/ext/regexp_parser.rb +4 -21
  221. data/lib/rubocop/formatter/clang_style_formatter.rb +3 -7
  222. data/lib/rubocop/formatter/disabled_config_formatter.rb +23 -8
  223. data/lib/rubocop/formatter/formatter_set.rb +7 -1
  224. data/lib/rubocop/formatter/html_formatter.rb +32 -10
  225. data/lib/rubocop/formatter/json_formatter.rb +0 -1
  226. data/lib/rubocop/formatter/offense_count_formatter.rb +12 -2
  227. data/lib/rubocop/formatter/tap_formatter.rb +3 -7
  228. data/lib/rubocop/formatter.rb +1 -1
  229. data/lib/rubocop/lockfile.rb +56 -7
  230. data/lib/rubocop/lsp/logger.rb +1 -1
  231. data/lib/rubocop/lsp/routes.rb +12 -15
  232. data/lib/rubocop/lsp/runtime.rb +1 -1
  233. data/lib/rubocop/lsp/server.rb +7 -2
  234. data/lib/rubocop/lsp/severity.rb +1 -1
  235. data/lib/rubocop/lsp.rb +36 -0
  236. data/lib/rubocop/magic_comment.rb +1 -1
  237. data/lib/rubocop/options.rb +17 -12
  238. data/lib/rubocop/path_util.rb +6 -2
  239. data/lib/rubocop/rake_task.rb +1 -1
  240. data/lib/rubocop/rspec/cop_helper.rb +8 -2
  241. data/lib/rubocop/rspec/expect_offense.rb +16 -8
  242. data/lib/rubocop/rspec/shared_contexts.rb +73 -16
  243. data/lib/rubocop/rspec/support.rb +3 -0
  244. data/lib/rubocop/runner.rb +14 -3
  245. data/lib/rubocop/server/cache.rb +11 -2
  246. data/lib/rubocop/server/client_command/exec.rb +2 -3
  247. data/lib/rubocop/server/client_command/start.rb +1 -1
  248. data/lib/rubocop/server/core.rb +4 -0
  249. data/lib/rubocop/server/server_command/exec.rb +0 -1
  250. data/lib/rubocop/target_finder.rb +84 -78
  251. data/lib/rubocop/target_ruby.rb +82 -80
  252. data/lib/rubocop/version.rb +19 -4
  253. data/lib/rubocop.rb +9 -0
  254. metadata +18 -11
  255. /data/lib/rubocop/formatter/{git_hub_actions_formatter.rb → github_actions_formatter.rb} +0 -0
@@ -12,12 +12,12 @@ require_relative 'severity'
12
12
  # https://github.com/standardrb/standard/blob/main/LICENSE.txt
13
13
  #
14
14
  module RuboCop
15
- module Lsp
15
+ module LSP
16
16
  # Routes for Language Server Protocol of RuboCop.
17
17
  # @api private
18
18
  class Routes
19
19
  def self.handle(name, &block)
20
- define_method("handle_#{name}", &block)
20
+ define_method(:"handle_#{name}", &block)
21
21
  end
22
22
 
23
23
  private_class_method :handle
@@ -45,10 +45,6 @@ module RuboCop
45
45
  result: LanguageServer::Protocol::Interface::InitializeResult.new(
46
46
  capabilities: LanguageServer::Protocol::Interface::ServerCapabilities.new(
47
47
  document_formatting_provider: true,
48
- diagnostic_provider: LanguageServer::Protocol::Interface::DiagnosticOptions.new(
49
- inter_file_dependencies: false,
50
- workspace_diagnostics: false
51
- ),
52
48
  text_document_sync: LanguageServer::Protocol::Interface::TextDocumentSyncOptions.new(
53
49
  change: LanguageServer::Protocol::Constant::TextDocumentSyncKind::FULL,
54
50
  open_close: true
@@ -60,8 +56,9 @@ module RuboCop
60
56
 
61
57
  handle 'initialized' do |_request|
62
58
  version = RuboCop::Version::STRING
59
+ yjit = Object.const_defined?('RubyVM::YJIT') && RubyVM::YJIT.enabled? ? ' +YJIT' : ''
63
60
 
64
- Logger.log("RuboCop #{version} language server initialized, PID #{Process.pid}")
61
+ Logger.log("RuboCop #{version} language server#{yjit} initialized, PID #{Process.pid}")
65
62
  end
66
63
 
67
64
  handle 'shutdown' do |request|
@@ -72,12 +69,6 @@ module RuboCop
72
69
  end
73
70
  end
74
71
 
75
- handle 'textDocument/diagnostic' do |request|
76
- doc = request[:params][:textDocument]
77
- result = diagnostic(doc[:uri], doc[:text])
78
- @server.write(result)
79
- end
80
-
81
72
  handle 'textDocument/didChange' do |request|
82
73
  params = request[:params]
83
74
  result = diagnostic(params[:textDocument][:uri], params[:contentChanges][0][:text])
@@ -126,6 +117,12 @@ module RuboCop
126
117
  end
127
118
 
128
119
  uri = request[:params][:arguments][0][:uri]
120
+ formatted = nil
121
+
122
+ # The `workspace/executeCommand` is an LSP method triggered by intentional user actions,
123
+ # so the user's intention for autocorrection is respected.
124
+ LSP.disable { formatted = format_file(uri, command: command) }
125
+
129
126
  @server.write(
130
127
  id: request[:id],
131
128
  method: 'workspace/applyEdit',
@@ -133,7 +130,7 @@ module RuboCop
133
130
  label: label,
134
131
  edit: {
135
132
  changes: {
136
- uri => format_file(uri, command: command)
133
+ uri => formatted
137
134
  }
138
135
  }
139
136
  }
@@ -238,7 +235,7 @@ module RuboCop
238
235
  def to_range(location)
239
236
  {
240
237
  start: { character: location[:start_column] - 1, line: location[:start_line] - 1 },
241
- end: { character: location[:last_column] - 1, line: location[:last_line] - 1 }
238
+ end: { character: location[:last_column], line: location[:last_line] - 1 }
242
239
  }
243
240
  end
244
241
  end
@@ -10,7 +10,7 @@
10
10
  # https://github.com/standardrb/standard/blob/main/LICENSE.txt
11
11
  #
12
12
  module RuboCop
13
- module Lsp
13
+ module LSP
14
14
  # Runtime for Language Server Protocol of RuboCop.
15
15
  # @api private
16
16
  class Runtime
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'language_server-protocol'
4
+ require_relative '../lsp'
4
5
  require_relative 'logger'
5
6
  require_relative 'routes'
6
7
  require_relative 'runtime'
@@ -15,14 +16,18 @@ require_relative 'runtime'
15
16
  # https://github.com/standardrb/standard/blob/main/LICENSE.txt
16
17
  #
17
18
  module RuboCop
18
- module Lsp
19
+ module LSP
19
20
  # Language Server Protocol of RuboCop.
20
21
  # @api private
21
22
  class Server
22
23
  def initialize(config_store)
24
+ $PROGRAM_NAME = "rubocop --lsp #{ConfigFinder.project_root}"
25
+
26
+ RuboCop::LSP.enable
27
+
23
28
  @reader = LanguageServer::Protocol::Transport::Io::Reader.new($stdin)
24
29
  @writer = LanguageServer::Protocol::Transport::Io::Writer.new($stdout)
25
- @runtime = RuboCop::Lsp::Runtime.new(config_store)
30
+ @runtime = RuboCop::LSP::Runtime.new(config_store)
26
31
  @routes = Routes.new(self)
27
32
  end
28
33
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RuboCop
4
- module Lsp
4
+ module LSP
5
5
  # Severity for Language Server Protocol of RuboCop.
6
6
  # @api private
7
7
  class Severity
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ # The RuboCop's built-in LSP module.
5
+ module LSP
6
+ module_function
7
+
8
+ # Returns true when LSP is enabled, false when disabled.
9
+ #
10
+ # @return [Boolean]
11
+ def enabled?
12
+ @enabled ||= false
13
+ end
14
+
15
+ # Enable LSP.
16
+ #
17
+ # @return [void]
18
+ def enable
19
+ @enabled = true
20
+ end
21
+
22
+ # Disable LSP.
23
+ #
24
+ # @return [void]
25
+ def disable(&block)
26
+ if block
27
+ original = @enabled
28
+ @enabled = false
29
+ yield
30
+ @enabled = original
31
+ else
32
+ @enabled = false
33
+ end
34
+ end
35
+ end
36
+ end
@@ -268,7 +268,7 @@ module RuboCop
268
268
 
269
269
  # Rewrite the comment without a given token type
270
270
  def without(type)
271
- if @comment.match?(/\A#\s*#{self.class::KEYWORDS[type.to_sym]}/)
271
+ if @comment.match?(/\A#\s*#{self.class::KEYWORDS[type.to_sym]}/io)
272
272
  ''
273
273
  else
274
274
  @comment
@@ -95,6 +95,7 @@ module RuboCop
95
95
  option(opts, '--ignore-unrecognized-cops')
96
96
  option(opts, '--force-default-config')
97
97
  option(opts, '-s', '--stdin FILE')
98
+ option(opts, '--editor-mode')
98
99
  option(opts, '-P', '--[no-]parallel')
99
100
  option(opts, '--raise-cop-error')
100
101
  add_severity_option(opts)
@@ -364,15 +365,12 @@ module RuboCop
364
365
  raise OptionArgumentError, '-C/--cache argument must be true or false'
365
366
  end
366
367
 
367
- if display_only_fail_level_offenses_with_autocorrect?
368
- raise OptionArgumentError, '--autocorrect cannot be used with ' \
369
- '--display-only-fail-level-offenses.'
370
- end
371
368
  validate_auto_gen_config
372
369
  validate_autocorrect
373
370
  validate_display_only_failed
374
371
  validate_display_only_failed_and_display_only_correctable
375
372
  validate_display_only_correctable_and_autocorrect
373
+ validate_lsp_and_editor_mode
376
374
  disable_parallel_when_invalid_option_combo
377
375
 
378
376
  return if incompatible_options.size <= 1
@@ -420,6 +418,13 @@ module RuboCop
420
418
  format('--display-only-failed cannot be used together with other display options.')
421
419
  end
422
420
 
421
+ def validate_lsp_and_editor_mode
422
+ return if !@options.key?(:lsp) || !@options.key?(:editor_mode)
423
+
424
+ raise OptionArgumentError,
425
+ format('Do not specify `--editor-mode` as it is redundant in `--lsp`.')
426
+ end
427
+
423
428
  def validate_autocorrect
424
429
  if @options.key?(:safe_autocorrect) && @options.key?(:autocorrect_all)
425
430
  message = Rainbow(<<~MESSAGE).red
@@ -460,10 +465,6 @@ module RuboCop
460
465
  (@options[:only] & %w[Lint/RedundantCopDisableDirective RedundantCopDisableDirective]).any?
461
466
  end
462
467
 
463
- def display_only_fail_level_offenses_with_autocorrect?
464
- @options.key?(:display_only_fail_level_offenses) && @options.key?(:autocorrect)
465
- end
466
-
467
468
  def except_syntax?
468
469
  @options.key?(:except) && (@options[:except] & %w[Lint/Syntax Syntax]).any?
469
470
  end
@@ -572,7 +573,7 @@ module RuboCop
572
573
  'cops. Only valid for --format junit.'],
573
574
  display_only_fail_level_offenses:
574
575
  ['Only output offense messages at',
575
- 'the specified --fail-level or above'],
576
+ 'the specified --fail-level or above.'],
576
577
  display_only_correctable: ['Only output correctable offense messages.'],
577
578
  display_only_safe_correctable: ['Only output safe-correctable offense messages',
578
579
  'when combined with --display-only-correctable.'],
@@ -614,9 +615,13 @@ module RuboCop
614
615
  version: 'Display version.',
615
616
  verbose_version: 'Display verbose version.',
616
617
  parallel: ['Use available CPUs to execute inspection in',
617
- 'parallel. Default is true.'],
618
+ 'parallel. Default is true.',
619
+ 'You can specify the number of parallel processes using',
620
+ 'the $PARALLEL_PROCESSOR_COUNT environment variable.'],
618
621
  stdin: ['Pipe source from STDIN, using FILE in offense',
619
622
  'reports. This is useful for editor integration.'],
623
+ editor_mode: ['Optimize real-time feedback in editors,',
624
+ 'adjusting behaviors for editing experience.'],
620
625
  init: 'Generate a .rubocop.yml file in the current directory.',
621
626
  server: ['If a server process has not been started yet, start',
622
627
  'the server process and execute inspection with server.',
@@ -633,8 +638,8 @@ module RuboCop
633
638
  raise_cop_error: ['Raise cop-related errors with cause and location.',
634
639
  'This is used to prevent cops from failing silently.',
635
640
  'Default is false.'],
636
- profile: 'Profile rubocop',
637
- memory: 'Profile rubocop memory usage'
641
+ profile: 'Profile rubocop.',
642
+ memory: 'Profile rubocop memory usage.'
638
643
  }.freeze
639
644
  end
640
645
  # rubocop:enable Metrics/ModuleLength
@@ -44,7 +44,7 @@ module RuboCop
44
44
  end
45
45
  end
46
46
 
47
- # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity
47
+ # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
48
48
  def match_path?(pattern, path)
49
49
  case pattern
50
50
  when String
@@ -52,6 +52,10 @@ module RuboCop
52
52
  if pattern == path
53
53
  true
54
54
  elsif glob?(pattern)
55
+ # File name matching doesn't really work with relative patterns that start with "..". We
56
+ # get around that problem by converting the pattern to an absolute path.
57
+ pattern = File.expand_path(pattern) if pattern.start_with?('..')
58
+
55
59
  File.fnmatch?(pattern, path, File::FNM_PATHNAME | File::FNM_EXTGLOB)
56
60
  end
57
61
 
@@ -66,7 +70,7 @@ module RuboCop
66
70
  end
67
71
  end
68
72
  end
69
- # rubocop:enable Metrics/MethodLength, Metrics/CyclomaticComplexity
73
+ # rubocop:enable Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
70
74
 
71
75
  # Returns true for an absolute Unix or Windows path.
72
76
  def absolute?(path)
@@ -44,7 +44,7 @@ module RuboCop
44
44
  def run_cli(verbose, options)
45
45
  # We lazy-load RuboCop so that the task doesn't dramatically impact the
46
46
  # load time of your Rakefile.
47
- require 'rubocop'
47
+ require_relative '../rubocop'
48
48
 
49
49
  cli = CLI.new
50
50
  puts 'Running RuboCop...' if verbose
@@ -6,7 +6,11 @@ require 'tempfile'
6
6
  module CopHelper
7
7
  extend RSpec::SharedContext
8
8
 
9
- let(:ruby_version) { RuboCop::TargetRuby::DEFAULT_VERSION }
9
+ let(:ruby_version) do
10
+ # The minimum version Prism can parse is 3.3.
11
+ ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : RuboCop::TargetRuby::DEFAULT_VERSION
12
+ end
13
+ let(:parser_engine) { ENV.fetch('PARSER_ENGINE', :parser_whitequark).to_sym }
10
14
  let(:rails_version) { false }
11
15
 
12
16
  def inspect_source(source, file = nil)
@@ -28,7 +32,9 @@ module CopHelper
28
32
  file = file.path
29
33
  end
30
34
 
31
- processed_source = RuboCop::ProcessedSource.new(source, ruby_version, file)
35
+ processed_source = RuboCop::ProcessedSource.new(
36
+ source, ruby_version, file, parser_engine: parser_engine
37
+ )
32
38
  processed_source.config = configuration
33
39
  processed_source.registry = registry
34
40
  processed_source
@@ -111,6 +111,7 @@ module RuboCop
111
111
  source
112
112
  end
113
113
 
114
+ # rubocop:disable Metrics/AbcSize
114
115
  def expect_offense(source, file = nil, severity: nil, chomp: false, **replacements)
115
116
  expected_annotations = parse_annotations(source, **replacements)
116
117
  source = expected_annotations.plain_source
@@ -123,10 +124,17 @@ module RuboCop
123
124
  expect(actual_annotations).to eq(expected_annotations), ''
124
125
  expect(@offenses.map(&:severity).uniq).to eq([severity]) if severity
125
126
 
127
+ # Validate that all offenses have a range that formatters can display
128
+ expect do
129
+ @offenses.each { |offense| offense.location.source_line }
130
+ end.not_to raise_error, 'One of the offenses has a misconstructed range, for ' \
131
+ 'example if the offense is on line 1 and the source is empty'
132
+
126
133
  @offenses
127
134
  end
135
+ # rubocop:enable Metrics/AbcSize
128
136
 
129
- # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
137
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity
130
138
  def expect_correction(correction, loop: true, source: nil)
131
139
  if source
132
140
  expected_annotations = parse_annotations(source, raise_error: false)
@@ -148,7 +156,6 @@ module RuboCop
148
156
 
149
157
  break corrected_source unless loop
150
158
  break corrected_source if @last_corrector.empty?
151
- break corrected_source if corrected_source == @processed_source.buffer.source
152
159
 
153
160
  if iteration > RuboCop::Runner::MAX_ITERATIONS
154
161
  raise RuboCop::Runner::InfiniteCorrectionLoop.new(@processed_source.path, [@offenses])
@@ -163,19 +170,20 @@ module RuboCop
163
170
 
164
171
  expect(new_source).to eq(correction)
165
172
  end
166
- # rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
173
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity
167
174
 
168
175
  def expect_no_corrections
169
176
  raise '`expect_no_corrections` must follow `expect_offense`' unless @processed_source
170
177
 
171
178
  return if @last_corrector.empty?
172
179
 
173
- # In order to print a nice diff, e.g. what source got corrected to,
174
- # we need to run the actual corrections
175
-
180
+ # This is just here for a pretty diff if the source actually got changed
176
181
  new_source = @last_corrector.rewrite
177
-
178
182
  expect(new_source).to eq(@processed_source.buffer.source)
183
+
184
+ # There is an infinite loop if a corrector is present that did not make
185
+ # any changes. It will cause the same offense/correction on the next loop.
186
+ raise RuboCop::Runner::InfiniteCorrectionLoop.new(@processed_source.path, [@offenses])
179
187
  end
180
188
 
181
189
  def expect_no_offenses(source, file = nil)
@@ -212,7 +220,7 @@ module RuboCop
212
220
 
213
221
  # Parsed representation of code annotated with the `^^^ Message` style
214
222
  class AnnotatedSource
215
- ANNOTATION_PATTERN = /\A\s*(\^+|\^{}) /.freeze
223
+ ANNOTATION_PATTERN = /\A\s*(\^+|\^{}) ?/.freeze
216
224
  ABBREV = "[...]\n"
217
225
 
218
226
  # @param annotated_source [String] string passed to the matchers
@@ -50,6 +50,26 @@ RSpec.shared_context 'isolated environment' do # rubocop:disable Metrics/BlockLe
50
50
  end
51
51
  end
52
52
 
53
+ # Workaround for https://github.com/rubocop/rubocop/issues/12978,
54
+ # there should already be no gemfile in the temp directory
55
+ RSpec.shared_context 'isolated bundler' do
56
+ around do |example|
57
+ # No bundler env and reset cached gemfile path
58
+ Bundler.with_unbundled_env do
59
+ old_values = Bundler.instance_variables.to_h do |name|
60
+ [name, Bundler.instance_variable_get(name)]
61
+ end
62
+ Bundler.instance_variables.each { |name| Bundler.remove_instance_variable(name) }
63
+ example.call
64
+ ensure
65
+ Bundler.instance_variables.each { |name| Bundler.remove_instance_variable(name) }
66
+ old_values.each do |name, value|
67
+ Bundler.instance_variable_set(name, value)
68
+ end
69
+ end
70
+ end
71
+ end
72
+
53
73
  RSpec.shared_context 'maintain registry' do
54
74
  around(:each) { |example| RuboCop::Cop::Registry.with_temporary_global { example.run } }
55
75
 
@@ -100,17 +120,29 @@ RSpec.shared_context 'config' do # rubocop:disable Metrics/BlockLength
100
120
  let(:cur_cop_config) do
101
121
  RuboCop::ConfigLoader
102
122
  .default_configuration.for_cop(cop_class)
103
- .merge({
104
- 'Enabled' => true, # in case it is 'pending'
105
- 'AutoCorrect' => true # in case defaults set it to false
106
- })
123
+ .merge(
124
+ 'Enabled' => true, # in case it is 'pending'
125
+ 'AutoCorrect' => 'always' # in case defaults set it to 'disabled' or false
126
+ )
107
127
  .merge(cop_config)
108
128
  end
109
129
 
110
130
  let(:config) do
111
131
  hash = { 'AllCops' => all_cops_config, cop_class.cop_name => cur_cop_config }.merge!(other_cops)
112
132
 
113
- RuboCop::Config.new(hash, "#{Dir.pwd}/.rubocop.yml")
133
+ config = RuboCop::Config.new(hash, "#{Dir.pwd}/.rubocop.yml")
134
+
135
+ rails_version_in_gemfile = Gem::Version.new(
136
+ rails_version || RuboCop::Config::DEFAULT_RAILS_VERSION
137
+ )
138
+
139
+ allow(config).to receive(:gem_versions_in_target).and_return(
140
+ {
141
+ 'railties' => rails_version_in_gemfile
142
+ }
143
+ )
144
+
145
+ config
114
146
  end
115
147
 
116
148
  let(:cop) { cop_class.new(config, cop_options) }
@@ -128,50 +160,75 @@ RSpec.shared_context 'mock console output' do
128
160
  end
129
161
  end
130
162
 
163
+ RSpec.shared_context 'lsp' do
164
+ before do
165
+ RuboCop::LSP.enable
166
+ end
167
+
168
+ after do
169
+ RuboCop::LSP.disable
170
+ end
171
+ end
172
+
131
173
  RSpec.shared_context 'ruby 2.0' do
132
- let(:ruby_version) { 2.0 }
174
+ # Prism supports parsing Ruby 3.3+.
175
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 2.0 }
133
176
  end
134
177
 
135
178
  RSpec.shared_context 'ruby 2.1' do
136
- let(:ruby_version) { 2.1 }
179
+ # Prism supports parsing Ruby 3.3+.
180
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 2.1 }
137
181
  end
138
182
 
139
183
  RSpec.shared_context 'ruby 2.2' do
140
- let(:ruby_version) { 2.2 }
184
+ # Prism supports parsing Ruby 3.3+.
185
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 2.2 }
141
186
  end
142
187
 
143
188
  RSpec.shared_context 'ruby 2.3' do
144
- let(:ruby_version) { 2.3 }
189
+ # Prism supports parsing Ruby 3.3+.
190
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 2.3 }
145
191
  end
146
192
 
147
193
  RSpec.shared_context 'ruby 2.4' do
148
- let(:ruby_version) { 2.4 }
194
+ # Prism supports parsing Ruby 3.3+.
195
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 2.4 }
149
196
  end
150
197
 
151
198
  RSpec.shared_context 'ruby 2.5' do
152
- let(:ruby_version) { 2.5 }
199
+ # Prism supports parsing Ruby 3.3+.
200
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 2.5 }
153
201
  end
154
202
 
155
203
  RSpec.shared_context 'ruby 2.6' do
156
- let(:ruby_version) { 2.6 }
204
+ # Prism supports parsing Ruby 3.3+.
205
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 2.6 }
157
206
  end
158
207
 
159
208
  RSpec.shared_context 'ruby 2.7' do
160
- let(:ruby_version) { 2.7 }
209
+ # Prism supports parsing Ruby 3.3+.
210
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 2.7 }
161
211
  end
162
212
 
163
213
  RSpec.shared_context 'ruby 3.0' do
164
- let(:ruby_version) { 3.0 }
214
+ # Prism supports parsing Ruby 3.3+.
215
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 3.0 }
165
216
  end
166
217
 
167
218
  RSpec.shared_context 'ruby 3.1' do
168
- let(:ruby_version) { 3.1 }
219
+ # Prism supports parsing Ruby 3.3+.
220
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 3.1 }
169
221
  end
170
222
 
171
223
  RSpec.shared_context 'ruby 3.2' do
172
- let(:ruby_version) { 3.2 }
224
+ # Prism supports parsing Ruby 3.3+.
225
+ let(:ruby_version) { ENV['PARSER_ENGINE'] == 'parser_prism' ? 3.3 : 3.2 }
173
226
  end
174
227
 
175
228
  RSpec.shared_context 'ruby 3.3' do
176
229
  let(:ruby_version) { 3.3 }
177
230
  end
231
+
232
+ RSpec.shared_context 'ruby 3.4' do
233
+ let(:ruby_version) { 3.4 }
234
+ end
@@ -13,6 +13,8 @@ RSpec.configure do |config|
13
13
  config.include HostEnvironmentSimulatorHelper
14
14
  config.include_context 'config', :config
15
15
  config.include_context 'isolated environment', :isolated_environment
16
+ config.include_context 'isolated bundler', :isolated_bundler
17
+ config.include_context 'lsp', :lsp
16
18
  config.include_context 'maintain registry', :restore_registry
17
19
  config.include_context 'ruby 2.0', :ruby20
18
20
  config.include_context 'ruby 2.1', :ruby21
@@ -26,4 +28,5 @@ RSpec.configure do |config|
26
28
  config.include_context 'ruby 3.1', :ruby31
27
29
  config.include_context 'ruby 3.2', :ruby32
28
30
  config.include_context 'ruby 3.3', :ruby33
31
+ config.include_context 'ruby 3.4', :ruby34
29
32
  end
@@ -20,7 +20,11 @@ module RuboCop
20
20
  message = 'Infinite loop detected'
21
21
  message += " in #{path}" if path
22
22
  message += " and caused by #{root_cause}" if root_cause
23
- super(message)
23
+ message += "\n"
24
+ hint = 'Hint: Please update to the latest RuboCop version if not already in use, ' \
25
+ "and report a bug if the issue still occurs on this version.\n" \
26
+ 'Please check the latest version at https://rubygems.org/gems/rubocop.'
27
+ super(Rainbow(message).red + Rainbow(hint).yellow)
24
28
  end
25
29
  end
26
30
 
@@ -467,15 +471,21 @@ module RuboCop
467
471
  end
468
472
  end
469
473
 
474
+ # rubocop:disable Metrics/MethodLength
470
475
  def get_processed_source(file)
471
476
  config = @config_store.for_file(file)
472
477
  ruby_version = config.target_ruby_version
478
+ parser_engine = config.parser_engine
473
479
 
474
480
  processed_source = if @options[:stdin]
475
- ProcessedSource.new(@options[:stdin], ruby_version, file)
481
+ ProcessedSource.new(
482
+ @options[:stdin], ruby_version, file, parser_engine: parser_engine
483
+ )
476
484
  else
477
485
  begin
478
- ProcessedSource.from_file(file, ruby_version)
486
+ ProcessedSource.from_file(
487
+ file, ruby_version, parser_engine: parser_engine
488
+ )
479
489
  rescue Errno::ENOENT
480
490
  raise RuboCop::Error, "No such file or directory: #{file}"
481
491
  end
@@ -484,6 +494,7 @@ module RuboCop
484
494
  processed_source.registry = mobilized_cop_classes(config)
485
495
  processed_source
486
496
  end
497
+ # rubocop:enable Metrics/MethodLength
487
498
 
488
499
  # A Cop::Team instance is stateful and may change when inspecting.
489
500
  # The "standby" team for a given config is an initialized but
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fileutils'
3
+ require 'digest'
4
4
  require 'pathname'
5
5
  require_relative '../cache_config'
6
6
  require_relative '../config_finder'
@@ -20,6 +20,7 @@ module RuboCop
20
20
  # @api private
21
21
  class Cache
22
22
  GEMFILE_NAMES = %w[Gemfile gems.rb].freeze
23
+ LOCKFILE_NAMES = %w[Gemfile.lock gems.locked].freeze
23
24
 
24
25
  class << self
25
26
  attr_accessor :cache_root_path
@@ -42,6 +43,14 @@ module RuboCop
42
43
  @project_dir_cache_key ||= project_dir[1..].tr('/', '+')
43
44
  end
44
45
 
46
+ def restart_key
47
+ lockfile_path = LOCKFILE_NAMES.map do |lockfile_name|
48
+ Pathname(project_dir).join(lockfile_name)
49
+ end.find(&:exist?)
50
+
51
+ Digest::SHA1.hexdigest(lockfile_path&.read || RuboCop::Version::STRING)
52
+ end
53
+
45
54
  def dir
46
55
  Pathname.new(File.join(cache_path, project_dir_cache_key)).tap do |d|
47
56
  d.mkpath unless d.exist?
@@ -117,7 +126,7 @@ module RuboCop
117
126
 
118
127
  def pid_running?
119
128
  Process.kill(0, pid_path.read.to_i) == 1
120
- rescue Errno::ESRCH, Errno::ENOENT, Errno::EACCES
129
+ rescue Errno::ESRCH, Errno::ENOENT, Errno::EACCES, Errno::EROFS
121
130
  false
122
131
  end
123
132
 
@@ -17,7 +17,6 @@ module RuboCop
17
17
  class Exec < Base
18
18
  def run
19
19
  ensure_server!
20
- Cache.status_path.delete if Cache.status_path.file?
21
20
  read_stdin = ARGV.include?('-s') || ARGV.include?('--stdin')
22
21
  send_request(
23
22
  command: 'exec',
@@ -42,7 +41,7 @@ module RuboCop
42
41
  end
43
42
 
44
43
  def incompatible_version?
45
- Cache.version_path.read != RuboCop::Version::STRING
44
+ Cache.version_path.read != Cache.restart_key
46
45
  end
47
46
 
48
47
  def stderr
@@ -55,7 +54,7 @@ module RuboCop
55
54
  end
56
55
 
57
56
  status = Cache.status_path.read
58
- raise "RuboCop server: '#{status}' is not a valid status!" if (status =~ /^\d+$/).nil?
57
+ raise "RuboCop server: '#{status}' is not a valid status!" unless /\A\d+\z/.match?(status)
59
58
 
60
59
  status.to_i
61
60
  end