Как написать RuboCop Cop, чтобы запретить писать работникам Sidekiq, используя ключевые аргументы? - PullRequest
1 голос
/ 21 апреля 2020

Не слишком долго go, я обнаружил, что нельзя использовать аргументы ключевых слов при определении работников Sidekiq . Так как он вызывает исключение только после того, как его ставят в очередь, я хочу, чтобы он не достиг производства навсегда. И для этого я хотел бы добавить полицейского, который проверяет аргументы для #perform и выдает ошибку, если используется аргумент ключевого слова. Пока это моя неудачная попытка:

module RuboCop
  module Cop
    class SidekiqDontUseKeywordArguments < RuboCop::Cop::Cop
      MSG = "Don't use keyword arguments in workers".freeze
      OBSERVED_METHOD = :perform

      def on_def(node)
        return if node.method_name != OBSERVED_METHOD

        node.arguments.each do |argument|
          if keyword_argument?(argument)
            add_offense(node, location: :expression)
          end
        end
      end

      private

      def keyword_argument?(argument)
        # detect if the argument is a keyword
      end
    end
  end
end

Я здесь упускаю две вещи. Первое и самое важное - я не знаю, как определить, является ли аргумент ключевым словом или нет. Во-вторых, я бы хотел применить этого копа только для работников Sidekiq. Я придерживаюсь правильного подхода здесь? Есть ли лучший способ сделать это?

1 Ответ

1 голос
/ 21 апреля 2020

Вы можете включить определенные c копы только для ваших работников Sidekiq, используя наследование . Например, если ваши работники живут в app/workers, вы можете создать там новый набор правил, который будет наследоваться от root вашего проекта, а затем включить вашего настраиваемого полицейского:

# app/workers/.rubocop.yml
inherit_from:
  - ../../.rubocop.yml
require:
  - ../lib/rubocop/cop/custom/sidekiq_dont_use_keyword_arguments.rb
Custom/SidekiqDontUseKeywordArguments:
  Enabled: true
# For validation of this theory only; do not use this
Lint/DuplicateMethods:
  Enabled: false

Чтобы ваш настраиваемый полицейский обнаружил ключевое слово аргументы используют метод node.type. Элементы node.arguments сами являются узлами и поддерживают одни и те же методы, и чтение аргумента type вернет одно из четырех значений:

# Standard argument: perform(foo)
:arg

# Optional standard argument: perform(foo = 1)
:optarg

# Keyword argument: perform(foo:)
:kwarg

# Optional keyword argument: perform(foo: 1)
:kwoptarg

Так что проверьте :kwarg и :kwoptarg (и обратите внимание на изменение пути и дополнительный модуль Custom, чтобы определить отдел этого полицейского):

# app/lib/rubocop/cop/custom/sidekiq_dont_use_keyword_arguments.rb

module RuboCop
  module Cop
    module Custom
      class SidekiqDontUseKeywordArguments < RuboCop::Cop::Cop
        MSG = "Don't use keyword arguments in workers".freeze
        OBSERVED_METHOD = :perform

        def on_def(node)
          return if node.method_name != OBSERVED_METHOD

          node.arguments.each do |argument|
            if argument.type == :kwarg || argument.type == : kwoptarg
              add_offense(node, location: :expression)
            end
          end
        end
      end
    end
  end
end

Давайте использовать это как пример работника:

# app/workers/example_worker.rb
class ExampleWorker
  # Standard argument; this will not trigger the cop
  def perform(foo); end

  # Optional standard argument; this will not trigger the cop
  def perform(foo = 1); end

  # Keyword argument; this will trigger the cop
  def perform(foo:); end

  # Optional keyword argument; this will trigger the cop
  def perform(foo: 1); end
end

Запуск Rubocop вернет следующий вывод:

rubocop app/workers
Inspecting 1 file
C

Offenses:

app/workers/example_worker.rb:9:3: C: Custom/SidekiqDontUseKeywordArguments: Don't use keyword arguments in workers
  def perform(foo:); end
  ^^^^^^^^^^^^^^^^^^^^^^
app/workers/example_worker.rb:12:3: C: Custom/SidekiqDontUseKeywordArguments: Don't use keyword arguments in workers
  def perform(foo: 1); end
  ^^^^^^^^^^^^^^^^^^^^^^^^

1 file inspected, 2 offenses detected
...