summaryrefslogtreecommitdiff
path: root/rubocop/cop/usage_data
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-06-16 18:25:58 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-06-16 18:25:58 +0000
commita5f4bba440d7f9ea47046a0a561d49adf0a1e6d4 (patch)
treefb69158581673816a8cd895f9d352dcb3c678b1e /rubocop/cop/usage_data
parentd16b2e8639e99961de6ddc93909f3bb5c1445ba1 (diff)
downloadgitlab-ce-a5f4bba440d7f9ea47046a0a561d49adf0a1e6d4.tar.gz
Add latest changes from gitlab-org/gitlab@14-0-stable-eev14.0.0-rc42
Diffstat (limited to 'rubocop/cop/usage_data')
-rw-r--r--rubocop/cop/usage_data/histogram_with_large_table.rb58
-rw-r--r--rubocop/cop/usage_data/instrumentation_superclass.rb63
2 files changed, 121 insertions, 0 deletions
diff --git a/rubocop/cop/usage_data/histogram_with_large_table.rb b/rubocop/cop/usage_data/histogram_with_large_table.rb
new file mode 100644
index 00000000000..961773df55c
--- /dev/null
+++ b/rubocop/cop/usage_data/histogram_with_large_table.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+module RuboCop
+ module Cop
+ module UsageData
+ # This cop checks that histogram method is not used in usage_data.rb files
+ # for models representing large tables, as defined by migration helpers.
+ #
+ # @example
+ #
+ # # bad
+ # histogram(Issue, buckets: 1..100)
+ # histogram(User.active, buckets: 1..100)
+ class HistogramWithLargeTable < RuboCop::Cop::Cop
+ MSG = 'Avoid histogram method on %{model_name}'
+
+ # Match one level const as Issue, Gitlab
+ def_node_matcher :one_level_node, <<~PATTERN
+ (send nil? :histogram
+ `(const {nil? cbase} $_)
+ ...)
+ PATTERN
+
+ # Match two level const as ::Clusters::Cluster, ::Ci::Pipeline
+ def_node_matcher :two_level_node, <<~PATTERN
+ (send nil? :histogram
+ `(const
+ (const {nil? cbase} $_)
+ $_)
+ ...)
+ PATTERN
+
+ def on_send(node)
+ one_level_matches = one_level_node(node)
+ two_level_matches = two_level_node(node)
+
+ return unless Array(one_level_matches).any? || Array(two_level_matches).any?
+
+ class_name = two_level_matches ? two_level_matches.join('::').to_sym : one_level_matches
+
+ if large_table?(class_name)
+ add_offense(node, location: :expression, message: format(MSG, model_name: class_name))
+ end
+ end
+
+ private
+
+ def large_table?(model)
+ high_traffic_models.include?(model.to_s)
+ end
+
+ def high_traffic_models
+ cop_config['HighTrafficModels'] || []
+ end
+ end
+ end
+ end
+end
diff --git a/rubocop/cop/usage_data/instrumentation_superclass.rb b/rubocop/cop/usage_data/instrumentation_superclass.rb
new file mode 100644
index 00000000000..2ff2ed47a23
--- /dev/null
+++ b/rubocop/cop/usage_data/instrumentation_superclass.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+module RuboCop
+ module Cop
+ module UsageData
+ # This cop checks that metric instrumentation classes subclass one of the allowed base classes.
+ #
+ # @example
+ #
+ # # good
+ # class CountIssues < DatabaseMetric
+ # # ...
+ # end
+ #
+ # # bad
+ # class CountIssues < BaseMetric
+ # # ...
+ # end
+ class InstrumentationSuperclass < RuboCop::Cop::Cop
+ MSG = "Instrumentation classes should subclass one of the following: %{allowed_classes}."
+
+ BASE_PATTERN = "(const nil? !#allowed_class?)"
+
+ def_node_matcher :class_definition, <<~PATTERN
+ (class (const _ !#allowed_class?) #{BASE_PATTERN} ...)
+ PATTERN
+
+ def_node_matcher :class_new_definition, <<~PATTERN
+ [!^(casgn {nil? cbase} #allowed_class? ...)
+ !^^(casgn {nil? cbase} #allowed_class? (block ...))
+ (send (const {nil? cbase} :Class) :new #{BASE_PATTERN})]
+ PATTERN
+
+ def on_class(node)
+ class_definition(node) do
+ register_offense(node.children[1])
+ end
+ end
+
+ def on_send(node)
+ class_new_definition(node) do
+ register_offense(node.children.last)
+ end
+ end
+
+ private
+
+ def allowed_class?(class_name)
+ allowed_classes.include?(class_name)
+ end
+
+ def allowed_classes
+ cop_config['AllowedClasses'] || []
+ end
+
+ def register_offense(offense_node)
+ message = format(MSG, allowed_classes: allowed_classes.join(', '))
+ add_offense(offense_node, message: message)
+ end
+ end
+ end
+ end
+end