diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-03-22 00:09:00 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-03-22 00:09:00 +0300 |
commit | 9fe1a4945b8db40c6b5d7b3ce7c6dbc93cdf67be (patch) | |
tree | 348efd8561338490a9f2c0c2a6bea91ef3bcd2de /rubocop | |
parent | 248492cc573e85aea19d7493c3a15d459be016c5 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'rubocop')
-rw-r--r-- | rubocop/cop/search/namespaced_class.rb | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/rubocop/cop/search/namespaced_class.rb b/rubocop/cop/search/namespaced_class.rb new file mode 100644 index 00000000000..8824107ae61 --- /dev/null +++ b/rubocop/cop/search/namespaced_class.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module Search + # Cop that enforces use of Search namespace for search related code. + # + # @example + # # bad + # class MySearchClass + # end + # + # # good + # module Search + # class MySearchClass + # end + # end + class NamespacedClass < RuboCop::Cop::Base + MSG = 'Search related code must be declared inside Search top level namespace. For more info: https://gitlab.com/gitlab-org/gitlab/-/issues/398207' + + # These namespaces are considered acceptable. + # Note: Nested namespace like Foo::Bar are also supported. + PERMITTED_NAMESPACES = %w[Search EE::Search API::Search EE::API::Search RuboCop::Cop::Search] + .map { |x| x.split('::') }.freeze + + SEARCH_REGEXES = [ + /elastic/i, + /zoekt/i, + /search/i + ].freeze + + def on_module(node) + add_identifiers(node) + + run_search_namespace_cop(node) if node.child_nodes.none? { |n| n.module_type? || n.class_type? } + end + + def on_class(node) + add_identifiers(node) + run_search_namespace_cop(node) + end + + private + + def run_search_namespace_cop(node) + add_offense(node.loc.name) if !namespace_allowed? && namespace_search_related? + end + + def add_identifiers(node) + identifiers.concat(identifiers_for(node)) + end + + def identifiers + @identifiers ||= [] + end + + def identifiers_for(node) + source = node.respond_to?(:identifier) ? node.identifier.source : node.source + source.sub(/^::/, '').split('::') + end + + def namespace_allowed? + PERMITTED_NAMESPACES.any? do |namespaces| + identifiers.first(namespaces.size) == namespaces + end + end + + def namespace_search_related? + SEARCH_REGEXES.any? { |x| x.match?(identifiers.join('::')) } + end + end + end + end +end |