rubocop 0.49.0 → 0.49.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/rubocop.rb +1 -0
- data/lib/rubocop/config_loader.rb +6 -0
- data/lib/rubocop/cop/generator.rb +163 -0
- data/lib/rubocop/cop/internal_affairs.rb +4 -0
- data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +33 -0
- data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +52 -0
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +17 -0
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +1 -1
- data/lib/rubocop/cop/performance/regexp_match.rb +1 -1
- data/lib/rubocop/cop/rails/file_path.rb +1 -1
- data/lib/rubocop/cop/rails/http_positional_arguments.rb +2 -2
- data/lib/rubocop/cop/style/conditional_assignment.rb +3 -0
- data/lib/rubocop/cop/style/empty_method.rb +12 -6
- data/lib/rubocop/cop/style/multiple_comparison.rb +1 -1
- data/lib/rubocop/cop/style/next.rb +1 -1
- data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/word_array.rb +2 -1
- data/lib/rubocop/cop/style/yoda_condition.rb +2 -2
- data/lib/rubocop/runner.rb +1 -1
- data/lib/rubocop/version.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 19d303a2e571971385e48eab0517fd03f0273c9c
|
4
|
+
data.tar.gz: 30129d935542762c11820ad7386ff213d4944cd2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8725c2dc3d92496b06acd39cc8efc4fd25e45e5ea7b3e3e3f565cf923de82c46f5efec1e279b75151f3a81341b94b9c70c0c3c66af60c3ab2bd2b844963993b9
|
7
|
+
data.tar.gz: d51e988da1e14e4b9477a2f5bec04cbd9509bcc09bb8febfc3e8d2df9957e8c98bb5c94e90fa3bacf9b0d848d496427bf6c57206c48a9c7acc3490bfade5d7c6
|
data/README.md
CHANGED
@@ -51,7 +51,7 @@ haven't reached version 1.0 yet). To prevent an unwanted RuboCop update you
|
|
51
51
|
might want to use a conservative version locking in your `Gemfile`:
|
52
52
|
|
53
53
|
```rb
|
54
|
-
gem 'rubocop', '~> 0.49.
|
54
|
+
gem 'rubocop', '~> 0.49.1', require: false
|
55
55
|
```
|
56
56
|
|
57
57
|
## Quickstart
|
data/lib/rubocop.rb
CHANGED
@@ -165,6 +165,12 @@ module RuboCop
|
|
165
165
|
def handle_disabled_by_default(config, new_default_configuration)
|
166
166
|
department_config = config.to_hash.reject { |cop| cop.include?('/') }
|
167
167
|
department_config.each do |dept, dept_params|
|
168
|
+
# Rails is always disabled by default and the department's Enabled
|
169
|
+
# flag works like the --rails command line option, which is that when
|
170
|
+
# AllCops:DisabledByDefault is true, each Rails cop must still be
|
171
|
+
# explicitly mentioned in user configuration in order to be enabled.
|
172
|
+
next if dept == 'Rails'
|
173
|
+
|
168
174
|
next unless dept_params['Enabled']
|
169
175
|
|
170
176
|
new_default_configuration.each do |cop, params|
|
@@ -0,0 +1,163 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# Source and spec generator for new cops
|
6
|
+
#
|
7
|
+
# This generator will take a cop name and generate a source file
|
8
|
+
# and spec file when given a valid qualified cop name.
|
9
|
+
class Generator
|
10
|
+
SOURCE_TEMPLATE = <<-RUBY.strip_indent
|
11
|
+
# frozen_string_literal: true
|
12
|
+
|
13
|
+
# TODO: when finished, run `rake generate_cops_documentation` to update the docs
|
14
|
+
module RuboCop
|
15
|
+
module Cop
|
16
|
+
module %<department>s
|
17
|
+
# TODO: Write cop description and example of bad / good code.
|
18
|
+
#
|
19
|
+
# @example
|
20
|
+
# # bad
|
21
|
+
# bad_method()
|
22
|
+
#
|
23
|
+
# # bad
|
24
|
+
# bad_method(args)
|
25
|
+
#
|
26
|
+
# # good
|
27
|
+
# good_method()
|
28
|
+
#
|
29
|
+
# # good
|
30
|
+
# good_method(args)
|
31
|
+
class %<cop_name>s < Cop
|
32
|
+
# TODO: Implement the cop into here.
|
33
|
+
#
|
34
|
+
# In many cases, you can use a node matcher for matching node pattern.
|
35
|
+
# See. https://github.com/bbatsov/rubocop/blob/master/lib/rubocop/node_pattern.rb
|
36
|
+
#
|
37
|
+
# For example
|
38
|
+
MSG = 'Message of %<cop_name>s'.freeze
|
39
|
+
|
40
|
+
def_node_matcher :bad_method?, <<-PATTERN
|
41
|
+
(send nil :bad_method ...)
|
42
|
+
PATTERN
|
43
|
+
|
44
|
+
def on_send(node)
|
45
|
+
return unless bad_method?(node)
|
46
|
+
add_offense(node, :expression)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
RUBY
|
53
|
+
|
54
|
+
SPEC_TEMPLATE = <<-RUBY.strip_indent
|
55
|
+
# frozen_string_literal: true
|
56
|
+
|
57
|
+
describe RuboCop::Cop::%<department>s::%<cop_name>s do
|
58
|
+
let(:config) { RuboCop::Config.new }
|
59
|
+
subject(:cop) { described_class.new(config) }
|
60
|
+
|
61
|
+
# TODO: Write test code
|
62
|
+
#
|
63
|
+
# For example
|
64
|
+
it 'registers an offense for offending code' do
|
65
|
+
inspect_source(cop, 'bad_method')
|
66
|
+
expect(cop.offenses.size).to eq(1)
|
67
|
+
expect(cop.messages)
|
68
|
+
.to eq(['Message of %<cop_name>s'])
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'accepts' do
|
72
|
+
inspect_source(cop, 'good_method')
|
73
|
+
expect(cop.offenses).to be_empty
|
74
|
+
end
|
75
|
+
end
|
76
|
+
RUBY
|
77
|
+
|
78
|
+
def initialize(name)
|
79
|
+
@badge = Badge.parse(name)
|
80
|
+
|
81
|
+
return if badge.qualified?
|
82
|
+
|
83
|
+
raise ArgumentError, 'Specify a cop name with Department/Name style'
|
84
|
+
end
|
85
|
+
|
86
|
+
def write_source
|
87
|
+
write_unless_file_exists(source_path, generated_source)
|
88
|
+
end
|
89
|
+
|
90
|
+
def write_spec
|
91
|
+
write_unless_file_exists(spec_path, generated_spec)
|
92
|
+
end
|
93
|
+
|
94
|
+
def todo
|
95
|
+
<<-TODO.strip_indent
|
96
|
+
created
|
97
|
+
- #{source_path}
|
98
|
+
- #{spec_path}
|
99
|
+
|
100
|
+
Do 4 steps
|
101
|
+
- Add an entry to `New feature` section in CHANGELOG.md
|
102
|
+
- e.g. Add new `#{badge.cop_name}` cop. ([@your_id][])
|
103
|
+
- Add `require '#{require_path}'` into lib/rubocop.rb
|
104
|
+
- Add an entry into config/enabled.yml or config/disabled.yml
|
105
|
+
- Implement a new cop to the generated file!
|
106
|
+
TODO
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
attr_reader :badge
|
112
|
+
|
113
|
+
def write_unless_file_exists(path, contents)
|
114
|
+
raise "#{path} already exists!" if File.exist?(path)
|
115
|
+
|
116
|
+
File.write(path, contents)
|
117
|
+
end
|
118
|
+
|
119
|
+
def generated_source
|
120
|
+
generate(SOURCE_TEMPLATE)
|
121
|
+
end
|
122
|
+
|
123
|
+
def generated_spec
|
124
|
+
generate(SPEC_TEMPLATE)
|
125
|
+
end
|
126
|
+
|
127
|
+
def generate(template)
|
128
|
+
format(template, department: badge.department, cop_name: badge.cop_name)
|
129
|
+
end
|
130
|
+
|
131
|
+
def require_path
|
132
|
+
source_path.sub('lib/', '').sub('.rb', '')
|
133
|
+
end
|
134
|
+
|
135
|
+
def spec_path
|
136
|
+
File.join(
|
137
|
+
'spec',
|
138
|
+
'rubocop',
|
139
|
+
'cop',
|
140
|
+
snake_case(badge.department.to_s),
|
141
|
+
"#{snake_case(badge.cop_name.to_s)}_spec.rb"
|
142
|
+
)
|
143
|
+
end
|
144
|
+
|
145
|
+
def source_path
|
146
|
+
File.join(
|
147
|
+
'lib',
|
148
|
+
'rubocop',
|
149
|
+
'cop',
|
150
|
+
snake_case(badge.department.to_s),
|
151
|
+
"#{snake_case(badge.cop_name.to_s)}.rb"
|
152
|
+
)
|
153
|
+
end
|
154
|
+
|
155
|
+
def snake_case(camel_case_string)
|
156
|
+
camel_case_string
|
157
|
+
.gsub(/([^A-Z])([A-Z]+)/, '\1_\2')
|
158
|
+
.gsub(/([A-Z])([A-Z][^A-Z\d]+)/, '\1_\2')
|
159
|
+
.downcase
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module InternalAffairs
|
6
|
+
# Checks that node types are checked using the predicate helpers.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
#
|
10
|
+
# # bad
|
11
|
+
# node.type == :send
|
12
|
+
#
|
13
|
+
# # good
|
14
|
+
# node.send_type?
|
15
|
+
#
|
16
|
+
class NodeTypePredicate < Cop
|
17
|
+
MSG = 'Use `#%s_type?` to check node type.'.freeze
|
18
|
+
|
19
|
+
def_node_search :node_type_check, <<-PATTERN
|
20
|
+
(send (send _ :type) :== (sym $_))
|
21
|
+
PATTERN
|
22
|
+
|
23
|
+
def on_send(node)
|
24
|
+
node_type_check(node) do |node_type|
|
25
|
+
return unless Parser::Meta::NODE_TYPES.include?(node_type)
|
26
|
+
|
27
|
+
add_offense(node, :expression, format(MSG, node_type))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module InternalAffairs
|
6
|
+
# Checks that cops are not tested using `described_class::MSG`.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
#
|
10
|
+
# # bad
|
11
|
+
# expect(cop.messages).to eq([described_class::MSG])
|
12
|
+
#
|
13
|
+
# # good
|
14
|
+
# expect(cop.messages).to eq(['Do not write bad code like that.'])
|
15
|
+
#
|
16
|
+
class UselessMessageAssertion < Cop
|
17
|
+
MSG = 'Do not specify cop behavior using `described_class::MSG`.'.freeze
|
18
|
+
|
19
|
+
def_node_search :described_class_msg, <<-PATTERN
|
20
|
+
(const (send nil :described_class) :MSG)
|
21
|
+
PATTERN
|
22
|
+
|
23
|
+
def_node_matcher :rspec_expectation_on_msg?, <<-PATTERN
|
24
|
+
(send (send nil :expect #contains_described_class_msg?) :to ...)
|
25
|
+
PATTERN
|
26
|
+
|
27
|
+
def investigate(_processed_source)
|
28
|
+
assertions_using_described_class_msg.each do |node|
|
29
|
+
add_offense(node, :expression)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def contains_described_class_msg?(node)
|
36
|
+
described_class_msg(node).any?
|
37
|
+
end
|
38
|
+
|
39
|
+
def assertions_using_described_class_msg
|
40
|
+
described_class_msg(processed_source.ast).reject do |node|
|
41
|
+
node.ancestors.any?(&method(:rspec_expectation_on_msg?))
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Only process spec files
|
46
|
+
def relevant_file?(file)
|
47
|
+
file.end_with?('_spec.rb')
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -7,11 +7,27 @@ module RuboCop
|
|
7
7
|
#
|
8
8
|
# @example
|
9
9
|
#
|
10
|
+
# # EnforcedStyleInsidePipes: no_space (default)
|
11
|
+
#
|
10
12
|
# # bad
|
11
13
|
# {}.each { | x, y |puts x }
|
14
|
+
# ->( x, y ) { puts x }
|
12
15
|
#
|
13
16
|
# # good
|
14
17
|
# {}.each { |x, y| puts x }
|
18
|
+
# ->(x, y) { puts x }
|
19
|
+
#
|
20
|
+
# @example
|
21
|
+
#
|
22
|
+
# # EnforcedStyleInsidePipes: space
|
23
|
+
#
|
24
|
+
# # bad
|
25
|
+
# {}.each { |x, y| puts x }
|
26
|
+
# ->(x, y) { puts x }
|
27
|
+
#
|
28
|
+
# # good
|
29
|
+
# {}.each { | x, y | puts x }
|
30
|
+
# ->( x, y ) { puts x }
|
15
31
|
class SpaceAroundBlockParameters < Cop
|
16
32
|
include ConfigurableEnforcedStyle
|
17
33
|
|
@@ -22,6 +38,7 @@ module RuboCop
|
|
22
38
|
|
23
39
|
opening_pipe = args.loc.begin
|
24
40
|
closing_pipe = args.loc.end
|
41
|
+
return if opening_pipe.nil? || closing_pipe.nil?
|
25
42
|
|
26
43
|
check_inside_pipes(args.children, opening_pipe, closing_pipe)
|
27
44
|
|
@@ -56,11 +56,11 @@ module RuboCop
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def special_keyword_arg?(node)
|
59
|
-
KEYWORD_ARGS.include?(node.children.first) if node.
|
59
|
+
KEYWORD_ARGS.include?(node.children.first) if node.sym_type?
|
60
60
|
end
|
61
61
|
|
62
62
|
def format_arg?(node)
|
63
|
-
node.children.first == :format if node.
|
63
|
+
node.children.first == :format if node.sym_type?
|
64
64
|
end
|
65
65
|
|
66
66
|
def convert_hash_data(data, type)
|
@@ -301,6 +301,9 @@ module RuboCop
|
|
301
301
|
def assignment_node(node)
|
302
302
|
*_variable, assignment = *node
|
303
303
|
|
304
|
+
# ignore pseudo-assignments without rhs in for nodes
|
305
|
+
return if node.parent && node.parent.for_type?
|
306
|
+
|
304
307
|
if assignment.begin_type? && assignment.children.one?
|
305
308
|
assignment, = *assignment
|
306
309
|
end
|
@@ -6,37 +6,42 @@ module RuboCop
|
|
6
6
|
# This cop checks for the formatting of empty method definitions.
|
7
7
|
# By default it enforces empty method definitions to go on a single
|
8
8
|
# line (compact style), but it can be configured to enforce the `end`
|
9
|
-
# to go on its own line (expanded style.
|
9
|
+
# to go on its own line (expanded style).
|
10
10
|
#
|
11
11
|
# Note: A method definition is not considered empty if it contains
|
12
12
|
# comments.
|
13
13
|
#
|
14
14
|
# @example
|
15
15
|
#
|
16
|
-
# EnforcedStyle: compact (default)
|
16
|
+
# # EnforcedStyle: compact (default)
|
17
17
|
#
|
18
18
|
# @bad
|
19
19
|
# def foo(bar)
|
20
20
|
# end
|
21
|
+
#
|
21
22
|
# def self.foo(bar)
|
22
23
|
# end
|
23
24
|
#
|
24
25
|
# @good
|
25
26
|
# def foo(bar); end
|
27
|
+
#
|
26
28
|
# def foo(bar)
|
27
29
|
# # baz
|
28
30
|
# end
|
31
|
+
#
|
29
32
|
# def self.foo(bar); end
|
30
33
|
#
|
31
|
-
# EnforcedStyle: expanded
|
34
|
+
# # EnforcedStyle: expanded
|
32
35
|
#
|
33
36
|
# @bad
|
34
37
|
# def foo(bar); end
|
38
|
+
#
|
35
39
|
# def self.foo(bar); end
|
36
40
|
#
|
37
41
|
# @good
|
38
42
|
# def foo(bar)
|
39
43
|
# end
|
44
|
+
#
|
40
45
|
# def self.foo(bar)
|
41
46
|
# end
|
42
47
|
class EmptyMethod < Cop
|
@@ -70,9 +75,10 @@ module RuboCop
|
|
70
75
|
def corrected(node)
|
71
76
|
method_name, args, _body, scope = method_def_node_parts(node)
|
72
77
|
|
73
|
-
arguments = args.
|
74
|
-
|
75
|
-
|
78
|
+
arguments = !args.children.empty? ? args.source : ''
|
79
|
+
indent = ' ' * node.loc.column
|
80
|
+
joint = compact_style? ? '; ' : "\n#{indent}"
|
81
|
+
scope = scope ? 'self.' : ''
|
76
82
|
|
77
83
|
["def #{scope}#{method_name}#{arguments}", 'end'].join(joint)
|
78
84
|
end
|
@@ -15,7 +15,7 @@ module RuboCop
|
|
15
15
|
# a = 'a'
|
16
16
|
# foo if ['a', 'b', 'c'].include?(a)
|
17
17
|
class MultipleComparison < Cop
|
18
|
-
MSG = 'Avoid comparing a variable with multiple items' \
|
18
|
+
MSG = 'Avoid comparing a variable with multiple items ' \
|
19
19
|
'in a conditional, use `Array#include?` instead.'.freeze
|
20
20
|
|
21
21
|
def on_if(node)
|
@@ -153,7 +153,7 @@ module RuboCop
|
|
153
153
|
def end_range(node)
|
154
154
|
source_buffer = node.source_range.source_buffer
|
155
155
|
end_pos = node.loc.end.end_pos
|
156
|
-
begin_pos = node.loc.end.begin_pos - node.
|
156
|
+
begin_pos = node.loc.end.begin_pos - node.loc.end.column
|
157
157
|
begin_pos -= 1 if end_followed_by_whitespace_only?(source_buffer,
|
158
158
|
end_pos)
|
159
159
|
|
@@ -99,7 +99,7 @@ module RuboCop
|
|
99
99
|
# If the condition is parenthesized we recurse and check for any
|
100
100
|
# complex expressions within it.
|
101
101
|
def complex_condition?(condition)
|
102
|
-
if condition.
|
102
|
+
if condition.begin_type?
|
103
103
|
condition.to_a.any? { |x| complex_condition?(x) }
|
104
104
|
else
|
105
105
|
non_complex_type?(condition) ? false : true
|
@@ -93,7 +93,8 @@ module RuboCop
|
|
93
93
|
def complex_content?(strings)
|
94
94
|
strings.any? do |s|
|
95
95
|
string = s.str_content
|
96
|
-
!string.valid_encoding? ||
|
96
|
+
!string.dup.force_encoding(::Encoding::UTF_8).valid_encoding? ||
|
97
|
+
string !~ word_regex || string =~ / /
|
97
98
|
end
|
98
99
|
end
|
99
100
|
|
@@ -22,7 +22,7 @@ module RuboCop
|
|
22
22
|
# for <= 42
|
23
23
|
class YodaCondition < Cop
|
24
24
|
MSG = 'Reverse the order of the operands `%s`.'.freeze
|
25
|
-
|
25
|
+
|
26
26
|
REVERSE_COMPARISON = {
|
27
27
|
'<' => '>',
|
28
28
|
'<=' => '>=',
|
@@ -41,7 +41,7 @@ module RuboCop
|
|
41
41
|
def yoda_condition?(node)
|
42
42
|
return false unless comparison_operator?(node)
|
43
43
|
|
44
|
-
|
44
|
+
node.receiver.literal? && !node.arguments.first.literal?
|
45
45
|
end
|
46
46
|
|
47
47
|
def comparison_operator?(node)
|
data/lib/rubocop/runner.rb
CHANGED
@@ -49,7 +49,7 @@ module RuboCop
|
|
49
49
|
# Warms up the RuboCop cache by forking a suitable number of rubocop
|
50
50
|
# instances that each inspects its alotted group of files.
|
51
51
|
def warm_cache(target_files)
|
52
|
-
puts 'Running parallel inspection'
|
52
|
+
puts 'Running parallel inspection' if @options[:debug]
|
53
53
|
Parallel.each(target_files, &method(:file_offenses))
|
54
54
|
end
|
55
55
|
|
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.49.
|
4
|
+
version: 0.49.1
|
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: 2017-05-
|
13
|
+
date: 2017-05-29 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rainbow
|
@@ -191,7 +191,11 @@ files:
|
|
191
191
|
- lib/rubocop/cop/cop.rb
|
192
192
|
- lib/rubocop/cop/corrector.rb
|
193
193
|
- lib/rubocop/cop/force.rb
|
194
|
+
- lib/rubocop/cop/generator.rb
|
194
195
|
- lib/rubocop/cop/ignored_node.rb
|
196
|
+
- lib/rubocop/cop/internal_affairs.rb
|
197
|
+
- lib/rubocop/cop/internal_affairs/node_type_predicate.rb
|
198
|
+
- lib/rubocop/cop/internal_affairs/useless_message_assertion.rb
|
195
199
|
- lib/rubocop/cop/layout/access_modifier_indentation.rb
|
196
200
|
- lib/rubocop/cop/layout/align_array.rb
|
197
201
|
- lib/rubocop/cop/layout/align_hash.rb
|