rubocop 0.53.0 → 0.54.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/config/default.yml +16 -3
- data/config/enabled.yml +10 -0
- data/lib/rubocop.rb +2 -0
- data/lib/rubocop/cli.rb +3 -1
- data/lib/rubocop/config.rb +41 -4
- data/lib/rubocop/config_loader.rb +1 -2
- data/lib/rubocop/config_loader_resolver.rb +5 -5
- data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
- data/lib/rubocop/cop/layout/else_alignment.rb +14 -10
- data/lib/rubocop/cop/layout/empty_comment.rb +22 -2
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +1 -1
- data/lib/rubocop/cop/layout/indent_heredoc.rb +21 -4
- data/lib/rubocop/cop/mixin/uncommunicative_name.rb +3 -3
- data/lib/rubocop/cop/naming/constant_name.rb +13 -4
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +3 -2
- data/lib/rubocop/cop/rails/http_status.rb +181 -0
- data/lib/rubocop/cop/rails/skips_model_validations.rb +2 -2
- data/lib/rubocop/cop/style/documentation.rb +7 -0
- data/lib/rubocop/cop/style/empty_line_after_guard_clause.rb +16 -1
- data/lib/rubocop/cop/style/format_string_token.rb +8 -0
- data/lib/rubocop/cop/style/inline_comment.rb +3 -1
- data/lib/rubocop/cop/style/inverse_methods.rb +22 -5
- data/lib/rubocop/cop/style/redundant_begin.rb +20 -0
- data/lib/rubocop/cop/style/safe_navigation.rb +2 -1
- data/lib/rubocop/cop/style/trivial_accessors.rb +3 -0
- data/lib/rubocop/cop/style/unpack_first.rb +67 -0
- data/lib/rubocop/cop/util.rb +3 -11
- data/lib/rubocop/formatter/offense_count_formatter.rb +17 -0
- data/lib/rubocop/magic_comment.rb +1 -1
- data/lib/rubocop/target_finder.rb +1 -1
- data/lib/rubocop/version.rb +1 -1
- metadata +18 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b90da169ae8cd99e01c43d41be0a4d43911dcf77
|
4
|
+
data.tar.gz: 5c1db29014d29765ee9400b93d695a0beee04e4a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 750f559ae4fe5bdc11721d45907baf604f37b182602045ef38c62ca277302e3834a99bb7dab80ddd5eb70be9d358b309aeb37129a85aefeb0234ffdb54848f04
|
7
|
+
data.tar.gz: f3f987115edf268066df468d4077c1f1e160dce133b277b6ac6a261cf26a7e26e41f6f54fe24eecf626858931016a7562e9386b7f2a3180f1c31f0500dfe2f67
|
data/README.md
CHANGED
@@ -52,7 +52,7 @@ haven't reached version 1.0 yet). To prevent an unwanted RuboCop update you
|
|
52
52
|
might want to use a conservative version locking in your `Gemfile`:
|
53
53
|
|
54
54
|
```rb
|
55
|
-
gem 'rubocop', '~> 0.
|
55
|
+
gem 'rubocop', '~> 0.54.0', require: false
|
56
56
|
```
|
57
57
|
|
58
58
|
## Quickstart
|
data/config/default.yml
CHANGED
@@ -115,9 +115,15 @@ AllCops:
|
|
115
115
|
AllowSymlinksInCacheRootDirectory: false
|
116
116
|
# What MRI version of the Ruby interpreter is the inspected code intended to
|
117
117
|
# run on? (If there is more than one, set this to the lowest version.)
|
118
|
-
# If a value is specified for TargetRubyVersion then it is used.
|
119
|
-
#
|
120
|
-
#
|
118
|
+
# If a value is specified for TargetRubyVersion then it is used. Acceptable
|
119
|
+
# values are specificed as a float (i.e. 2.5); the teeny version of Ruby
|
120
|
+
# should not be included. If the project specifies a Ruby version in the
|
121
|
+
# .ruby-version file, Gemfile or gems.rb file, RuboCop will try to determine
|
122
|
+
# the desired version of Ruby by inspecting the .ruby-version file first,
|
123
|
+
# followed by the Gemfile.lock or gems.locked file. (Although the Ruby version
|
124
|
+
# is specified in the Gemfile or gems.rb file, RuboCop reads the final value
|
125
|
+
# from the lock file.) If the Ruby version is still unresolved, RuboCop will
|
126
|
+
# use the oldest officially supported Ruby version (currently Ruby 2.1).
|
121
127
|
TargetRubyVersion: ~
|
122
128
|
# What version of Rails is the inspected code using? If a value is specified
|
123
129
|
# for TargetRailsVersion then it is used. Acceptable values are specificed
|
@@ -762,6 +768,7 @@ Naming/UncommunicativeMethodParamName:
|
|
762
768
|
AllowedNames:
|
763
769
|
- io
|
764
770
|
- id
|
771
|
+
- to
|
765
772
|
# Blacklisted names that will register an offense
|
766
773
|
ForbiddenNames: []
|
767
774
|
|
@@ -1666,6 +1673,12 @@ Rails/HasManyOrHasOneDependent:
|
|
1666
1673
|
Include:
|
1667
1674
|
- app/models/**/*.rb
|
1668
1675
|
|
1676
|
+
Rails/HttpStatus:
|
1677
|
+
EnforcedStyle: symbolic
|
1678
|
+
SupportedStyles:
|
1679
|
+
- numeric
|
1680
|
+
- symbolic
|
1681
|
+
|
1669
1682
|
Rails/InverseOf:
|
1670
1683
|
Include:
|
1671
1684
|
- app/models/**/*.rb
|
data/config/enabled.yml
CHANGED
@@ -1169,6 +1169,10 @@ Rails/HttpPositionalArguments:
|
|
1169
1169
|
- 'spec/**/*'
|
1170
1170
|
- 'test/**/*'
|
1171
1171
|
|
1172
|
+
Rails/HttpStatus:
|
1173
|
+
Description: 'Enforces use of symbolic or numeric value to define HTTP status.'
|
1174
|
+
Enabled: true
|
1175
|
+
|
1172
1176
|
Rails/InverseOf:
|
1173
1177
|
Description: 'Checks for associations where the inverse cannot be determined automatically.'
|
1174
1178
|
Enabled: true
|
@@ -2006,6 +2010,12 @@ Style/UnneededPercentQ:
|
|
2006
2010
|
StyleGuide: '#percent-q'
|
2007
2011
|
Enabled: true
|
2008
2012
|
|
2013
|
+
Style/UnpackFirst:
|
2014
|
+
Description: >-
|
2015
|
+
Checks for accessing the first element of `String#unpack`
|
2016
|
+
instead of using `unpack1`
|
2017
|
+
Enabled: true
|
2018
|
+
|
2009
2019
|
Style/VariableInterpolation:
|
2010
2020
|
Description: >-
|
2011
2021
|
Don't interpolate global, instance and class variables
|
data/lib/rubocop.rb
CHANGED
@@ -522,6 +522,7 @@ require_relative 'rubocop/cop/style/unless_else'
|
|
522
522
|
require_relative 'rubocop/cop/style/unneeded_capital_w'
|
523
523
|
require_relative 'rubocop/cop/style/unneeded_interpolation'
|
524
524
|
require_relative 'rubocop/cop/style/unneeded_percent_q'
|
525
|
+
require_relative 'rubocop/cop/style/unpack_first'
|
525
526
|
require_relative 'rubocop/cop/style/variable_interpolation'
|
526
527
|
require_relative 'rubocop/cop/style/when_then'
|
527
528
|
require_relative 'rubocop/cop/style/while_until_do'
|
@@ -550,6 +551,7 @@ require_relative 'rubocop/cop/rails/find_each'
|
|
550
551
|
require_relative 'rubocop/cop/rails/has_and_belongs_to_many'
|
551
552
|
require_relative 'rubocop/cop/rails/has_many_or_has_one_dependent'
|
552
553
|
require_relative 'rubocop/cop/rails/http_positional_arguments'
|
554
|
+
require_relative 'rubocop/cop/rails/http_status'
|
553
555
|
require_relative 'rubocop/cop/rails/inverse_of'
|
554
556
|
require_relative 'rubocop/cop/rails/lexically_scoped_action_filter'
|
555
557
|
require_relative 'rubocop/cop/rails/not_null_column'
|
data/lib/rubocop/cli.rb
CHANGED
@@ -41,7 +41,7 @@ module RuboCop
|
|
41
41
|
execute_runners(paths)
|
42
42
|
rescue RuboCop::ConfigNotFoundError => e
|
43
43
|
warn e.message
|
44
|
-
|
44
|
+
STATUS_ERROR
|
45
45
|
rescue RuboCop::Error => e
|
46
46
|
warn Rainbow("Error: #{e.message}").red
|
47
47
|
STATUS_ERROR
|
@@ -258,6 +258,8 @@ module RuboCop
|
|
258
258
|
warn <<-WARNING.strip_indent
|
259
259
|
Errors are usually caused by RuboCop bugs.
|
260
260
|
Please, report your problems to RuboCop's issue tracker.
|
261
|
+
#{Gem.loaded_specs['rubocop'].metadata['bug_tracker_uri']}
|
262
|
+
|
261
263
|
Mention the following information in the issue report:
|
262
264
|
#{RuboCop::Version.version(true)}
|
263
265
|
WARNING
|
data/lib/rubocop/config.rb
CHANGED
@@ -425,6 +425,10 @@ module RuboCop
|
|
425
425
|
@target_ruby_version_source = :ruby_version_file
|
426
426
|
|
427
427
|
target_ruby_version_from_version_file
|
428
|
+
elsif target_ruby_version_from_bundler_lock_file
|
429
|
+
@target_ruby_version_source = :bundler_lock_file
|
430
|
+
|
431
|
+
target_ruby_version_from_bundler_lock_file
|
428
432
|
else
|
429
433
|
DEFAULT_RUBY_VERSION
|
430
434
|
end
|
@@ -557,6 +561,8 @@ module RuboCop
|
|
557
561
|
case @target_ruby_version_source
|
558
562
|
when :ruby_version_file
|
559
563
|
"`#{RUBY_VERSION_FILENAME}`"
|
564
|
+
when :bundler_lock_file
|
565
|
+
"`#{bundler_lock_file_path}`"
|
560
566
|
when :rubocop_yml
|
561
567
|
"`TargetRubyVersion` parameter (in #{smart_loaded_path})"
|
562
568
|
end
|
@@ -577,6 +583,37 @@ module RuboCop
|
|
577
583
|
end
|
578
584
|
end
|
579
585
|
|
586
|
+
def target_ruby_version_from_bundler_lock_file
|
587
|
+
@target_ruby_version_from_bundler_lock_file ||=
|
588
|
+
read_ruby_version_from_bundler_lock_file
|
589
|
+
end
|
590
|
+
|
591
|
+
def read_ruby_version_from_bundler_lock_file
|
592
|
+
lock_file_path = bundler_lock_file_path
|
593
|
+
return nil unless lock_file_path
|
594
|
+
|
595
|
+
in_ruby_section = false
|
596
|
+
File.foreach(lock_file_path) do |line|
|
597
|
+
# If ruby is in Gemfile.lock or gems.lock, there should be two lines
|
598
|
+
# towards the bottom of the file that look like:
|
599
|
+
# RUBY VERSION
|
600
|
+
# ruby W.X.YpZ
|
601
|
+
# We ultimately want to match the "ruby W.X.Y.pZ" line, but there's
|
602
|
+
# extra logic to make sure we only start looking once we've seen the
|
603
|
+
# "RUBY VERSION" line.
|
604
|
+
in_ruby_section ||= line.match(/^\s*RUBY\s*VERSION\s*$/)
|
605
|
+
next unless in_ruby_section
|
606
|
+
# We currently only allow this feature to work with MRI ruby. If jruby
|
607
|
+
# (or something else) is used by the project, it's lock file will have a
|
608
|
+
# line that looks like:
|
609
|
+
# RUBY VERSION
|
610
|
+
# ruby W.X.YpZ (jruby x.x.x.x)
|
611
|
+
# The regex won't match in this situation.
|
612
|
+
result = line.match(/^\s*ruby\s+(\d+\.\d+)[p.\d]*\s*$/)
|
613
|
+
return result.captures.first.to_f if result
|
614
|
+
end
|
615
|
+
end
|
616
|
+
|
580
617
|
def target_rails_version_from_bundler_lock_file
|
581
618
|
@target_rails_version_from_bundler_lock_file ||=
|
582
619
|
read_rails_version_from_bundler_lock_file
|
@@ -587,9 +624,9 @@ module RuboCop
|
|
587
624
|
return nil unless lock_file_path
|
588
625
|
|
589
626
|
File.foreach(lock_file_path) do |line|
|
590
|
-
# If rails is in
|
627
|
+
# If rails is in Gemfile.lock or gems.lock, there should be a line like:
|
591
628
|
# rails (X.X.X)
|
592
|
-
result = line.match(/^\s+rails\s+\((\d
|
629
|
+
result = line.match(/^\s+rails\s+\((\d+\.\d+)/)
|
593
630
|
return result.captures.first.to_f if result
|
594
631
|
end
|
595
632
|
end
|
@@ -598,8 +635,8 @@ module RuboCop
|
|
598
635
|
return nil unless loaded_path
|
599
636
|
base_path = base_dir_for_path_parameters
|
600
637
|
['gems.locked', 'Gemfile.lock'].each do |file_name|
|
601
|
-
path =
|
602
|
-
return path if
|
638
|
+
path = find_file_upwards(file_name, base_path)
|
639
|
+
return path if path
|
603
640
|
end
|
604
641
|
nil
|
605
642
|
end
|
@@ -35,7 +35,6 @@ module RuboCop
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def load_file(file)
|
38
|
-
return if file.nil?
|
39
38
|
path = File.absolute_path(file.is_a?(RemoteConfig) ? file.file : file)
|
40
39
|
|
41
40
|
hash = load_yaml_configuration(path)
|
@@ -47,7 +46,7 @@ module RuboCop
|
|
47
46
|
target_ruby_version_to_f!(hash)
|
48
47
|
|
49
48
|
resolver.resolve_inheritance_from_gems(hash, hash.delete('inherit_gem'))
|
50
|
-
resolver.resolve_inheritance(path, hash, file)
|
49
|
+
resolver.resolve_inheritance(path, hash, file, debug?)
|
51
50
|
|
52
51
|
hash.delete('inherit_from')
|
53
52
|
hash.delete('inherit_mode')
|
@@ -17,7 +17,7 @@ module RuboCop
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
def resolve_inheritance(path, hash, file)
|
20
|
+
def resolve_inheritance(path, hash, file, debug)
|
21
21
|
inherited_files = Array(hash['inherit_from'])
|
22
22
|
base_configs(path, inherited_files, file)
|
23
23
|
.reverse.each_with_index do |base_config, index|
|
@@ -25,7 +25,7 @@ module RuboCop
|
|
25
25
|
next unless v.is_a?(Hash)
|
26
26
|
if hash.key?(k)
|
27
27
|
v = merge(v, hash[k],
|
28
|
-
cop_name: k, file: file,
|
28
|
+
cop_name: k, file: file, debug: debug,
|
29
29
|
inherited_file: inherited_files[index],
|
30
30
|
inherit_mode: determine_inherit_mode(hash, k))
|
31
31
|
end
|
@@ -86,7 +86,7 @@ module RuboCop
|
|
86
86
|
result[key] = merge(base_hash[key], derived_hash[key])
|
87
87
|
elsif should_union?(base_hash, key, opts[:inherit_mode])
|
88
88
|
result[key] = base_hash[key] | derived_hash[key]
|
89
|
-
|
89
|
+
elsif opts[:debug]
|
90
90
|
warn_on_duplicate_setting(base_hash, derived_hash, key, opts)
|
91
91
|
end
|
92
92
|
end
|
@@ -112,9 +112,9 @@ module RuboCop
|
|
112
112
|
return if base_hash[key].is_a?(Array) &&
|
113
113
|
inherit_mode && inherit_mode.include?(key)
|
114
114
|
|
115
|
-
|
115
|
+
puts "#{PathUtil.smart_path(opts[:file])}: " \
|
116
116
|
"#{opts[:cop_name]}:#{key} overrides " \
|
117
|
-
"the same parameter in #{opts[:inherited_file]}"
|
117
|
+
"the same parameter in #{opts[:inherited_file]}"
|
118
118
|
end
|
119
119
|
|
120
120
|
def determine_inherit_mode(hash, key)
|
@@ -58,7 +58,7 @@ module RuboCop
|
|
58
58
|
|
59
59
|
def previous_declaration(node)
|
60
60
|
declarations = gem_declarations(processed_source.ast)
|
61
|
-
node_index = declarations.find_index(node)
|
61
|
+
node_index = declarations.map(&:location).find_index(node.location)
|
62
62
|
declarations.to_a[node_index - 1]
|
63
63
|
end
|
64
64
|
|
@@ -40,7 +40,7 @@ module RuboCop
|
|
40
40
|
return if ignored_node?(node)
|
41
41
|
return unless node.else? && begins_its_line?(node.loc.else)
|
42
42
|
|
43
|
-
check_alignment(
|
43
|
+
check_alignment(base_range_of_if(node, base), node.loc.else)
|
44
44
|
|
45
45
|
return unless node.elsif_conditional?
|
46
46
|
|
@@ -50,14 +50,7 @@ module RuboCop
|
|
50
50
|
def on_rescue(node)
|
51
51
|
return unless node.loc.respond_to?(:else) && node.loc.else
|
52
52
|
|
53
|
-
|
54
|
-
parent = parent.parent if parent.ensure_type?
|
55
|
-
base = case parent.type
|
56
|
-
when :def, :defs then base_for_method_definition(parent)
|
57
|
-
when :kwbegin then parent.loc.begin
|
58
|
-
else node.loc.keyword
|
59
|
-
end
|
60
|
-
check_alignment(base, node.loc.else)
|
53
|
+
check_alignment(base_range_of_rescue(node), node.loc.else)
|
61
54
|
end
|
62
55
|
|
63
56
|
def on_case(node)
|
@@ -77,7 +70,7 @@ module RuboCop
|
|
77
70
|
ignore_node(node)
|
78
71
|
end
|
79
72
|
|
80
|
-
def
|
73
|
+
def base_range_of_if(node, base)
|
81
74
|
if base
|
82
75
|
base.source_range
|
83
76
|
else
|
@@ -86,6 +79,17 @@ module RuboCop
|
|
86
79
|
end
|
87
80
|
end
|
88
81
|
|
82
|
+
def base_range_of_rescue(node)
|
83
|
+
parent = node.parent
|
84
|
+
parent = parent.parent if parent.ensure_type?
|
85
|
+
case parent.type
|
86
|
+
when :def, :defs then base_for_method_definition(parent)
|
87
|
+
when :kwbegin then parent.loc.begin
|
88
|
+
when :block then parent.send_node.source_range
|
89
|
+
else node.loc.keyword
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
89
93
|
def base_for_method_definition(node)
|
90
94
|
parent = node.parent
|
91
95
|
if parent && parent.send_type?
|
@@ -87,8 +87,14 @@ module RuboCop
|
|
87
87
|
|
88
88
|
def autocorrect(node)
|
89
89
|
lambda do |corrector|
|
90
|
-
|
91
|
-
|
90
|
+
previous_token = previous_token(node)
|
91
|
+
range = if previous_token && node.loc.line == previous_token.line
|
92
|
+
range_with_surrounding_space(range: node.loc.expression,
|
93
|
+
newlines: false)
|
94
|
+
else
|
95
|
+
range_by_whole_lines(node.loc.expression,
|
96
|
+
include_final_newline: true)
|
97
|
+
end
|
92
98
|
|
93
99
|
corrector.remove(range)
|
94
100
|
end
|
@@ -134,6 +140,20 @@ module RuboCop
|
|
134
140
|
def allow_margin_comment?
|
135
141
|
cop_config['AllowMarginComment']
|
136
142
|
end
|
143
|
+
|
144
|
+
def current_token(node)
|
145
|
+
processed_source.find_token do |token|
|
146
|
+
token.pos.column == node.loc.column &&
|
147
|
+
token.pos.last_column == node.loc.last_column &&
|
148
|
+
token.line == node.loc.line
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def previous_token(node)
|
153
|
+
current_token = current_token(node)
|
154
|
+
index = processed_source.tokens.index(current_token)
|
155
|
+
index.zero? ? nil : processed_source.tokens[index - 1]
|
156
|
+
end
|
137
157
|
end
|
138
158
|
end
|
139
159
|
end
|
@@ -73,9 +73,11 @@ module RuboCop
|
|
73
73
|
include ConfigurableEnforcedStyle
|
74
74
|
include SafeMode
|
75
75
|
|
76
|
-
|
77
|
-
|
78
|
-
|
76
|
+
RUBY23_TYPE_MSG = 'Use %<indentation_width>d spaces for indentation ' \
|
77
|
+
'in a heredoc by using `<<~` instead of ' \
|
78
|
+
'`%<current_indent_type>s`.'.freeze
|
79
|
+
RUBY23_WIDTH_MSG = 'Use %<indentation_width>d spaces for '\
|
80
|
+
'indentation in a heredoc.'.freeze
|
79
81
|
LIBRARY_MSG = 'Use %<indentation_width>d spaces for indentation in a ' \
|
80
82
|
'heredoc by using %<method>s.'.freeze
|
81
83
|
STRIP_METHODS = {
|
@@ -148,13 +150,28 @@ module RuboCop
|
|
148
150
|
end
|
149
151
|
|
150
152
|
def ruby23_message(indentation_width, current_indent_type)
|
153
|
+
if current_indent_type == '<<~'
|
154
|
+
ruby23_width_message(indentation_width)
|
155
|
+
else
|
156
|
+
ruby23_type_message(indentation_width, current_indent_type)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def ruby23_type_message(indentation_width, current_indent_type)
|
151
161
|
format(
|
152
|
-
|
162
|
+
RUBY23_TYPE_MSG,
|
153
163
|
indentation_width: indentation_width,
|
154
164
|
current_indent_type: current_indent_type
|
155
165
|
)
|
156
166
|
end
|
157
167
|
|
168
|
+
def ruby23_width_message(indentation_width)
|
169
|
+
format(
|
170
|
+
RUBY23_WIDTH_MSG,
|
171
|
+
indentation_width: indentation_width
|
172
|
+
)
|
173
|
+
end
|
174
|
+
|
158
175
|
def too_long_line?(node)
|
159
176
|
return false if config.for_cop('Metrics/LineLength')['AllowHeredoc']
|
160
177
|
body = heredoc_body(node)
|
@@ -6,15 +6,15 @@ module RuboCop
|
|
6
6
|
module UncommunicativeName
|
7
7
|
CASE_MSG = 'Only use lowercase characters for %<name_type>s.'.freeze
|
8
8
|
NUM_MSG = 'Do not end %<name_type>s with a number.'.freeze
|
9
|
-
LENGTH_MSG = '%<name_type>s must be
|
10
|
-
'characters.'.freeze
|
9
|
+
LENGTH_MSG = '%<name_type>s must be at least %<min>s ' \
|
10
|
+
'characters long.'.freeze
|
11
11
|
FORBIDDEN_MSG = 'Do not use %<name>s as a name for a ' \
|
12
12
|
'%<name_type>s.'.freeze
|
13
13
|
|
14
14
|
def check(node, args)
|
15
15
|
args.each do |arg|
|
16
16
|
name = arg.children.first.to_s
|
17
|
-
next if arg.restarg_type? && name.empty?
|
17
|
+
next if (arg.restarg_type? || arg.kwrestarg_type?) && name.empty?
|
18
18
|
next if allowed_names.include?(name)
|
19
19
|
range = arg_range(arg, name.size)
|
20
20
|
issue_offenses(node, range, name)
|
@@ -30,7 +30,12 @@ module RuboCop
|
|
30
30
|
PATTERN
|
31
31
|
|
32
32
|
def on_casgn(node)
|
33
|
-
|
33
|
+
if node.parent && node.parent.or_asgn_type?
|
34
|
+
lhs, value = *node.parent
|
35
|
+
_scope, const_name = *lhs
|
36
|
+
else
|
37
|
+
_scope, const_name, value = *node
|
38
|
+
end
|
34
39
|
|
35
40
|
# We cannot know the result of method calls like
|
36
41
|
# NewClass = something_that_returns_a_class
|
@@ -39,15 +44,19 @@ module RuboCop
|
|
39
44
|
# SomeClass = SomeOtherClass
|
40
45
|
# SomeClass = Class.new(...)
|
41
46
|
# SomeClass = Struct.new(...)
|
42
|
-
return if
|
43
|
-
allowed_method_call_on_rhs?(value) ||
|
44
|
-
class_or_struct_return_method?(value)
|
47
|
+
return if allowed_assignment?(value)
|
45
48
|
|
46
49
|
add_offense(node, location: :name) if const_name !~ SNAKE_CASE
|
47
50
|
end
|
48
51
|
|
49
52
|
private
|
50
53
|
|
54
|
+
def allowed_assignment?(value)
|
55
|
+
value && %i[block const casgn].include?(value.type) ||
|
56
|
+
allowed_method_call_on_rhs?(value) ||
|
57
|
+
class_or_struct_return_method?(value)
|
58
|
+
end
|
59
|
+
|
51
60
|
def allowed_method_call_on_rhs?(node)
|
52
61
|
node && node.send_type? &&
|
53
62
|
(node.receiver.nil? || !node.receiver.literal?)
|
@@ -34,7 +34,7 @@ module RuboCop
|
|
34
34
|
#
|
35
35
|
class MemoizedInstanceVariableName < Cop
|
36
36
|
MSG = 'Memoized variable `%<var>s` does not match ' \
|
37
|
-
'method name `%<method>s`. Use `@%<
|
37
|
+
'method name `%<method>s`. Use `@%<suggested_var>s` instead.'.freeze
|
38
38
|
|
39
39
|
def self.node_pattern
|
40
40
|
memo_assign = '(or_asgn $(ivasgn _) _)'
|
@@ -55,6 +55,7 @@ module RuboCop
|
|
55
55
|
msg = format(
|
56
56
|
MSG,
|
57
57
|
var: ivar_assign.children.first.to_s,
|
58
|
+
suggested_var: method_name.to_s.delete('!?'),
|
58
59
|
method: method_name
|
59
60
|
)
|
60
61
|
add_offense(node, location: ivar_assign.source_range, message: msg)
|
@@ -65,7 +66,7 @@ module RuboCop
|
|
65
66
|
|
66
67
|
def matches?(method_name, ivar_assign)
|
67
68
|
return true if ivar_assign.nil? || method_name == :initialize
|
68
|
-
method_name = method_name.to_s.
|
69
|
+
method_name = method_name.to_s.delete('!?')
|
69
70
|
variable = ivar_assign.children.first
|
70
71
|
variable_name = variable.to_s.sub('@', '')
|
71
72
|
variable_name == method_name
|
@@ -0,0 +1,181 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Rails
|
6
|
+
# Enforces use of symbolic or numeric value to define HTTP status.
|
7
|
+
#
|
8
|
+
# @example `EnforcedStyle: symbolic` (default)
|
9
|
+
# # bad
|
10
|
+
# render :foo, status: 200
|
11
|
+
# render json: { foo: 'bar' }, status: 200
|
12
|
+
# render plain: 'foo/bar', status: 304
|
13
|
+
# redirect_to root_url, status: 301
|
14
|
+
#
|
15
|
+
# # good
|
16
|
+
# render :foo, status: :ok
|
17
|
+
# render json: { foo: 'bar' }, status: :ok
|
18
|
+
# render plain: 'foo/bar', status: :not_modified
|
19
|
+
# redirect_to root_url, status: :moved_permanently
|
20
|
+
#
|
21
|
+
# @example `EnforcedStyle: numeric`
|
22
|
+
# # bad
|
23
|
+
# render :foo, status: :ok
|
24
|
+
# render json: { foo: 'bar' }, status: :not_found
|
25
|
+
# render plain: 'foo/bar', status: :not_modified
|
26
|
+
# redirect_to root_url, status: :moved_permanently
|
27
|
+
#
|
28
|
+
# # good
|
29
|
+
# render :foo, status: 200
|
30
|
+
# render json: { foo: 'bar' }, status: 404
|
31
|
+
# render plain: 'foo/bar', status: 304
|
32
|
+
# redirect_to root_url, status: 301
|
33
|
+
#
|
34
|
+
class HttpStatus < Cop
|
35
|
+
begin
|
36
|
+
require 'rack/utils'
|
37
|
+
RACK_LOADED = true
|
38
|
+
rescue LoadError
|
39
|
+
RACK_LOADED = false
|
40
|
+
end
|
41
|
+
|
42
|
+
include ConfigurableEnforcedStyle
|
43
|
+
|
44
|
+
def_node_matcher :http_status, <<-PATTERN
|
45
|
+
{
|
46
|
+
(send nil? {:render :redirect_to}
|
47
|
+
_
|
48
|
+
(hash
|
49
|
+
(pair
|
50
|
+
(sym :status)
|
51
|
+
${int sym})))
|
52
|
+
(send nil? {:render}
|
53
|
+
(hash
|
54
|
+
_
|
55
|
+
(pair
|
56
|
+
(sym :status)
|
57
|
+
${int sym})))
|
58
|
+
}
|
59
|
+
PATTERN
|
60
|
+
|
61
|
+
def on_send(node)
|
62
|
+
http_status(node) do |ast_node|
|
63
|
+
checker = checker_class.new(ast_node)
|
64
|
+
return unless checker.offensive?
|
65
|
+
add_offense(checker.node, message: checker.message)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def support_autocorrect?
|
70
|
+
RACK_LOADED
|
71
|
+
end
|
72
|
+
|
73
|
+
def autocorrect(node)
|
74
|
+
lambda do |corrector|
|
75
|
+
checker = checker_class.new(node)
|
76
|
+
corrector.replace(node.loc.expression, checker.preferred_style)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def checker_class
|
83
|
+
case style
|
84
|
+
when :symbolic
|
85
|
+
SymbolicStyleChecker
|
86
|
+
when :numeric
|
87
|
+
NumericStyleChecker
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# :nodoc:
|
92
|
+
class SymbolicStyleChecker
|
93
|
+
MSG = 'Prefer `%<prefer>s` over `%<current>s` ' \
|
94
|
+
'to define HTTP status code.'.freeze
|
95
|
+
DEFAULT_MSG = 'Prefer `symbolic` over `numeric` ' \
|
96
|
+
'to define HTTP status code.'.freeze
|
97
|
+
|
98
|
+
attr_reader :node
|
99
|
+
def initialize(node)
|
100
|
+
@node = node
|
101
|
+
end
|
102
|
+
|
103
|
+
def offensive?
|
104
|
+
!node.sym_type? && !custom_http_status_code?
|
105
|
+
end
|
106
|
+
|
107
|
+
def message
|
108
|
+
if RACK_LOADED
|
109
|
+
format(MSG, prefer: preferred_style, current: number.to_s)
|
110
|
+
else
|
111
|
+
DEFAULT_MSG
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def preferred_style
|
116
|
+
symbol.inspect
|
117
|
+
end
|
118
|
+
|
119
|
+
private
|
120
|
+
|
121
|
+
def symbol
|
122
|
+
::Rack::Utils::SYMBOL_TO_STATUS_CODE.key(number)
|
123
|
+
end
|
124
|
+
|
125
|
+
def number
|
126
|
+
node.children.first
|
127
|
+
end
|
128
|
+
|
129
|
+
def custom_http_status_code?
|
130
|
+
node.int_type? &&
|
131
|
+
!::Rack::Utils::SYMBOL_TO_STATUS_CODE.value?(number)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# :nodoc:
|
136
|
+
class NumericStyleChecker
|
137
|
+
MSG = 'Prefer `%<prefer>s` over `%<current>s` ' \
|
138
|
+
'to define HTTP status code.'.freeze
|
139
|
+
DEFAULT_MSG = 'Prefer `numeric` over `symbolic` ' \
|
140
|
+
'to define HTTP status code.'.freeze
|
141
|
+
WHITELIST_STATUS = %i[error success missing redirect].freeze
|
142
|
+
|
143
|
+
attr_reader :node
|
144
|
+
def initialize(node)
|
145
|
+
@node = node
|
146
|
+
end
|
147
|
+
|
148
|
+
def offensive?
|
149
|
+
!node.int_type? && !whitelisted_symbol?
|
150
|
+
end
|
151
|
+
|
152
|
+
def message
|
153
|
+
if RACK_LOADED
|
154
|
+
format(MSG, prefer: preferred_style, current: symbol.inspect)
|
155
|
+
else
|
156
|
+
DEFAULT_MSG
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def preferred_style
|
161
|
+
number.to_s
|
162
|
+
end
|
163
|
+
|
164
|
+
private
|
165
|
+
|
166
|
+
def number
|
167
|
+
::Rack::Utils::SYMBOL_TO_STATUS_CODE[symbol]
|
168
|
+
end
|
169
|
+
|
170
|
+
def symbol
|
171
|
+
node.value
|
172
|
+
end
|
173
|
+
|
174
|
+
def whitelisted_symbol?
|
175
|
+
node.sym_type? && WHITELIST_STATUS.include?(node.value)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
@@ -16,12 +16,12 @@ module RuboCop
|
|
16
16
|
# person.toggle :active
|
17
17
|
# product.touch
|
18
18
|
# Billing.update_all("category = 'authorized', author = 'David'")
|
19
|
-
# user.update_attribute(website
|
19
|
+
# user.update_attribute(:website, 'example.com')
|
20
20
|
# user.update_columns(last_request_at: Time.current)
|
21
21
|
# Post.update_counters 5, comment_count: -1, action_count: 1
|
22
22
|
#
|
23
23
|
# # good
|
24
|
-
# user.
|
24
|
+
# user.update(website: 'example.com')
|
25
25
|
# FileUtils.touch('file')
|
26
26
|
class SkipsModelValidations < Cop
|
27
27
|
MSG = 'Avoid using `%<method>s` because it skips validations.'.freeze
|
@@ -30,6 +30,7 @@ module RuboCop
|
|
30
30
|
MSG = 'Missing top-level %<type>s documentation comment.'.freeze
|
31
31
|
|
32
32
|
def_node_matcher :constant_definition?, '{class module casgn}'
|
33
|
+
def_node_search :outer_module, '(const (const nil? _) _)'
|
33
34
|
|
34
35
|
def on_class(node)
|
35
36
|
_, _, body = *node
|
@@ -50,6 +51,8 @@ module RuboCop
|
|
50
51
|
def check(node, body, type)
|
51
52
|
return if namespace?(body)
|
52
53
|
return if documentation_comment?(node) || nodoc_comment?(node)
|
54
|
+
return if compact_namespace?(node) &&
|
55
|
+
nodoc_comment?(outer_module(node).first)
|
53
56
|
|
54
57
|
add_offense(node,
|
55
58
|
location: :keyword,
|
@@ -66,6 +69,10 @@ module RuboCop
|
|
66
69
|
end
|
67
70
|
end
|
68
71
|
|
72
|
+
def compact_namespace?(node)
|
73
|
+
node.loc.name.source =~ /::/
|
74
|
+
end
|
75
|
+
|
69
76
|
# First checks if the :nodoc: comment is associated with the
|
70
77
|
# class/module. Unless the element is tagged with :nodoc:, the search
|
71
78
|
# proceeds to check its ancestors for :nodoc: all.
|
@@ -43,7 +43,8 @@ module RuboCop
|
|
43
43
|
def on_if(node)
|
44
44
|
return unless contains_guard_clause?(node)
|
45
45
|
|
46
|
-
return if
|
46
|
+
return if next_line_rescue_or_ensure?(node)
|
47
|
+
return if next_sibling_parent_empty_or_else?(node)
|
47
48
|
return if next_sibling_empty_or_guard_clause?(node)
|
48
49
|
|
49
50
|
return if next_line_empty?(node)
|
@@ -68,6 +69,20 @@ module RuboCop
|
|
68
69
|
processed_source[node.last_line].blank?
|
69
70
|
end
|
70
71
|
|
72
|
+
def next_line_rescue_or_ensure?(node)
|
73
|
+
parent = node.parent
|
74
|
+
parent.nil? || parent.rescue_type? || parent.ensure_type?
|
75
|
+
end
|
76
|
+
|
77
|
+
def next_sibling_parent_empty_or_else?(node)
|
78
|
+
next_sibling = node.parent.children[node.sibling_index + 1]
|
79
|
+
return true if next_sibling.nil?
|
80
|
+
|
81
|
+
parent = next_sibling.parent
|
82
|
+
|
83
|
+
parent && parent.if_type? && parent.else?
|
84
|
+
end
|
85
|
+
|
71
86
|
def next_sibling_empty_or_guard_clause?(node)
|
72
87
|
next_sibling = node.parent.children[node.sibling_index + 1]
|
73
88
|
return true if next_sibling.nil?
|
@@ -51,6 +51,7 @@ module RuboCop
|
|
51
51
|
}.freeze
|
52
52
|
|
53
53
|
def on_str(node)
|
54
|
+
return if placeholder_argument?(node)
|
54
55
|
return if node.each_ancestor(:xstr, :regexp).any?
|
55
56
|
|
56
57
|
tokens(node) do |detected_style, token_range|
|
@@ -156,6 +157,13 @@ module RuboCop
|
|
156
157
|
new_end
|
157
158
|
)
|
158
159
|
end
|
160
|
+
|
161
|
+
def placeholder_argument?(node)
|
162
|
+
return false unless node.parent
|
163
|
+
return true if node.parent.pair_type?
|
164
|
+
|
165
|
+
placeholder_argument?(node.parent)
|
166
|
+
end
|
159
167
|
end
|
160
168
|
end
|
161
169
|
end
|
@@ -22,7 +22,9 @@ module RuboCop
|
|
22
22
|
|
23
23
|
def investigate(processed_source)
|
24
24
|
processed_source.each_comment do |comment|
|
25
|
-
next if comment_line?(processed_source[comment.loc.line - 1])
|
25
|
+
next if comment_line?(processed_source[comment.loc.line - 1]) ||
|
26
|
+
comment.text.match(/\A# rubocop:(enable|disable)/)
|
27
|
+
|
26
28
|
add_offense(comment)
|
27
29
|
end
|
28
30
|
end
|
@@ -27,18 +27,21 @@ module RuboCop
|
|
27
27
|
# foo != bar
|
28
28
|
# foo == bar
|
29
29
|
# !!('foo' =~ /^\w+$/)
|
30
|
+
# !(foo.class < Numeric) # Checking class hierarchy is allowed
|
30
31
|
class InverseMethods < Cop
|
31
32
|
include IgnoredNode
|
32
33
|
|
33
34
|
MSG = 'Use `%<inverse>s` instead of inverting `%<method>s`.'.freeze
|
35
|
+
CLASS_COMPARISON_METHODS = %i[<= >= < >].freeze
|
34
36
|
EQUALITY_METHODS = %i[== != =~ !~ <= >= < >].freeze
|
35
37
|
NEGATED_EQUALITY_METHODS = %i[!= !~].freeze
|
38
|
+
CAMEL_CASE = /[A-Z]+[a-z]+/
|
36
39
|
|
37
40
|
def_node_matcher :inverse_candidate?, <<-PATTERN
|
38
41
|
{
|
39
|
-
(send $(send (...) $_
|
40
|
-
(send (block $(send (...) $_)
|
41
|
-
(send (begin $(send (...) $_
|
42
|
+
(send $(send $(...) $_ $...) :!)
|
43
|
+
(send (block $(send $(...) $_) $...) :!)
|
44
|
+
(send (begin $(send $(...) $_ $...)) :!)
|
42
45
|
}
|
43
46
|
PATTERN
|
44
47
|
|
@@ -52,8 +55,9 @@ module RuboCop
|
|
52
55
|
|
53
56
|
def on_send(node)
|
54
57
|
return if part_of_ignored_node?(node)
|
55
|
-
inverse_candidate?(node) do |_method_call, method|
|
58
|
+
inverse_candidate?(node) do |_method_call, lhs, method, rhs|
|
56
59
|
return unless inverse_methods.key?(method)
|
60
|
+
return if possible_class_hierarchy_check?(lhs, rhs, method)
|
57
61
|
return if negated?(node)
|
58
62
|
|
59
63
|
add_offense(node,
|
@@ -78,7 +82,7 @@ module RuboCop
|
|
78
82
|
end
|
79
83
|
|
80
84
|
def autocorrect(node)
|
81
|
-
method_call, method = inverse_candidate?(node)
|
85
|
+
method_call, _lhs, method, _rhs = inverse_candidate?(node)
|
82
86
|
|
83
87
|
if method_call && method
|
84
88
|
lambda do |corrector|
|
@@ -143,6 +147,19 @@ module RuboCop
|
|
143
147
|
method_call.loc.expression.end_pos,
|
144
148
|
node.loc.expression.end_pos)
|
145
149
|
end
|
150
|
+
|
151
|
+
# When comparing classes, `!(Integer < Numeric)` is not the same as
|
152
|
+
# `Integer > Numeric`.
|
153
|
+
def possible_class_hierarchy_check?(lhs, rhs, method)
|
154
|
+
CLASS_COMPARISON_METHODS.include?(method) &&
|
155
|
+
(camel_case_constant?(lhs) ||
|
156
|
+
(rhs.size == 1 &&
|
157
|
+
camel_case_constant?(rhs.first)))
|
158
|
+
end
|
159
|
+
|
160
|
+
def camel_case_constant?(node)
|
161
|
+
node.const_type? && node.source =~ CAMEL_CASE
|
162
|
+
end
|
146
163
|
end
|
147
164
|
end
|
148
165
|
end
|
@@ -9,6 +9,7 @@ module RuboCop
|
|
9
9
|
#
|
10
10
|
# @example
|
11
11
|
#
|
12
|
+
# # bad
|
12
13
|
# def redundant
|
13
14
|
# begin
|
14
15
|
# ala
|
@@ -18,12 +19,31 @@ module RuboCop
|
|
18
19
|
# end
|
19
20
|
# end
|
20
21
|
#
|
22
|
+
# # good
|
21
23
|
# def preferred
|
22
24
|
# ala
|
23
25
|
# bala
|
24
26
|
# rescue StandardError => e
|
25
27
|
# something
|
26
28
|
# end
|
29
|
+
#
|
30
|
+
# # bad
|
31
|
+
# # When using Ruby 2.5 or later.
|
32
|
+
# do_something do
|
33
|
+
# begin
|
34
|
+
# something
|
35
|
+
# rescue => ex
|
36
|
+
# anything
|
37
|
+
# end
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
# # good
|
41
|
+
# # In Ruby 2.5 or later, you can omit `begin` in `do-end` block.
|
42
|
+
# do_something do
|
43
|
+
# something
|
44
|
+
# rescue => ex
|
45
|
+
# anything
|
46
|
+
# end
|
27
47
|
class RedundantBegin < Cop
|
28
48
|
MSG = 'Redundant `begin` block detected.'.freeze
|
29
49
|
|
@@ -228,9 +228,10 @@ module RuboCop
|
|
228
228
|
start_method.each_ancestor do |ancestor|
|
229
229
|
break unless %i[send block].include?(ancestor.type)
|
230
230
|
next unless ancestor.send_type?
|
231
|
-
break if ancestor == method_chain
|
232
231
|
|
233
232
|
corrector.insert_before(ancestor.loc.dot, '&')
|
233
|
+
|
234
|
+
break if ancestor == method_chain
|
234
235
|
end
|
235
236
|
end
|
236
237
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# This cop checks for accessing the first element of `String#unpack`
|
7
|
+
# which can be replaced with the shorter method `unpack1`.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
#
|
11
|
+
# # bad
|
12
|
+
# 'foo'.unpack('h*').first
|
13
|
+
# 'foo'.unpack('h*')[0]
|
14
|
+
# 'foo'.unpack('h*').slice(0)
|
15
|
+
# 'foo'.unpack('h*').at(0)
|
16
|
+
# 'foo'.unpack('h*').take(1)
|
17
|
+
#
|
18
|
+
# # good
|
19
|
+
# 'foo'.unpack1('h*')
|
20
|
+
#
|
21
|
+
class UnpackFirst < Cop
|
22
|
+
extend TargetRubyVersion
|
23
|
+
|
24
|
+
minimum_target_ruby_version 2.4
|
25
|
+
|
26
|
+
MSG = 'Use `%<receiver>s.unpack1(%<format>s)` instead of '\
|
27
|
+
'`%<receiver>s.unpack(%<format>s)%<method>s`.'.freeze
|
28
|
+
|
29
|
+
def_node_matcher :unpack_and_first_element?, <<-PATTERN
|
30
|
+
{
|
31
|
+
(send $(send (...) :unpack $(...)) :first)
|
32
|
+
(send $(send (...) :unpack $(...)) {:[] :slice :at} (int 0))
|
33
|
+
(send $(send (...) :unpack $(...)) :take (int 1))
|
34
|
+
}
|
35
|
+
PATTERN
|
36
|
+
|
37
|
+
def on_send(node)
|
38
|
+
unpack_and_first_element?(node) do |unpack_call, unpack_arg|
|
39
|
+
range = first_element_range(node, unpack_call)
|
40
|
+
message = format(MSG,
|
41
|
+
receiver: unpack_call.receiver.source,
|
42
|
+
format: unpack_arg.source,
|
43
|
+
method: range.source)
|
44
|
+
add_offense(node, message: message)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def autocorrect(node)
|
49
|
+
unpack_and_first_element?(node) do |unpack_call, _unpack_arg|
|
50
|
+
lambda do |corrector|
|
51
|
+
corrector.remove(first_element_range(node, unpack_call))
|
52
|
+
corrector.replace(unpack_call.loc.selector, 'unpack1')
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def first_element_range(node, unpack_call)
|
60
|
+
Parser::Source::Range.new(node.loc.expression.source_buffer,
|
61
|
+
unpack_call.loc.expression.end_pos,
|
62
|
+
node.loc.expression.end_pos)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/lib/rubocop/cop/util.rb
CHANGED
@@ -121,7 +121,7 @@ module RuboCop
|
|
121
121
|
.sub('Style', 'Styles')
|
122
122
|
end
|
123
123
|
|
124
|
-
def tokens(node)
|
124
|
+
def tokens(node)
|
125
125
|
@tokens ||= {}
|
126
126
|
return @tokens[node.object_id] if @tokens[node.object_id]
|
127
127
|
|
@@ -129,17 +129,9 @@ module RuboCop
|
|
129
129
|
begin_pos = source_range.begin_pos
|
130
130
|
end_pos = source_range.end_pos
|
131
131
|
|
132
|
-
|
133
|
-
token.end_pos <= end_pos
|
132
|
+
@tokens[node.object_id] = processed_source.tokens.select do |token|
|
133
|
+
token.end_pos <= end_pos && token.begin_pos >= begin_pos
|
134
134
|
end
|
135
|
-
|
136
|
-
node_tokens = []
|
137
|
-
tokens_to_node_end.reverse_each do |token|
|
138
|
-
break unless token.begin_pos >= begin_pos
|
139
|
-
node_tokens.unshift(token)
|
140
|
-
end
|
141
|
-
|
142
|
-
@tokens[node.object_id] = node_tokens
|
143
135
|
end
|
144
136
|
|
145
137
|
private
|
@@ -17,10 +17,27 @@ module RuboCop
|
|
17
17
|
def started(target_files)
|
18
18
|
super
|
19
19
|
@offense_counts = Hash.new(0)
|
20
|
+
|
21
|
+
return unless output.tty?
|
22
|
+
|
23
|
+
file_phrase = target_files.count == 1 ? 'file' : 'files'
|
24
|
+
|
25
|
+
# 185/407 files |====== 45 ======> | ETA: 00:00:04
|
26
|
+
# %c / %C | %w > %i | %e
|
27
|
+
bar_format = " %c/%C #{file_phrase} |%w>%i| %e "
|
28
|
+
|
29
|
+
@progressbar = ProgressBar.create(
|
30
|
+
output: output,
|
31
|
+
total: target_files.count,
|
32
|
+
format: bar_format,
|
33
|
+
autostart: false
|
34
|
+
)
|
35
|
+
@progressbar.start
|
20
36
|
end
|
21
37
|
|
22
38
|
def file_finished(_file, offenses)
|
23
39
|
offenses.each { |o| @offense_counts[o.cop_name] += 1 }
|
40
|
+
@progressbar.increment if instance_variable_defined?(:@progressbar)
|
24
41
|
end
|
25
42
|
|
26
43
|
def finished(_inspected_files)
|
@@ -121,7 +121,7 @@ module RuboCop
|
|
121
121
|
end
|
122
122
|
|
123
123
|
# Most recently modified file first.
|
124
|
-
target_files.sort_by! { |path| Integer(
|
124
|
+
target_files.sort_by! { |path| -Integer(File.mtime(path)) } if fail_fast?
|
125
125
|
|
126
126
|
target_files
|
127
127
|
end
|
data/lib/rubocop/version.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
module RuboCop
|
4
4
|
# This module holds the RuboCop version information.
|
5
5
|
module Version
|
6
|
-
STRING = '0.
|
6
|
+
STRING = '0.54.0'.freeze
|
7
7
|
|
8
8
|
MSG = '%<version>s (using Parser %<parser_version>s, running on ' \
|
9
9
|
'%<ruby_engine>s %<ruby_version>s %<ruby_platform>s)'.freeze
|
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.54.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bozhidar Batsov
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2018-03-
|
13
|
+
date: 2018-03-21 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: parallel
|
@@ -122,6 +122,20 @@ dependencies:
|
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '1.3'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rack
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
125
139
|
description: |2
|
126
140
|
Automatic Ruby code style checking tool.
|
127
141
|
Aims to enforce the community-driven Ruby Style Guide.
|
@@ -500,6 +514,7 @@ files:
|
|
500
514
|
- lib/rubocop/cop/rails/has_and_belongs_to_many.rb
|
501
515
|
- lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb
|
502
516
|
- lib/rubocop/cop/rails/http_positional_arguments.rb
|
517
|
+
- lib/rubocop/cop/rails/http_status.rb
|
503
518
|
- lib/rubocop/cop/rails/inverse_of.rb
|
504
519
|
- lib/rubocop/cop/rails/lexically_scoped_action_filter.rb
|
505
520
|
- lib/rubocop/cop/rails/not_null_column.rb
|
@@ -678,6 +693,7 @@ files:
|
|
678
693
|
- lib/rubocop/cop/style/unneeded_capital_w.rb
|
679
694
|
- lib/rubocop/cop/style/unneeded_interpolation.rb
|
680
695
|
- lib/rubocop/cop/style/unneeded_percent_q.rb
|
696
|
+
- lib/rubocop/cop/style/unpack_first.rb
|
681
697
|
- lib/rubocop/cop/style/variable_interpolation.rb
|
682
698
|
- lib/rubocop/cop/style/when_then.rb
|
683
699
|
- lib/rubocop/cop/style/while_until_do.rb
|