rubocop-petal 1.8.0 → 1.10.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/config/default.yml +37 -0
- data/lib/rubocop/cop/grape/unnecessary_namespace.rb +10 -1
- data/lib/rubocop/cop/migration/alter_after_create_table.rb +145 -0
- data/lib/rubocop/cop/rspec/aggregate_failures_tag.rb +123 -0
- data/lib/rubocop/cop/sidekiq/helpers.rb +1 -1
- data/lib/rubocop/cop/sidekiq/job_location.rb +61 -0
- data/lib/rubocop/cop/sidekiq/job_naming.rb +60 -0
- data/lib/rubocop/cop/sidekiq/prefer_job.rb +40 -0
- data/lib/rubocop/petal/version.rb +1 -1
- metadata +8 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 10f81655924fecdd2195281a71d19602efadfc7a9a60e7a9f005136c969aa45f
|
|
4
|
+
data.tar.gz: d5e0bab2b887cec6b46ed1ac96993cd18fe0c485f0723425288bb9c80c57f396
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0f54b691eb3fa5512d745e425494ce785dec5f74deccc101c85e7214eb2b4d227619f987347e2ab29a7dc5d0d509b52bfdaa6e44cdf297d440b76a21a91dd4dd
|
|
7
|
+
data.tar.gz: 210f323604d3ceae5db556afd7aa7f689b4c830d2886d7994030586c0726f5e6f7b7e05314dc49f0d39ec887142b857dd0ce9cbe22712dc3fc8a855ae35ac084
|
data/config/default.yml
CHANGED
|
@@ -15,6 +15,12 @@ Grape/PreferNamespace:
|
|
|
15
15
|
Include:
|
|
16
16
|
- app/api/**/*
|
|
17
17
|
|
|
18
|
+
Migration/AlterAfterCreateTable:
|
|
19
|
+
Description: 'Prefer defining new table changes inside the create_table block.'
|
|
20
|
+
Enabled: true
|
|
21
|
+
Include:
|
|
22
|
+
- db/migrate/**
|
|
23
|
+
|
|
18
24
|
Migration/AlwaysBulkChangeTable:
|
|
19
25
|
Description: 'Suggest to always use `bulk: true` when using `change_table`.'
|
|
20
26
|
Enabled: true
|
|
@@ -59,6 +65,12 @@ RSpec/AggregateExamples:
|
|
|
59
65
|
- validate_inclusion_of
|
|
60
66
|
- validates_exclusion_of
|
|
61
67
|
|
|
68
|
+
RSpec/AggregateFailuresTag:
|
|
69
|
+
Description: 'Checks that the `:aggregate_failures` tag is only used on examples, not on example groups.'
|
|
70
|
+
Enabled: true
|
|
71
|
+
Include:
|
|
72
|
+
- spec/**/*
|
|
73
|
+
|
|
62
74
|
RSpec/ChewyStrategy:
|
|
63
75
|
Description: 'Prevent using Chewy strategy in tests.'
|
|
64
76
|
Enabled: true
|
|
@@ -156,12 +168,14 @@ Sidekiq/KeywordArguments:
|
|
|
156
168
|
Enabled: true
|
|
157
169
|
Include:
|
|
158
170
|
- app/workers/**/*
|
|
171
|
+
- app/jobs/**/*
|
|
159
172
|
|
|
160
173
|
Sidekiq/NoNilReturn:
|
|
161
174
|
Description: 'Prevent early nil return in workers'
|
|
162
175
|
Enabled: false
|
|
163
176
|
Include:
|
|
164
177
|
- app/workers/**/*
|
|
178
|
+
- app/jobs/**/*
|
|
165
179
|
|
|
166
180
|
Sidekiq/PerformInline:
|
|
167
181
|
Description: 'Suggest to use `perform_inline` instead of `new.perform` for Sidekiq workers.'
|
|
@@ -171,3 +185,26 @@ Sidekiq/SymbolArgument:
|
|
|
171
185
|
Description: "Prevent passing keywords arguments in worker's perform method"
|
|
172
186
|
Enabled: true
|
|
173
187
|
SafeAutoCorrect: false
|
|
188
|
+
|
|
189
|
+
Sidekiq/PreferJob:
|
|
190
|
+
Description: 'Prefer `Sidekiq::Job` over `Sidekiq::Worker`.'
|
|
191
|
+
Enabled: true
|
|
192
|
+
StyleGuide: https://github.com/sidekiq/sidekiq/wiki/Best-Practices#4-use-precise-terminology
|
|
193
|
+
Include:
|
|
194
|
+
- app/workers/**/*
|
|
195
|
+
- app/jobs/**/*
|
|
196
|
+
|
|
197
|
+
Sidekiq/JobNaming:
|
|
198
|
+
Description: 'Job class name should end with `Job` instead of `Worker`.'
|
|
199
|
+
Enabled: true
|
|
200
|
+
StyleGuide: https://github.com/sidekiq/sidekiq/wiki/Best-Practices#4-use-precise-terminology
|
|
201
|
+
Include:
|
|
202
|
+
- app/workers/**/*
|
|
203
|
+
- app/jobs/**/*
|
|
204
|
+
|
|
205
|
+
Sidekiq/JobLocation:
|
|
206
|
+
Description: 'Job class with `Job` suffix should be placed in `app/jobs` directory instead of `app/workers`.'
|
|
207
|
+
Enabled: true
|
|
208
|
+
StyleGuide: https://github.com/sidekiq/sidekiq/wiki/Best-Practices#4-use-precise-terminology
|
|
209
|
+
Include:
|
|
210
|
+
- app/workers/**/*
|
|
@@ -18,7 +18,16 @@ module RuboCop
|
|
|
18
18
|
'Specify endpoint name with an argument: `get :some_path`.'
|
|
19
19
|
HTTP_ACTIONS = Set.new(%i[get head put post patch delete])
|
|
20
20
|
GRAPE_NAMESPACE_ALIAS = Set.new(%i[namespace resource resources])
|
|
21
|
-
METHOD_JUSTIFY_NAMESPACE = Set.new(%i[route_param
|
|
21
|
+
METHOD_JUSTIFY_NAMESPACE = Set.new(%i[route_param
|
|
22
|
+
namespaces
|
|
23
|
+
resource
|
|
24
|
+
resources
|
|
25
|
+
version
|
|
26
|
+
before
|
|
27
|
+
after
|
|
28
|
+
finally
|
|
29
|
+
after_validation
|
|
30
|
+
before_validation])
|
|
22
31
|
|
|
23
32
|
def_node_matcher :namespace?, <<~PATTERN
|
|
24
33
|
(send nil? GRAPE_NAMESPACE_ALIAS ({sym | str} _))
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Migration
|
|
6
|
+
# Prefer defining table changes inside the create_table block instead of
|
|
7
|
+
# altering the table immediately after creating it.
|
|
8
|
+
#
|
|
9
|
+
# @example
|
|
10
|
+
# # bad
|
|
11
|
+
# create_table :users do |t|
|
|
12
|
+
# t.string :email
|
|
13
|
+
# end
|
|
14
|
+
#
|
|
15
|
+
# add_index :users, :email, unique: true
|
|
16
|
+
#
|
|
17
|
+
# # good
|
|
18
|
+
# create_table :users do |t|
|
|
19
|
+
# t.string :email
|
|
20
|
+
# t.index :email, unique: true
|
|
21
|
+
# end
|
|
22
|
+
class AlterAfterCreateTable < Base
|
|
23
|
+
extend AutoCorrector
|
|
24
|
+
include RangeHelp
|
|
25
|
+
|
|
26
|
+
MSG = 'Prefer defining new table changes inside the create_table block.'
|
|
27
|
+
|
|
28
|
+
ALTER_METHODS = (
|
|
29
|
+
Rails::BulkChangeTable::COMBINABLE_ALTER_METHODS +
|
|
30
|
+
Rails::BulkChangeTable::MYSQL_COMBINABLE_ALTER_METHODS +
|
|
31
|
+
Rails::BulkChangeTable::POSTGRESQL_COMBINABLE_ALTER_METHODS +
|
|
32
|
+
Rails::BulkChangeTable::POSTGRESQL_COMBINABLE_ALTER_METHODS_SINCE_6_1
|
|
33
|
+
).uniq.freeze
|
|
34
|
+
|
|
35
|
+
RESTRICT_ON_SEND = ALTER_METHODS.freeze
|
|
36
|
+
|
|
37
|
+
def on_block(node)
|
|
38
|
+
return unless node.send_node&.command?(:create_table)
|
|
39
|
+
return unless (alter_node = alter_node_after_create_table(node))
|
|
40
|
+
return unless same_table?(node.send_node, alter_node)
|
|
41
|
+
|
|
42
|
+
add_alter_offense(node, alter_node)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def alter_node_after_create_table(create_table_node)
|
|
48
|
+
siblings = sibling_nodes(create_table_node)
|
|
49
|
+
index = siblings.index(create_table_node)
|
|
50
|
+
return unless index
|
|
51
|
+
|
|
52
|
+
alter_node = siblings[index + 1]
|
|
53
|
+
return unless alter_node&.send_type?
|
|
54
|
+
return unless ALTER_METHODS.include?(alter_node.method_name)
|
|
55
|
+
return unless alter_node.receiver.nil?
|
|
56
|
+
|
|
57
|
+
alter_node
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def sibling_nodes(node)
|
|
61
|
+
parent = node.parent
|
|
62
|
+
return parent.children if parent&.begin_type?
|
|
63
|
+
|
|
64
|
+
[]
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def same_table?(create_table_node, alter_node)
|
|
68
|
+
create_table_argument = create_table_node.first_argument
|
|
69
|
+
alter_table_argument = alter_node.first_argument
|
|
70
|
+
return false unless create_table_argument && alter_table_argument
|
|
71
|
+
|
|
72
|
+
if create_table_argument.is_a?(RuboCop::AST::BasicLiteralNode) &&
|
|
73
|
+
alter_table_argument.is_a?(RuboCop::AST::BasicLiteralNode)
|
|
74
|
+
literal_value(create_table_argument) == literal_value(alter_table_argument)
|
|
75
|
+
else
|
|
76
|
+
create_table_argument.source == alter_table_argument.source
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def literal_value(node)
|
|
81
|
+
return unless node.is_a?(RuboCop::AST::BasicLiteralNode)
|
|
82
|
+
|
|
83
|
+
node.value.to_s
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def add_alter_offense(create_table_node, alter_node)
|
|
87
|
+
replacement = replacement_for(create_table_node, alter_node)
|
|
88
|
+
|
|
89
|
+
add_offense(alter_node.loc.selector) do |corrector|
|
|
90
|
+
next unless replacement
|
|
91
|
+
|
|
92
|
+
end_line_range = processed_source.buffer.line_range(create_table_node.loc.end.line)
|
|
93
|
+
corrector.insert_before(end_line_range, "#{replacement}\n")
|
|
94
|
+
corrector.remove(range_by_whole_lines(alter_node.source_range, include_final_newline: true))
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def replacement_for(create_table_node, alter_node)
|
|
99
|
+
block_variable = create_table_node.arguments.first&.source
|
|
100
|
+
return unless block_variable
|
|
101
|
+
|
|
102
|
+
case alter_node.method_name
|
|
103
|
+
when :add_index
|
|
104
|
+
replacement_for_add_index(block_variable, alter_node)
|
|
105
|
+
when :add_column
|
|
106
|
+
replacement_for_add_column(block_variable, alter_node)
|
|
107
|
+
when :add_timestamps
|
|
108
|
+
replacement_for_add_timestamps(block_variable, alter_node)
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def replacement_for_add_index(block_variable, node)
|
|
113
|
+
"#{indentation(node)}#{block_variable}.index #{arguments_after_table(node)}"
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def replacement_for_add_column(block_variable, node)
|
|
117
|
+
column_node, type_node = node.arguments[1, 2]
|
|
118
|
+
return unless column_node && type_node
|
|
119
|
+
return unless type_node.sym_type?
|
|
120
|
+
|
|
121
|
+
extra_arguments = node.arguments[3..].map(&:source)
|
|
122
|
+
arguments = [column_node.source, *extra_arguments].join(', ')
|
|
123
|
+
|
|
124
|
+
"#{indentation(node)}#{block_variable}.#{type_node.value} #{arguments}"
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def replacement_for_add_timestamps(block_variable, node)
|
|
128
|
+
arguments = arguments_after_table(node)
|
|
129
|
+
method_call = "#{block_variable}.timestamps"
|
|
130
|
+
method_call = "#{method_call} #{arguments}" unless arguments.empty?
|
|
131
|
+
|
|
132
|
+
"#{indentation(node)}#{method_call}"
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def arguments_after_table(node)
|
|
136
|
+
node.arguments[1..].map(&:source).join(', ')
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def indentation(alter_node)
|
|
140
|
+
' ' * (alter_node.loc.column + 2)
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module RSpec
|
|
6
|
+
# Checks that the `:aggregate_failures` tag is only used on examples,
|
|
7
|
+
# not on example groups.
|
|
8
|
+
#
|
|
9
|
+
# The `:aggregate_failures` tag only works on individual examples (`it`, `specify`, etc.),
|
|
10
|
+
# not on example groups (`describe`, `context`, etc.).
|
|
11
|
+
#
|
|
12
|
+
# @example
|
|
13
|
+
# # bad
|
|
14
|
+
# describe '#enabled?', :aggregate_failures do
|
|
15
|
+
# # ...
|
|
16
|
+
# end
|
|
17
|
+
#
|
|
18
|
+
# context 'when enabled', :aggregate_failures do
|
|
19
|
+
# # ...
|
|
20
|
+
# end
|
|
21
|
+
#
|
|
22
|
+
# # good
|
|
23
|
+
# it 'returns true', :aggregate_failures do
|
|
24
|
+
# # ...
|
|
25
|
+
# end
|
|
26
|
+
#
|
|
27
|
+
# specify 'the behavior', :aggregate_failures do
|
|
28
|
+
# # ...
|
|
29
|
+
# end
|
|
30
|
+
#
|
|
31
|
+
class AggregateFailuresTag < Base
|
|
32
|
+
MSG = 'The `:aggregate_failures` tag should only be used on examples, not on example groups.'
|
|
33
|
+
|
|
34
|
+
EXAMPLE_METHODS = %i[
|
|
35
|
+
it
|
|
36
|
+
specify
|
|
37
|
+
example
|
|
38
|
+
scenario
|
|
39
|
+
its
|
|
40
|
+
fit
|
|
41
|
+
fspecify
|
|
42
|
+
fexample
|
|
43
|
+
fscenario
|
|
44
|
+
focus
|
|
45
|
+
xit
|
|
46
|
+
xspecify
|
|
47
|
+
xexample
|
|
48
|
+
xscenario
|
|
49
|
+
skip
|
|
50
|
+
pending
|
|
51
|
+
].freeze
|
|
52
|
+
|
|
53
|
+
RSPEC_METHODS = %i[
|
|
54
|
+
describe
|
|
55
|
+
context
|
|
56
|
+
feature
|
|
57
|
+
example_group
|
|
58
|
+
xdescribe
|
|
59
|
+
fdescribe
|
|
60
|
+
it
|
|
61
|
+
specify
|
|
62
|
+
example
|
|
63
|
+
scenario
|
|
64
|
+
its
|
|
65
|
+
fit
|
|
66
|
+
fspecify
|
|
67
|
+
fexample
|
|
68
|
+
fscenario
|
|
69
|
+
focus
|
|
70
|
+
xit
|
|
71
|
+
xspecify
|
|
72
|
+
xexample
|
|
73
|
+
xscenario
|
|
74
|
+
skip
|
|
75
|
+
pending
|
|
76
|
+
].freeze
|
|
77
|
+
|
|
78
|
+
def on_block(node)
|
|
79
|
+
return unless rspec_block?(node)
|
|
80
|
+
return unless aggregate_failures_tag?(node)
|
|
81
|
+
return if example_method?(node)
|
|
82
|
+
|
|
83
|
+
# Create a range that includes the method call up to and including the 'do' keyword
|
|
84
|
+
send_node = node.send_node
|
|
85
|
+
range = send_node.source_range.join(node.loc.begin)
|
|
86
|
+
add_offense(range)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
private
|
|
90
|
+
|
|
91
|
+
def rspec_block?(node)
|
|
92
|
+
send_node = node.send_node
|
|
93
|
+
return false unless send_node
|
|
94
|
+
return false unless send_node.send_type?
|
|
95
|
+
|
|
96
|
+
RSPEC_METHODS.include?(send_node.method_name)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def example_method?(node)
|
|
100
|
+
send_node = node.send_node
|
|
101
|
+
return false unless send_node
|
|
102
|
+
|
|
103
|
+
EXAMPLE_METHODS.include?(send_node.method_name)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def aggregate_failures_tag?(node)
|
|
107
|
+
send_node = node.send_node
|
|
108
|
+
return false unless send_node
|
|
109
|
+
|
|
110
|
+
send_node.arguments.any? do |arg|
|
|
111
|
+
if arg.sym_type? && arg.value == :aggregate_failures
|
|
112
|
+
true
|
|
113
|
+
elsif arg.hash_type?
|
|
114
|
+
arg.pairs.any? { |pair| pair.key.sym_type? && pair.key.value == :aggregate_failures }
|
|
115
|
+
else
|
|
116
|
+
false
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
@@ -7,7 +7,7 @@ module RuboCop
|
|
|
7
7
|
module Helpers
|
|
8
8
|
NODE_MATCHERS = lambda do
|
|
9
9
|
def_node_matcher :sidekiq_include?, <<~PATTERN
|
|
10
|
-
(send nil? :include (const (const nil? :Sidekiq) :Worker))
|
|
10
|
+
(send nil? :include (const (const {nil? cbase} :Sidekiq) {:Worker :Job}))
|
|
11
11
|
PATTERN
|
|
12
12
|
|
|
13
13
|
def_node_matcher :includes_sidekiq?, <<~PATTERN
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'helpers'
|
|
4
|
+
|
|
5
|
+
module RuboCop
|
|
6
|
+
module Cop
|
|
7
|
+
module Sidekiq
|
|
8
|
+
# This cop checks that Sidekiq job classes with "Job" suffix are placed in the
|
|
9
|
+
# `app/jobs` directory instead of `app/workers` directory.
|
|
10
|
+
# This follows the modern Sidekiq convention where jobs should be organized
|
|
11
|
+
# in the appropriate directory structure.
|
|
12
|
+
#
|
|
13
|
+
# @example
|
|
14
|
+
# # bad - Job class in app/workers directory
|
|
15
|
+
# # app/workers/my_job.rb
|
|
16
|
+
# class MyJob
|
|
17
|
+
# include Sidekiq::Job
|
|
18
|
+
# end
|
|
19
|
+
#
|
|
20
|
+
# # good - Job class in app/jobs directory
|
|
21
|
+
# # app/jobs/my_job.rb
|
|
22
|
+
# class MyJob
|
|
23
|
+
# include Sidekiq::Job
|
|
24
|
+
# end
|
|
25
|
+
#
|
|
26
|
+
# # good - Worker class can stay in app/workers (though not recommended)
|
|
27
|
+
# # app/workers/my_worker.rb
|
|
28
|
+
# class MyWorker
|
|
29
|
+
# include Sidekiq::Worker
|
|
30
|
+
# end
|
|
31
|
+
class JobLocation < Base
|
|
32
|
+
include Helpers
|
|
33
|
+
|
|
34
|
+
MSG = 'Job class with `Job` suffix should be placed in `app/jobs` directory instead of `app/workers`.'
|
|
35
|
+
|
|
36
|
+
def on_class(node)
|
|
37
|
+
return unless sidekiq_worker?(node)
|
|
38
|
+
|
|
39
|
+
class_name = extract_class_name(node)
|
|
40
|
+
return unless class_name
|
|
41
|
+
return unless class_name.end_with?('Job')
|
|
42
|
+
|
|
43
|
+
file_path = processed_source.buffer.name
|
|
44
|
+
return unless file_path.include?('app/workers/')
|
|
45
|
+
|
|
46
|
+
add_offense(node.children.first, message: MSG)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
def extract_class_name(node)
|
|
52
|
+
name_node = node.children.first
|
|
53
|
+
return unless name_node&.const_type?
|
|
54
|
+
|
|
55
|
+
# Get the last part of the constant name (e.g., "EmailJob" from "MyApp::EmailJob")
|
|
56
|
+
name_node.children.last.to_s
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'helpers'
|
|
4
|
+
|
|
5
|
+
module RuboCop
|
|
6
|
+
module Cop
|
|
7
|
+
module Sidekiq
|
|
8
|
+
# This cop checks that Sidekiq job class names end with "Job" instead of "Worker".
|
|
9
|
+
# Since Sidekiq 6.3, it is best practice to use "Job" terminology over "Worker".
|
|
10
|
+
#
|
|
11
|
+
# @example
|
|
12
|
+
# # bad
|
|
13
|
+
# class MyWorker
|
|
14
|
+
# include Sidekiq::Job
|
|
15
|
+
# end
|
|
16
|
+
#
|
|
17
|
+
# class ProcessDataWorker
|
|
18
|
+
# include Sidekiq::Worker
|
|
19
|
+
# end
|
|
20
|
+
#
|
|
21
|
+
# # good
|
|
22
|
+
# class MyJob
|
|
23
|
+
# include Sidekiq::Job
|
|
24
|
+
# end
|
|
25
|
+
#
|
|
26
|
+
# class ProcessDataJob
|
|
27
|
+
# include Sidekiq::Job
|
|
28
|
+
# end
|
|
29
|
+
class JobNaming < Base
|
|
30
|
+
include Helpers
|
|
31
|
+
|
|
32
|
+
MSG = 'Job class name should end with `Job` instead of `Worker`.'
|
|
33
|
+
|
|
34
|
+
def_node_matcher :class_name, <<~PATTERN
|
|
35
|
+
(class (const _ $_) ...)
|
|
36
|
+
PATTERN
|
|
37
|
+
|
|
38
|
+
def on_class(node)
|
|
39
|
+
return unless sidekiq_worker?(node)
|
|
40
|
+
|
|
41
|
+
class_name = extract_class_name(node)
|
|
42
|
+
return unless class_name
|
|
43
|
+
return unless class_name.end_with?('Worker')
|
|
44
|
+
|
|
45
|
+
add_offense(node.children.first, message: MSG)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def extract_class_name(node)
|
|
51
|
+
name_node = node.children.first
|
|
52
|
+
return unless name_node&.const_type?
|
|
53
|
+
|
|
54
|
+
# Get the last part of the constant name (e.g., "EmailWorker" from "MyApp::EmailWorker")
|
|
55
|
+
name_node.children.last.to_s
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'helpers'
|
|
4
|
+
|
|
5
|
+
module RuboCop
|
|
6
|
+
module Cop
|
|
7
|
+
module Sidekiq
|
|
8
|
+
# This cop checks for the use of `Sidekiq::Worker` and suggests using `Sidekiq::Job` instead.
|
|
9
|
+
# Since Sidekiq 6.3, it is best practice to use `Sidekiq::Job` over `Sidekiq::Worker`.
|
|
10
|
+
#
|
|
11
|
+
# @example
|
|
12
|
+
# # bad
|
|
13
|
+
# class MyWorker
|
|
14
|
+
# include Sidekiq::Worker
|
|
15
|
+
# end
|
|
16
|
+
#
|
|
17
|
+
# # good
|
|
18
|
+
# class MyJob
|
|
19
|
+
# include Sidekiq::Job
|
|
20
|
+
# end
|
|
21
|
+
class PreferJob < Base
|
|
22
|
+
extend AutoCorrector
|
|
23
|
+
|
|
24
|
+
MSG = 'Prefer `Sidekiq::Job` over `Sidekiq::Worker`.'
|
|
25
|
+
|
|
26
|
+
def_node_matcher :sidekiq_worker_include?, <<~PATTERN
|
|
27
|
+
(send nil? :include (const (const {nil? cbase} :Sidekiq) :Worker))
|
|
28
|
+
PATTERN
|
|
29
|
+
|
|
30
|
+
def on_send(node)
|
|
31
|
+
return unless sidekiq_worker_include?(node)
|
|
32
|
+
|
|
33
|
+
add_offense(node, message: MSG) do |corrector|
|
|
34
|
+
corrector.replace(node.arguments.first, 'Sidekiq::Job')
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rubocop-petal
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.10.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jean-Francis Bastien
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: lint_roller
|
|
@@ -108,7 +107,6 @@ dependencies:
|
|
|
108
107
|
- - "~>"
|
|
109
108
|
- !ruby/object:Gem::Version
|
|
110
109
|
version: '2.31'
|
|
111
|
-
description:
|
|
112
110
|
email:
|
|
113
111
|
- jfbastien@petalmd.com
|
|
114
112
|
executables: []
|
|
@@ -128,6 +126,7 @@ files:
|
|
|
128
126
|
- lib/rubocop/cop/grape/helpers_include_module.rb
|
|
129
127
|
- lib/rubocop/cop/grape/prefer_namespace.rb
|
|
130
128
|
- lib/rubocop/cop/grape/unnecessary_namespace.rb
|
|
129
|
+
- lib/rubocop/cop/migration/alter_after_create_table.rb
|
|
131
130
|
- lib/rubocop/cop/migration/always_bulk_change_table.rb
|
|
132
131
|
- lib/rubocop/cop/migration/change_table_references.rb
|
|
133
132
|
- lib/rubocop/cop/migration/foreign_key_option.rb
|
|
@@ -145,6 +144,7 @@ files:
|
|
|
145
144
|
- lib/rubocop/cop/rspec/aggregate_examples/matchers_with_side_effects.rb
|
|
146
145
|
- lib/rubocop/cop/rspec/aggregate_examples/metadata_helpers.rb
|
|
147
146
|
- lib/rubocop/cop/rspec/aggregate_examples/node_matchers.rb
|
|
147
|
+
- lib/rubocop/cop/rspec/aggregate_failures_tag.rb
|
|
148
148
|
- lib/rubocop/cop/rspec/chewy_strategy.rb
|
|
149
149
|
- lib/rubocop/cop/rspec/create_list_max.rb
|
|
150
150
|
- lib/rubocop/cop/rspec/json_response.rb
|
|
@@ -155,9 +155,12 @@ files:
|
|
|
155
155
|
- lib/rubocop/cop/sidekiq/const_argument.rb
|
|
156
156
|
- lib/rubocop/cop/sidekiq/date_time_argument.rb
|
|
157
157
|
- lib/rubocop/cop/sidekiq/helpers.rb
|
|
158
|
+
- lib/rubocop/cop/sidekiq/job_location.rb
|
|
159
|
+
- lib/rubocop/cop/sidekiq/job_naming.rb
|
|
158
160
|
- lib/rubocop/cop/sidekiq/keyword_arguments.rb
|
|
159
161
|
- lib/rubocop/cop/sidekiq/no_nil_return.rb
|
|
160
162
|
- lib/rubocop/cop/sidekiq/perform_inline.rb
|
|
163
|
+
- lib/rubocop/cop/sidekiq/prefer_job.rb
|
|
161
164
|
- lib/rubocop/cop/sidekiq/symbol_argument.rb
|
|
162
165
|
- lib/rubocop/petal.rb
|
|
163
166
|
- lib/rubocop/petal/plugin.rb
|
|
@@ -172,7 +175,6 @@ metadata:
|
|
|
172
175
|
bug_tracker_uri: https://github.com/petalmd/rubocop-petal/issues
|
|
173
176
|
rubygems_mfa_required: 'true'
|
|
174
177
|
default_lint_roller_plugin: RuboCop::Petal::Plugin
|
|
175
|
-
post_install_message:
|
|
176
178
|
rdoc_options: []
|
|
177
179
|
require_paths:
|
|
178
180
|
- lib
|
|
@@ -187,8 +189,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
187
189
|
- !ruby/object:Gem::Version
|
|
188
190
|
version: '0'
|
|
189
191
|
requirements: []
|
|
190
|
-
rubygems_version: 3.
|
|
191
|
-
signing_key:
|
|
192
|
+
rubygems_version: 3.6.9
|
|
192
193
|
specification_version: 4
|
|
193
194
|
summary: Petal custom cops
|
|
194
195
|
test_files: []
|