繁体   English   中英

如何编写 RuboCop Cop 以防止使用关键字 arguments 编写 Sidekiq 工作人员?

[英]How to write a RuboCop Cop to prevent writing Sidekiq workers using keyword arguments?

不久前,我发现在定义 Sidekiq workers 时不能使用关键字 arguments 由于它只会在入队后引发异常,因此我想防止它永远进入生产环境。 为此,我想添加一个警察,检查 arguments 的#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 工人申请这个警察。 我在这里遵循正确的方法吗? 有没有更好的方法来做到这一点?

您可以使用inheritance为您的 Sidekiq 工作人员启用特定的警察。 例如,如果您的工作人员位于app/workers中,那么您可以在那里创建一个从项目根目录继承的新规则集,然后启用您的自定义警察:

# 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

要让您的自定义 cop 检测关键字 arguments,请使用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 将返回以下 output:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM