diff --git a/config/default.yml b/config/default.yml index a4dc18c..e0f0f02 100644 --- a/config/default.yml +++ b/config/default.yml @@ -146,6 +146,10 @@ Sidekiq/NoNilReturn: Include: - app/workers/**/* +Sidekiq/PerformInline: + Description: 'Suggest to use `perform_inline` instead of `new.perform` for Sidekiq workers.' + Enabled: true + Sidekiq/SymbolArgument: Description: "Prevent passing keywords arguments in worker's perform method" Enabled: true diff --git a/lib/rubocop/cop/sidekiq/perform_inline.rb b/lib/rubocop/cop/sidekiq/perform_inline.rb new file mode 100644 index 0000000..71306c7 --- /dev/null +++ b/lib/rubocop/cop/sidekiq/perform_inline.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module Sidekiq + # Suggest to use `perform_inline` instead of `new.perform` for Sidekiq workers. + # + # @bad + # MyWorker.new.perform + # + # @good + # MyWorker.perform_inline + # + class PerformInline < Base + extend AutoCorrector + MSG = 'Use `perform_inline` instead of `new.perform`.' + + RESTRICT_ON_SEND = %i[perform].freeze + + # @!method new_perform?(node) + def_node_matcher :new_perform?, <<~PATTERN + (send (send (const nil? _) :new) :perform) + PATTERN + + def on_send(node) + return unless new_perform?(node) + + add_offense(node) + end + + def autocorrect(node) + lambda do |corrector| + receiver, _method_name = *node + corrector.replace(receiver.source_range, + receiver.source_range.source.gsub('new.perform', 'perform_inline')) + end + end + end + end + end +end diff --git a/spec/rubocop/cop/sidekiq/perform_inline_spec.rb b/spec/rubocop/cop/sidekiq/perform_inline_spec.rb new file mode 100644 index 0000000..96d1bb6 --- /dev/null +++ b/spec/rubocop/cop/sidekiq/perform_inline_spec.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +RSpec.describe RuboCop::Cop::Sidekiq::PerformInline, :config do + let(:config) { RuboCop::Config.new } + + it 'registers an offense when using `new.perform`' do + expect_offense(<<~RUBY) + MyWorker.new.perform + ^^^^^^^^^^^ Sidekiq/PerformInline: Use `perform_inline` instead of `new.perform` + RUBY + + expect_correction(<<~RUBY) + MyWorker.perform_inline + RUBY + end + + it 'does not register an offense when using `#good_method`' do + expect_no_offenses(<<~RUBY) + MyWorker.perform_inline + RUBY + end +end