rubocop 0.53.0 → 0.54.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/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
|