rubocop 0.87.1 → 0.88.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/bin/rubocop-profile +31 -0
- data/config/default.yml +57 -6
- data/lib/rubocop.rb +6 -0
- data/lib/rubocop/cli.rb +2 -2
- data/lib/rubocop/cli/command/auto_genenerate_config.rb +2 -2
- data/lib/rubocop/config_loader.rb +20 -7
- data/lib/rubocop/config_store.rb +4 -0
- data/lib/rubocop/cop/autocorrect_logic.rb +1 -1
- data/lib/rubocop/cop/badge.rb +1 -1
- data/lib/rubocop/cop/base.rb +12 -4
- data/lib/rubocop/cop/cop.rb +1 -1
- data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +26 -0
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +6 -1
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +1 -0
- data/lib/rubocop/cop/layout/end_alignment.rb +3 -2
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +16 -5
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +3 -2
- data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +27 -68
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +3 -2
- data/lib/rubocop/cop/lint/disjunctive_assignment_in_constructor.rb +8 -2
- data/lib/rubocop/cop/lint/duplicate_elsif_condition.rb +39 -0
- data/lib/rubocop/cop/lint/duplicate_methods.rb +2 -2
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +3 -2
- data/lib/rubocop/cop/lint/literal_as_condition.rb +11 -1
- data/lib/rubocop/cop/lint/nested_method_definition.rb +13 -19
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +67 -0
- data/lib/rubocop/cop/mixin/statement_modifier.rb +3 -3
- data/lib/rubocop/cop/style/accessor_grouping.rb +8 -1
- data/lib/rubocop/cop/style/array_coercion.rb +63 -0
- data/lib/rubocop/cop/style/auto_resource_cleanup.rb +3 -2
- data/lib/rubocop/cop/style/bisected_attr_accessor.rb +5 -4
- data/lib/rubocop/cop/style/case_like_if.rb +217 -0
- data/lib/rubocop/cop/style/commented_keyword.rb +5 -2
- data/lib/rubocop/cop/style/conditional_assignment.rb +1 -1
- data/lib/rubocop/cop/style/exponential_notation.rb +6 -8
- data/lib/rubocop/cop/style/float_division.rb +7 -10
- data/lib/rubocop/cop/style/format_string_token.rb +5 -5
- data/lib/rubocop/cop/style/hash_as_last_array_item.rb +62 -0
- data/lib/rubocop/cop/style/hash_like_case.rb +76 -0
- data/lib/rubocop/cop/style/if_unless_modifier.rb +11 -11
- data/lib/rubocop/cop/style/missing_else.rb +1 -11
- data/lib/rubocop/cop/style/numeric_predicate.rb +3 -4
- data/lib/rubocop/cop/style/parallel_assignment.rb +3 -3
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
- data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +50 -0
- data/lib/rubocop/cop/style/redundant_sort.rb +3 -2
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +3 -2
- data/lib/rubocop/cop/style/trailing_method_end_statement.rb +9 -32
- data/lib/rubocop/cop/variable_force/variable.rb +5 -3
- data/lib/rubocop/file_finder.rb +12 -12
- data/lib/rubocop/path_util.rb +2 -17
- data/lib/rubocop/result_cache.rb +12 -8
- data/lib/rubocop/rspec/expect_offense.rb +31 -5
- data/lib/rubocop/rspec/shared_contexts.rb +12 -9
- data/lib/rubocop/runner.rb +5 -6
- data/lib/rubocop/target_finder.rb +2 -2
- data/lib/rubocop/version.rb +1 -1
- metadata +9 -2
data/lib/rubocop/path_util.rb
CHANGED
@@ -5,7 +5,7 @@ module RuboCop
|
|
5
5
|
module PathUtil
|
6
6
|
module_function
|
7
7
|
|
8
|
-
def relative_path(path, base_dir =
|
8
|
+
def relative_path(path, base_dir = Dir.pwd)
|
9
9
|
# Optimization for the common case where path begins with the base
|
10
10
|
# dir. Just cut off the first part.
|
11
11
|
if path.start_with?(base_dir)
|
@@ -24,7 +24,7 @@ module RuboCop
|
|
24
24
|
|
25
25
|
def smart_path(path)
|
26
26
|
# Ideally, we calculate this relative to the project root.
|
27
|
-
base_dir =
|
27
|
+
base_dir = Dir.pwd
|
28
28
|
|
29
29
|
if path.start_with? base_dir
|
30
30
|
relative_path(path, base_dir)
|
@@ -54,21 +54,6 @@ module RuboCop
|
|
54
54
|
%r{\A([A-Z]:)?/}i.match?(path)
|
55
55
|
end
|
56
56
|
|
57
|
-
def self.pwd
|
58
|
-
@pwd ||= Dir.pwd
|
59
|
-
end
|
60
|
-
|
61
|
-
def self.reset_pwd
|
62
|
-
@pwd = nil
|
63
|
-
end
|
64
|
-
|
65
|
-
def self.chdir(dir, &block)
|
66
|
-
reset_pwd
|
67
|
-
Dir.chdir(dir, &block)
|
68
|
-
ensure
|
69
|
-
reset_pwd
|
70
|
-
end
|
71
|
-
|
72
57
|
def hidden_file_in_not_hidden_dir?(pattern, path)
|
73
58
|
File.fnmatch?(
|
74
59
|
pattern, path,
|
data/lib/rubocop/result_cache.rb
CHANGED
@@ -33,7 +33,7 @@ module RuboCop
|
|
33
33
|
|
34
34
|
def requires_file_removal?(file_count, config_store)
|
35
35
|
file_count > 1 &&
|
36
|
-
file_count > config_store.
|
36
|
+
file_count > config_store.for_pwd.for_all_cops['MaxFilesInCache']
|
37
37
|
end
|
38
38
|
|
39
39
|
def remove_oldest_files(files, dirs, cache_root, verbose)
|
@@ -60,7 +60,7 @@ module RuboCop
|
|
60
60
|
end
|
61
61
|
|
62
62
|
def self.cache_root(config_store)
|
63
|
-
root = config_store.
|
63
|
+
root = config_store.for_pwd.for_all_cops['CacheRootDirectory']
|
64
64
|
root ||= if ENV.key?('XDG_CACHE_HOME')
|
65
65
|
# Include user ID in the path to make sure the user has write
|
66
66
|
# access.
|
@@ -72,7 +72,7 @@ module RuboCop
|
|
72
72
|
end
|
73
73
|
|
74
74
|
def self.allow_symlinks_in_cache_location?(config_store)
|
75
|
-
config_store.
|
75
|
+
config_store.for_pwd.for_all_cops['AllowSymlinksInCacheRootDirectory']
|
76
76
|
end
|
77
77
|
|
78
78
|
def initialize(file, team, options, config_store, cache_root = nil)
|
@@ -158,6 +158,7 @@ module RuboCop
|
|
158
158
|
end
|
159
159
|
|
160
160
|
# The checksum of the rubocop program running the inspection.
|
161
|
+
# rubocop:disable Metrics/AbcSize
|
161
162
|
def rubocop_checksum
|
162
163
|
ResultCache.source_checksum ||=
|
163
164
|
begin
|
@@ -168,13 +169,16 @@ module RuboCop
|
|
168
169
|
# exe directory. A change to any of them could affect the cop output
|
169
170
|
# so we include them in the cache hash.
|
170
171
|
source_files = $LOADED_FEATURES + Find.find(exe_root).to_a
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
172
|
+
|
173
|
+
digest = Digest::SHA1.new
|
174
|
+
source_files
|
175
|
+
.select { |path| File.file?(path) }
|
176
|
+
.sort!
|
177
|
+
.each { |path| digest << File.mtime(path).to_s }
|
178
|
+
digest.hexdigest
|
176
179
|
end
|
177
180
|
end
|
181
|
+
# rubocop:enable Metrics/AbcSize
|
178
182
|
|
179
183
|
# Return a hash of the options given at invocation, minus the ones that have
|
180
184
|
# no effect on which offenses and disabled line ranges are found, and thus
|
@@ -73,19 +73,20 @@ module RuboCop
|
|
73
73
|
# expect_no_corrections
|
74
74
|
#
|
75
75
|
# If your code has variables of different lengths, you can use `%{foo}`,
|
76
|
-
# `^{foo}`, and `_{foo}` to format your template
|
76
|
+
# `^{foo}`, and `_{foo}` to format your template; you can also abbreviate
|
77
|
+
# offense messages with `[...]`:
|
77
78
|
#
|
78
79
|
# %w[raise fail].each do |keyword|
|
79
80
|
# expect_offense(<<~RUBY, keyword: keyword)
|
80
81
|
# %{keyword}(RuntimeError, msg)
|
81
|
-
# ^{keyword}^^^^^^^^^^^^^^^^^^^ Redundant `RuntimeError` argument
|
82
|
+
# ^{keyword}^^^^^^^^^^^^^^^^^^^ Redundant `RuntimeError` argument [...]
|
82
83
|
# RUBY
|
83
84
|
#
|
84
85
|
# %w[has_one has_many].each do |type|
|
85
86
|
# expect_offense(<<~RUBY, type: type)
|
86
87
|
# class Book
|
87
88
|
# %{type} :chapter, foreign_key: 'book_id'
|
88
|
-
# _{type} ^^^^^^^^^^^^^^^^^^^^^^ Specifying the default
|
89
|
+
# _{type} ^^^^^^^^^^^^^^^^^^^^^^ Specifying the default [...]
|
89
90
|
# end
|
90
91
|
# RUBY
|
91
92
|
# end
|
@@ -102,6 +103,7 @@ module RuboCop
|
|
102
103
|
module ExpectOffense
|
103
104
|
def format_offense(source, **replacements)
|
104
105
|
replacements.each do |keyword, value|
|
106
|
+
value = value.to_s
|
105
107
|
source = source.gsub("%{#{keyword}}", value)
|
106
108
|
.gsub("^{#{keyword}}", '^' * value.size)
|
107
109
|
.gsub("_{#{keyword}}", ' ' * value.size)
|
@@ -132,7 +134,7 @@ module RuboCop
|
|
132
134
|
actual_annotations =
|
133
135
|
expected_annotations.with_offense_annotations(offenses)
|
134
136
|
|
135
|
-
expect(actual_annotations
|
137
|
+
expect(actual_annotations).to eq(expected_annotations)
|
136
138
|
expect(offenses.map(&:severity).uniq).to eq([severity]) if severity
|
137
139
|
end
|
138
140
|
|
@@ -188,6 +190,7 @@ module RuboCop
|
|
188
190
|
# Parsed representation of code annotated with the `^^^ Message` style
|
189
191
|
class AnnotatedSource
|
190
192
|
ANNOTATION_PATTERN = /\A\s*(\^+|\^{}) /.freeze
|
193
|
+
ABBREV = "[...]\n"
|
191
194
|
|
192
195
|
# @param annotated_source [String] string passed to the matchers
|
193
196
|
#
|
@@ -206,6 +209,7 @@ module RuboCop
|
|
206
209
|
source << source_line
|
207
210
|
end
|
208
211
|
end
|
212
|
+
annotations.each { |a| a[0] = 1 } if source.empty?
|
209
213
|
|
210
214
|
new(source, annotations)
|
211
215
|
end
|
@@ -221,6 +225,27 @@ module RuboCop
|
|
221
225
|
@annotations = annotations.sort.freeze
|
222
226
|
end
|
223
227
|
|
228
|
+
def ==(other)
|
229
|
+
other.is_a?(self.class) &&
|
230
|
+
other.lines == lines &&
|
231
|
+
match_annotations?(other)
|
232
|
+
end
|
233
|
+
|
234
|
+
# Dirty hack: expectations with [...] are rewritten when they match
|
235
|
+
# This way the diff is clean.
|
236
|
+
def match_annotations?(other)
|
237
|
+
annotations.zip(other.annotations) do |(_actual_line, actual_annotation),
|
238
|
+
(_expected_line, expected_annotation)|
|
239
|
+
if expected_annotation&.end_with?(ABBREV)
|
240
|
+
if actual_annotation.start_with?(expected_annotation[0...-ABBREV.length])
|
241
|
+
expected_annotation.replace(actual_annotation)
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
annotations == other.annotations
|
247
|
+
end
|
248
|
+
|
224
249
|
# Construct annotated source string (like what we parse)
|
225
250
|
#
|
226
251
|
# Reconstruct a deterministic annotated source string. This is
|
@@ -253,6 +278,7 @@ module RuboCop
|
|
253
278
|
|
254
279
|
reconstructed.join
|
255
280
|
end
|
281
|
+
alias inspect to_s
|
256
282
|
|
257
283
|
# Return the plain source code without annotations
|
258
284
|
#
|
@@ -279,7 +305,7 @@ module RuboCop
|
|
279
305
|
self.class.new(lines, offense_annotations)
|
280
306
|
end
|
281
307
|
|
282
|
-
|
308
|
+
protected
|
283
309
|
|
284
310
|
attr_reader :lines, :annotations
|
285
311
|
end
|
@@ -12,19 +12,22 @@ RSpec.shared_context 'isolated environment', :isolated_environment do
|
|
12
12
|
# get mismatched pathnames when loading config files later on.
|
13
13
|
tmpdir = File.realpath(tmpdir)
|
14
14
|
|
15
|
+
virtual_home = File.expand_path(File.join(tmpdir, 'home'))
|
16
|
+
Dir.mkdir(virtual_home)
|
17
|
+
ENV['HOME'] = virtual_home
|
18
|
+
ENV.delete('XDG_CONFIG_HOME')
|
19
|
+
|
20
|
+
base_dir = example.metadata[:project_inside_home] ? virtual_home : tmpdir
|
21
|
+
root = example.metadata[:root]
|
22
|
+
working_dir = root ? File.join(base_dir, 'work', root) : File.join(base_dir, 'work')
|
23
|
+
|
15
24
|
# Make upwards search for .rubocop.yml files stop at this directory.
|
16
|
-
RuboCop::FileFinder.root_level =
|
25
|
+
RuboCop::FileFinder.root_level = working_dir
|
17
26
|
|
18
27
|
begin
|
19
|
-
|
20
|
-
Dir.mkdir(virtual_home)
|
21
|
-
ENV['HOME'] = virtual_home
|
22
|
-
ENV.delete('XDG_CONFIG_HOME')
|
23
|
-
|
24
|
-
working_dir = File.join(tmpdir, 'work')
|
25
|
-
Dir.mkdir(working_dir)
|
28
|
+
FileUtils.mkdir_p(working_dir)
|
26
29
|
|
27
|
-
|
30
|
+
Dir.chdir(working_dir) do
|
28
31
|
example.run
|
29
32
|
end
|
30
33
|
ensure
|
data/lib/rubocop/runner.rb
CHANGED
@@ -118,8 +118,7 @@ module RuboCop
|
|
118
118
|
|
119
119
|
def file_offenses(file)
|
120
120
|
file_offense_cache(file) do
|
121
|
-
source =
|
122
|
-
source, offenses = do_inspection_loop(file, source)
|
121
|
+
source, offenses = do_inspection_loop(file)
|
123
122
|
offenses = add_redundant_disables(file, offenses.compact.sort, source)
|
124
123
|
offenses.sort.reject(&:disabled?).freeze
|
125
124
|
end
|
@@ -159,8 +158,7 @@ module RuboCop
|
|
159
158
|
# Do one extra inspection loop if any redundant disables were
|
160
159
|
# removed. This is done in order to find rubocop:enable directives that
|
161
160
|
# have now become useless.
|
162
|
-
_source, new_offenses = do_inspection_loop(file
|
163
|
-
get_processed_source(file))
|
161
|
+
_source, new_offenses = do_inspection_loop(file)
|
164
162
|
offenses |= new_offenses
|
165
163
|
end
|
166
164
|
end
|
@@ -213,7 +211,7 @@ module RuboCop
|
|
213
211
|
@cached_run ||=
|
214
212
|
(@options[:cache] == 'true' ||
|
215
213
|
@options[:cache] != 'false' &&
|
216
|
-
@config_store.
|
214
|
+
@config_store.for_pwd.for_all_cops['UseCache']) &&
|
217
215
|
# When running --auto-gen-config, there's some processing done in the
|
218
216
|
# cops related to calculating the Max parameters for Metrics cops. We
|
219
217
|
# need to do that processing and cannot use caching.
|
@@ -232,7 +230,8 @@ module RuboCop
|
|
232
230
|
cache.save(offenses)
|
233
231
|
end
|
234
232
|
|
235
|
-
def do_inspection_loop(file
|
233
|
+
def do_inspection_loop(file)
|
234
|
+
processed_source = get_processed_source(file)
|
236
235
|
offenses = []
|
237
236
|
|
238
237
|
# When running with --auto-correct, we need to inspect the file (which
|
@@ -132,7 +132,7 @@ module RuboCop
|
|
132
132
|
end
|
133
133
|
|
134
134
|
def all_cops_include
|
135
|
-
@config_store.
|
135
|
+
@config_store.for_pwd.for_all_cops['Include'].map(&:to_s)
|
136
136
|
end
|
137
137
|
|
138
138
|
def ruby_executable?(file)
|
@@ -160,7 +160,7 @@ module RuboCop
|
|
160
160
|
end
|
161
161
|
|
162
162
|
def configured_include?(file)
|
163
|
-
@config_store.
|
163
|
+
@config_store.for_pwd.file_to_include?(file)
|
164
164
|
end
|
165
165
|
|
166
166
|
def included_file?(file)
|
data/lib/rubocop/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.88.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bozhidar Batsov
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2020-07-
|
13
|
+
date: 2020-07-13 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: parallel
|
@@ -178,6 +178,7 @@ files:
|
|
178
178
|
- assets/logo.png
|
179
179
|
- assets/output.html.erb
|
180
180
|
- bin/console
|
181
|
+
- bin/rubocop-profile
|
181
182
|
- bin/setup
|
182
183
|
- config/default.yml
|
183
184
|
- exe/rubocop
|
@@ -347,6 +348,7 @@ files:
|
|
347
348
|
- lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb
|
348
349
|
- lib/rubocop/cop/lint/disjunctive_assignment_in_constructor.rb
|
349
350
|
- lib/rubocop/cop/lint/duplicate_case_condition.rb
|
351
|
+
- lib/rubocop/cop/lint/duplicate_elsif_condition.rb
|
350
352
|
- lib/rubocop/cop/lint/duplicate_hash_key.rb
|
351
353
|
- lib/rubocop/cop/lint/duplicate_methods.rb
|
352
354
|
- lib/rubocop/cop/lint/each_with_object_argument.rb
|
@@ -529,6 +531,7 @@ files:
|
|
529
531
|
- lib/rubocop/cop/style/accessor_grouping.rb
|
530
532
|
- lib/rubocop/cop/style/alias.rb
|
531
533
|
- lib/rubocop/cop/style/and_or.rb
|
534
|
+
- lib/rubocop/cop/style/array_coercion.rb
|
532
535
|
- lib/rubocop/cop/style/array_join.rb
|
533
536
|
- lib/rubocop/cop/style/ascii_comments.rb
|
534
537
|
- lib/rubocop/cop/style/attr.rb
|
@@ -539,6 +542,7 @@ files:
|
|
539
542
|
- lib/rubocop/cop/style/block_comments.rb
|
540
543
|
- lib/rubocop/cop/style/block_delimiters.rb
|
541
544
|
- lib/rubocop/cop/style/case_equality.rb
|
545
|
+
- lib/rubocop/cop/style/case_like_if.rb
|
542
546
|
- lib/rubocop/cop/style/character_literal.rb
|
543
547
|
- lib/rubocop/cop/style/class_and_module_children.rb
|
544
548
|
- lib/rubocop/cop/style/class_check.rb
|
@@ -582,7 +586,9 @@ files:
|
|
582
586
|
- lib/rubocop/cop/style/frozen_string_literal_comment.rb
|
583
587
|
- lib/rubocop/cop/style/global_vars.rb
|
584
588
|
- lib/rubocop/cop/style/guard_clause.rb
|
589
|
+
- lib/rubocop/cop/style/hash_as_last_array_item.rb
|
585
590
|
- lib/rubocop/cop/style/hash_each_methods.rb
|
591
|
+
- lib/rubocop/cop/style/hash_like_case.rb
|
586
592
|
- lib/rubocop/cop/style/hash_syntax.rb
|
587
593
|
- lib/rubocop/cop/style/hash_transform_keys.rb
|
588
594
|
- lib/rubocop/cop/style/hash_transform_values.rb
|
@@ -654,6 +660,7 @@ files:
|
|
654
660
|
- lib/rubocop/cop/style/redundant_conditional.rb
|
655
661
|
- lib/rubocop/cop/style/redundant_exception.rb
|
656
662
|
- lib/rubocop/cop/style/redundant_fetch_block.rb
|
663
|
+
- lib/rubocop/cop/style/redundant_file_extension_in_require.rb
|
657
664
|
- lib/rubocop/cop/style/redundant_freeze.rb
|
658
665
|
- lib/rubocop/cop/style/redundant_interpolation.rb
|
659
666
|
- lib/rubocop/cop/style/redundant_parentheses.rb
|