# frozen_string_literal: true module Gitlab module Dangerfiles CategoryStruct = Struct.new(:name, :project, :kind, :labels, keyword_init: true) class Category < CategoryStruct def self.for(name, **arguments) (name_to_class[name] || self).new(name: name, **arguments) end def self.name_to_class @name_to_class ||= { none: None, test: Test, tooling: Tooling, integrations_be: IntegrationsBE, integrations_fe: IntegrationsFE, ux: UX, }.freeze end private_class_method :name_to_class def has_capability?(...) has_particular_capability?(...) || has_universal_capability?(...) end private def has_particular_capability?(teammate) teammate.capabilities(project).include?(capability) end def has_universal_capability?(teammate) false end def capability @capability ||= "#{kind} #{name}" end class None < Category def capability @capability ||= kind.to_s end end class Test < Category private def has_particular_capability?(teammate) return false if kind != :reviewer area = teammate.role[/Software Engineer in Test(?:.*?, (\w+))/, 1] area && labels.any?("devops::#{area.downcase}") end end class Tooling < Category private def has_particular_capability?(teammate) if super true elsif %i[trainee_maintainer maintainer].include?(kind) false else # fallback to backend reviewer teammate.capabilities(project).include?("#{kind} backend") end end end class IntegrationsBE < Category private def has_particular_capability?(teammate) kind == :reviewer && teammate.role.match?(/Backend Engineer.+Manage:Integrations/) end end class IntegrationsFE < Category private def has_particular_capability?(teammate) kind == :reviewer && teammate.role.match?(/Frontend Engineer.+Manage:Integrations/) end end class UX < Category private def has_universal_capability?(teammate) teammate.projects.each_value.find do |capabilities| capabilities.include?(capability) end end end end end end