rubocop 0.49.0 → 0.49.1
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/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
|