-
-
Save stem/e0f71dc5c31f5187dad739023d7b50bf to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
require "yaml" | |
module RuboCop | |
module Cop | |
module Epicery | |
# Cop to ensure all jobs are properly configured : | |
# - inherits ::ApplicationJob WITH the :: to avoid nasty namespace issues | |
# - calls sidekiq_options queue: "something" | |
# | |
# TODO: make the queue name type a cop parameter (string|symbol) | |
# TODO: make the sidekiq config files pattern a cop parameter | |
# TODO: use memoization to avoid loading N times the sidekiq config | |
class Job < ::RuboCop::Cop::Base | |
extend AutoCorrector | |
def basename(node) | |
path = node.location.expression.source_buffer.name | |
File.basename(path) | |
end | |
def_node_matcher :class_name, <<~PATTERN | |
(class (const nil? $_) ...) | |
PATTERN | |
# check if this is the main class of this file, according | |
# to the rails file name convention : SomeClass is defined is some_class.rb | |
def main_class?(node) | |
name = class_name(node) | |
basename(node) == "#{name.to_s.underscore}.rb" | |
end | |
def in_subdir?(node, prefix) | |
path = node.location.expression.source_buffer.name | |
path = RuboCop::PathUtil.smart_path(path) | |
path.start_with?(prefix) | |
end | |
def_node_matcher :application_job?, <<~PATTERN | |
(class (const ...) (const cbase :ApplicationJob) ...) | |
PATTERN | |
def_node_matcher :queue_name?, <<~PATTERN | |
`(send nil? :sidekiq_options (hash <(pair (sym :queue) $(...)) ...>)) | |
PATTERN | |
def on_class(node) | |
return unless in_subdir?(node, "app/jobs/") | |
return unless main_class?(node) | |
return add_offense(node, message: "Jobs should inherit from ::ApplicationJob") unless application_job?(node) | |
expression = queue_name?(node) | |
return add_offense(node, message: "Manually set a queue; the default is not executed!") unless expression | |
unless expression.children[0].is_a?(String) | |
add_offense(expression, message: "Use a string as the queue name") do |corrector| | |
corrector.replace(expression, expression.children[0].to_s.inspect) | |
end | |
end | |
known_queues = Dir.glob("#{__dir__}/../../**/sidekiq*.yml").flat_map do |file| | |
YAML.load(File.read(file))[:queues] # rubocop:disable Security/YAMLLoad | |
end | |
unless known_queues.include?(expression.children[0].to_s) | |
add_offense(expression, message: "Unkown queue name") | |
end | |
end | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment