rubocop-petal 1.8.0 → 1.9.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cf2f66c07fd9f7e2d26db32b9ab5a5fc704293066bf6e8519b6fdec8cec71128
4
- data.tar.gz: 3f4a7fef3bde079552b9bcffc43665a93422d3bf4dacda37a754540787dd4773
3
+ metadata.gz: 02e763ff0683f1009a5b4e387eea9beb7e19eea47670c634f7d182b182856e41
4
+ data.tar.gz: 66576879ea7a772d5323fcf89aadf9a91ea1e0a25ee2679553ec5c83d2e197d7
5
5
  SHA512:
6
- metadata.gz: 70fe73e240f643f554767029a2cffbb4e298b80706c823c2dda8eccb2470da549aba51847241e68f7871aedabd6a0702f37ed97ed771c2aa703aabe6c03c9b93
7
- data.tar.gz: 77d30ff3b03bf663b6546f3a243a90cde664a854467879e0ef3d47f2856f860eddec31ac39a8f9b723450e642f3f9f2593c1ad1cfae59baa5fea8e1b3e67e3e6
6
+ metadata.gz: '02790f98ebe560dec0615c66faabf2c67ec9f062ef8db564026b76ee72dbbfb695bbe63946d418f5b8b2872275e684acf3f5d31a74bae35c54f0d30d5d31950d'
7
+ data.tar.gz: 2a363c24244f2c6b6b451bac58ccd9a65c6c0f4e5ab6d07160720ae28a707c85a2f3e273f38116b90cb3b2bf9f3a1d089f9f58cb422cfa89be002d720543c1e1
data/config/default.yml CHANGED
@@ -59,6 +59,12 @@ RSpec/AggregateExamples:
59
59
  - validate_inclusion_of
60
60
  - validates_exclusion_of
61
61
 
62
+ RSpec/AggregateFailuresTag:
63
+ Description: 'Checks that the `:aggregate_failures` tag is only used on examples, not on example groups.'
64
+ Enabled: true
65
+ Include:
66
+ - spec/**/*
67
+
62
68
  RSpec/ChewyStrategy:
63
69
  Description: 'Prevent using Chewy strategy in tests.'
64
70
  Enabled: true
@@ -156,12 +162,14 @@ Sidekiq/KeywordArguments:
156
162
  Enabled: true
157
163
  Include:
158
164
  - app/workers/**/*
165
+ - app/jobs/**/*
159
166
 
160
167
  Sidekiq/NoNilReturn:
161
168
  Description: 'Prevent early nil return in workers'
162
169
  Enabled: false
163
170
  Include:
164
171
  - app/workers/**/*
172
+ - app/jobs/**/*
165
173
 
166
174
  Sidekiq/PerformInline:
167
175
  Description: 'Suggest to use `perform_inline` instead of `new.perform` for Sidekiq workers.'
@@ -171,3 +179,26 @@ Sidekiq/SymbolArgument:
171
179
  Description: "Prevent passing keywords arguments in worker's perform method"
172
180
  Enabled: true
173
181
  SafeAutoCorrect: false
182
+
183
+ Sidekiq/PreferJob:
184
+ Description: 'Prefer `Sidekiq::Job` over `Sidekiq::Worker`.'
185
+ Enabled: true
186
+ StyleGuide: https://github.com/sidekiq/sidekiq/wiki/Best-Practices#4-use-precise-terminology
187
+ Include:
188
+ - app/workers/**/*
189
+ - app/jobs/**/*
190
+
191
+ Sidekiq/JobNaming:
192
+ Description: 'Job class name should end with `Job` instead of `Worker`.'
193
+ Enabled: true
194
+ StyleGuide: https://github.com/sidekiq/sidekiq/wiki/Best-Practices#4-use-precise-terminology
195
+ Include:
196
+ - app/workers/**/*
197
+ - app/jobs/**/*
198
+
199
+ Sidekiq/JobLocation:
200
+ Description: 'Job class with `Job` suffix should be placed in `app/jobs` directory instead of `app/workers`.'
201
+ Enabled: true
202
+ StyleGuide: https://github.com/sidekiq/sidekiq/wiki/Best-Practices#4-use-precise-terminology
203
+ Include:
204
+ - 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 namespaces resource resources version])
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,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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RuboCop
4
4
  module Petal
5
- VERSION = '1.8.0'
5
+ VERSION = '1.9.0'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-petal
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.0
4
+ version: 1.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jean-Francis Bastien
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-04-11 00:00:00.000000000 Z
11
+ date: 2025-09-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: lint_roller
@@ -145,6 +145,7 @@ files:
145
145
  - lib/rubocop/cop/rspec/aggregate_examples/matchers_with_side_effects.rb
146
146
  - lib/rubocop/cop/rspec/aggregate_examples/metadata_helpers.rb
147
147
  - lib/rubocop/cop/rspec/aggregate_examples/node_matchers.rb
148
+ - lib/rubocop/cop/rspec/aggregate_failures_tag.rb
148
149
  - lib/rubocop/cop/rspec/chewy_strategy.rb
149
150
  - lib/rubocop/cop/rspec/create_list_max.rb
150
151
  - lib/rubocop/cop/rspec/json_response.rb
@@ -155,9 +156,12 @@ files:
155
156
  - lib/rubocop/cop/sidekiq/const_argument.rb
156
157
  - lib/rubocop/cop/sidekiq/date_time_argument.rb
157
158
  - lib/rubocop/cop/sidekiq/helpers.rb
159
+ - lib/rubocop/cop/sidekiq/job_location.rb
160
+ - lib/rubocop/cop/sidekiq/job_naming.rb
158
161
  - lib/rubocop/cop/sidekiq/keyword_arguments.rb
159
162
  - lib/rubocop/cop/sidekiq/no_nil_return.rb
160
163
  - lib/rubocop/cop/sidekiq/perform_inline.rb
164
+ - lib/rubocop/cop/sidekiq/prefer_job.rb
161
165
  - lib/rubocop/cop/sidekiq/symbol_argument.rb
162
166
  - lib/rubocop/petal.rb
163
167
  - lib/rubocop/petal/plugin.rb