From c22dc6373f815eaafa8c42575e866991845431fc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9my=20Coutable?= <remy@rymai.me>
Date: Wed, 5 Jul 2023 11:07:48 +0000
Subject: [PATCH] Don't inherit from main .rubocop.yml in gems
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Rémy Coutable <remy@rymai.me>
---
 .rubocop.yml                                  |   5 -
 .rubocop_todo/rails/output_safety.yml         |   1 -
 doc/development/gems.md                       |  12 +-
 gems/activerecord-gitlab/.rubocop.yml         |  15 +-
 gems/activerecord-gitlab/Gemfile.lock         |  40 ++---
 .../activerecord-gitlab.gemspec               |  15 +-
 gems/config/rubocop.yml                       |  73 +++++++++
 gems/gitlab-rspec/.rubocop.yml                |  14 +-
 gems/gitlab-rspec/Gemfile.lock                |  27 ++--
 gems/gitlab-rspec/gitlab-rspec.gemspec        |   6 +-
 gems/gitlab-rspec/lib/gitlab/rspec.rb         |   5 +
 .../gitlab-rspec/lib/gitlab/rspec/stub_env.rb |   2 +-
 gems/gitlab-utils/.rubocop.yml                |  40 ++---
 gems/gitlab-utils/Gemfile.lock                |  37 +++--
 gems/gitlab-utils/gitlab-utils.gemspec        |   7 +-
 gems/gitlab-utils/lib/gitlab/version_info.rb  |  17 ++-
 .../spec/gitlab/utils/strong_memoize_spec.rb  |  26 ++--
 .../background_migration/feature_category.rb  |   2 +-
 rubocop/cop/rake/require.rb                   |  10 ++
 .../distinct_count_by_large_foreign_key.rb    |   6 +
 .../usage_data/histogram_with_large_table.rb  |   6 +
 .../usage_data/instrumentation_superclass.rb  |   8 +
 rubocop/cop/usage_data/large_table.rb         |   6 +
 rubocop/rubocop-usage-data.yml                |  11 --
 rubocop/usage_data_helpers.rb                 |  19 +++
 scripts/lint-vendored-gems.sh                 |   5 -
 scripts/static-analysis                       |   3 +-
 .../cop/qa/element_with_pattern_spec.rb       |   2 +-
 spec/rubocop/cop/rake/require_spec.rb         | 108 +++++++++-----
 ...istinct_count_by_large_foreign_key_spec.rb |  52 ++++---
 .../histogram_with_large_table_spec.rb        | 140 ++++++++++--------
 .../instrumentation_superclass_spec.rb        |  76 ++++++----
 .../cop/usage_data/large_table_spec.rb        |  10 +-
 33 files changed, 486 insertions(+), 320 deletions(-)
 create mode 100644 gems/config/rubocop.yml
 create mode 100644 rubocop/usage_data_helpers.rb
 delete mode 100755 scripts/lint-vendored-gems.sh

diff --git a/.rubocop.yml b/.rubocop.yml
index 8219ce78f03e3..8c52516a21c5e 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -984,11 +984,6 @@ Cop/SidekiqApiUsage:
     - 'config/initializers/sidekiq.rb'
     - 'config/initializers/forbid_sidekiq_in_transactions.rb'
 
-Rake/Require:
-  Include:
-    - '{,ee/,jh/}lib/**/*.rake'
-    - 'qa/tasks/**/*.rake'
-
 Cop/FeatureFlagUsage:
   Include:
     - 'lib/gitlab/redis/**/*.rb'
diff --git a/.rubocop_todo/rails/output_safety.yml b/.rubocop_todo/rails/output_safety.yml
index 960d4ef081846..53f9381099f99 100644
--- a/.rubocop_todo/rails/output_safety.yml
+++ b/.rubocop_todo/rails/output_safety.yml
@@ -147,7 +147,6 @@ Rails/OutputSafety:
     - 'lib/gitlab/observability.rb'
     - 'lib/gitlab/other_markup.rb'
     - 'lib/gitlab/string_range_marker.rb'
-    - 'lib/gitlab/utils.rb'
     - 'spec/helpers/application_helper_spec.rb'
     - 'spec/helpers/notify_helper_spec.rb'
     - 'spec/helpers/profiles_helper_spec.rb'
diff --git a/doc/development/gems.md b/doc/development/gems.md
index 0a8b840746199..a10fb86e88338 100644
--- a/doc/development/gems.md
+++ b/doc/development/gems.md
@@ -97,17 +97,7 @@ You can see example adding a new gem: [!121676](https://gitlab.com/gitlab-org/gi
 
    ```yaml
    inherit_from:
-     - ../../.rubocop.yml
-
-   CodeReuse/ActiveRecord:
-     Enabled: false
-
-   AllCops:
-     TargetRubyVersion: 3.0
-
-   Naming/FileName:
-     Exclude:
-       - spec/**/*.rb
+     - ../config/rubocop.yml
    ```
 
 1. Configure CI for a newly added Gem:
diff --git a/gems/activerecord-gitlab/.rubocop.yml b/gems/activerecord-gitlab/.rubocop.yml
index 52fdea825c63d..8c99d7c47d18b 100644
--- a/gems/activerecord-gitlab/.rubocop.yml
+++ b/gems/activerecord-gitlab/.rubocop.yml
@@ -1,15 +1,6 @@
 inherit_from:
-  - ../../.rubocop.yml
+  - ../config/rubocop.yml
 
-CodeReuse/ActiveRecord:
+# FIXME
+Gitlab/RSpec/AvoidSetup:
   Enabled: false
-
-Rails/ApplicationRecord:
-  Enabled: false
-
-AllCops:
-  TargetRubyVersion: 2.7
-
-Naming/FileName:
-  Exclude:
-    - spec/**/*.rb
diff --git a/gems/activerecord-gitlab/Gemfile.lock b/gems/activerecord-gitlab/Gemfile.lock
index 021572485939a..b250ae79d4bef 100644
--- a/gems/activerecord-gitlab/Gemfile.lock
+++ b/gems/activerecord-gitlab/Gemfile.lock
@@ -21,24 +21,24 @@ GEM
     ast (2.4.2)
     concurrent-ruby (1.2.2)
     diff-lcs (1.5.0)
-    gitlab-styles (10.0.0)
-      rubocop (~> 1.43.0)
+    gitlab-styles (10.1.0)
+      rubocop (~> 1.50.2)
       rubocop-graphql (~> 0.18)
       rubocop-performance (~> 1.15)
       rubocop-rails (~> 2.17)
-      rubocop-rspec (~> 2.18)
+      rubocop-rspec (~> 2.22)
     i18n (1.13.0)
       concurrent-ruby (~> 1.0)
     json (2.6.3)
     minitest (5.18.0)
-    parallel (1.22.1)
+    parallel (1.23.0)
     parser (3.2.2.3)
       ast (~> 2.4.1)
       racc
-    racc (1.6.2)
-    rack (3.0.4.1)
+    racc (1.7.1)
+    rack (3.0.8)
     rainbow (3.1.1)
-    regexp_parser (2.8.0)
+    regexp_parser (2.8.1)
     rexml (3.2.5)
     rspec (3.12.0)
       rspec-core (~> 3.12.0)
@@ -53,33 +53,36 @@ GEM
       diff-lcs (>= 1.2.0, < 2.0)
       rspec-support (~> 3.12.0)
     rspec-support (3.12.0)
-    rubocop (1.43.0)
+    rubocop (1.50.2)
       json (~> 2.3)
       parallel (~> 1.10)
       parser (>= 3.2.0.0)
       rainbow (>= 2.2.2, < 4.0)
       regexp_parser (>= 1.8, < 3.0)
       rexml (>= 3.2.5, < 4.0)
-      rubocop-ast (>= 1.24.1, < 2.0)
+      rubocop-ast (>= 1.28.0, < 2.0)
       ruby-progressbar (~> 1.7)
       unicode-display_width (>= 2.4.0, < 3.0)
-    rubocop-ast (1.26.0)
+    rubocop-ast (1.29.0)
       parser (>= 3.2.1.0)
-    rubocop-capybara (2.17.0)
+    rubocop-capybara (2.18.0)
       rubocop (~> 1.41)
+    rubocop-factory_bot (2.23.1)
+      rubocop (~> 1.33)
     rubocop-graphql (0.19.0)
       rubocop (>= 0.87, < 2)
-    rubocop-performance (1.16.0)
+    rubocop-performance (1.18.0)
       rubocop (>= 1.7.0, < 2.0)
       rubocop-ast (>= 0.4.0)
-    rubocop-rails (2.17.4)
+    rubocop-rails (2.20.2)
       activesupport (>= 4.2.0)
       rack (>= 1.1)
       rubocop (>= 1.33.0, < 2.0)
-    rubocop-rspec (2.18.1)
+    rubocop-rspec (2.22.0)
       rubocop (~> 1.33)
       rubocop-capybara (~> 2.17)
-    ruby-progressbar (1.11.0)
+      rubocop-factory_bot (~> 2.22)
+    ruby-progressbar (1.13.0)
     tzinfo (2.0.6)
       concurrent-ruby (~> 1.0)
     unicode-display_width (2.4.2)
@@ -90,9 +93,10 @@ PLATFORMS
 
 DEPENDENCIES
   activerecord-gitlab!
-  gitlab-styles (~> 10.0.0)
-  rspec (~> 3.0)
-  rubocop (~> 1.21)
+  gitlab-styles (~> 10.1.0)
+  rspec (~> 3.12)
+  rubocop (~> 1.50)
+  rubocop-rspec (~> 2.22)
 
 BUNDLED WITH
    2.4.14
diff --git a/gems/activerecord-gitlab/activerecord-gitlab.gemspec b/gems/activerecord-gitlab/activerecord-gitlab.gemspec
index 50d0c9a0569f4..36346b04602af 100644
--- a/gems/activerecord-gitlab/activerecord-gitlab.gemspec
+++ b/gems/activerecord-gitlab/activerecord-gitlab.gemspec
@@ -8,19 +8,20 @@ Gem::Specification.new do |spec|
   spec.authors = ["group::tenant-scale"]
   spec.email = ["engineering@gitlab.com"]
 
-  spec.summary = "GitLab's ActiveRecord patches"
+  spec.summary = "GitLab ActiveRecord patches"
   spec.description = "GitLab stores any patches relating to ActiveRecord here"
   spec.homepage = "https://gitlab.com/gitlab-org/gitlab/-/tree/master/gems/activerecord-gitlab"
   spec.license = "MIT"
-  spec.required_ruby_version = ">= 2.7"
+  spec.required_ruby_version = ">= 3.0"
+  spec.metadata["rubygems_mfa_required"] = "true"
 
-  spec.files = Dir['lib/**/*.rb']
-  spec.test_files = Dir['spec/**/*']
+  spec.files = Dir["lib/**/*.rb"]
   spec.require_paths = ["lib"]
 
   spec.add_runtime_dependency "activerecord", ">= 6.1.7.3"
 
-  spec.add_development_dependency "gitlab-styles", "~> 10.0.0"
-  spec.add_development_dependency "rspec", "~> 3.0"
-  spec.add_development_dependency "rubocop", "~> 1.21"
+  spec.add_development_dependency "gitlab-styles", "~> 10.1.0"
+  spec.add_development_dependency "rspec", "~> 3.12"
+  spec.add_development_dependency "rubocop", "~> 1.50"
+  spec.add_development_dependency "rubocop-rspec", "~> 2.22"
 end
diff --git a/gems/config/rubocop.yml b/gems/config/rubocop.yml
new file mode 100644
index 0000000000000..5422348ebeff7
--- /dev/null
+++ b/gems/config/rubocop.yml
@@ -0,0 +1,73 @@
+inherit_gem:
+  gitlab-styles:
+    - rubocop-default.yml
+
+require:
+  - ../../rubocop/rubocop
+  - rubocop-rspec
+
+inherit_mode:
+  merge:
+    - Include
+    - Exclude
+    - AllowedPatterns
+
+AllCops:
+  # Target the current Ruby version. For example, "3.0" or "3.1".
+  TargetRubyVersion: <%= RUBY_VERSION[/^\d+\.\d+/, 0] %>
+
+# This cop doesn't make sense in the context of gems
+CodeReuse/ActiveRecord:
+  Enabled: false
+
+# This cop doesn't make sense in the context of gems
+Cop/PutGroupRoutesUnderScope:
+  Enabled: false
+
+# This cop doesn't make sense in the context of gems
+Cop/PutProjectRoutesUnderScope:
+  Enabled: false
+
+Gemspec/AvoidExecutingGit:
+  Enabled: true
+
+# We disable this since we support multiple Ruby versions
+Gemspec/RequiredRubyVersion:
+  Enabled: false
+
+# This cop doesn't make sense in the context of gems
+Gitlab/DocUrl:
+  Enabled: false
+
+# This cop doesn't make sense in the context of gems
+Gitlab/NamespacedClass:
+  Enabled: false
+
+# This cop doesn't make sense in the context of gems
+Graphql/AuthorizeTypes:
+  Enabled: false
+
+# This cop doesn't make sense in the context of gems
+Graphql/Descriptions:
+  Enabled: false
+
+Naming/FileName:
+  Exclude:
+    - spec/**/*.rb
+
+# This cop doesn't make sense in the context of gems
+RSpec/MissingFeatureCategory:
+  Enabled: false
+
+# Enable once we drop 3.0 support
+Style/HashSyntax:
+  Enabled: false
+
+Style/RegexpLiteralMixedPreserve:
+  Enabled: true
+  SupportedStyles:
+    - slashes
+    - percent_r
+    - mixed
+    - mixed_preserve
+  EnforcedStyle: mixed_preserve
diff --git a/gems/gitlab-rspec/.rubocop.yml b/gems/gitlab-rspec/.rubocop.yml
index b605c30678a1e..8c670b439d3eb 100644
--- a/gems/gitlab-rspec/.rubocop.yml
+++ b/gems/gitlab-rspec/.rubocop.yml
@@ -1,14 +1,2 @@
 inherit_from:
-  - ../../.rubocop.yml
-
-CodeReuse/ActiveRecord:
-  Enabled: false
-
-AllCops:
-  TargetRubyVersion: 3.0
-
-Naming/FileName:
-  Exclude:
-    - spec/**/*.rb
-    - lib/gitlab/rspec.rb
-    - lib/gitlab/rspec/all.rb
+  - ../config/rubocop.yml
diff --git a/gems/gitlab-rspec/Gemfile.lock b/gems/gitlab-rspec/Gemfile.lock
index 6ccdedfe23c43..56c4b01e76441 100644
--- a/gems/gitlab-rspec/Gemfile.lock
+++ b/gems/gitlab-rspec/Gemfile.lock
@@ -43,12 +43,12 @@ GEM
     factory_bot_rails (6.2.0)
       factory_bot (~> 6.2.0)
       railties (>= 5.0.0)
-    gitlab-styles (10.0.0)
-      rubocop (~> 1.43.0)
+    gitlab-styles (10.1.0)
+      rubocop (~> 1.50.2)
       rubocop-graphql (~> 0.18)
       rubocop-performance (~> 1.15)
       rubocop-rails (~> 2.17)
-      rubocop-rspec (~> 2.18)
+      rubocop-rspec (~> 2.22)
     i18n (1.13.0)
       concurrent-ruby (~> 1.0)
     json (2.6.3)
@@ -86,7 +86,7 @@ GEM
       zeitwerk (~> 2.5)
     rainbow (3.1.1)
     rake (13.0.6)
-    regexp_parser (2.8.0)
+    regexp_parser (2.8.1)
     rexml (3.2.5)
     rspec (3.12.0)
       rspec-core (~> 3.12.0)
@@ -125,32 +125,35 @@ GEM
       rspec-mocks (~> 3.12)
       rspec-support (~> 3.12)
     rspec-support (3.12.0)
-    rubocop (1.43.0)
+    rubocop (1.50.2)
       json (~> 2.3)
       parallel (~> 1.10)
       parser (>= 3.2.0.0)
       rainbow (>= 2.2.2, < 4.0)
       regexp_parser (>= 1.8, < 3.0)
       rexml (>= 3.2.5, < 4.0)
-      rubocop-ast (>= 1.24.1, < 2.0)
+      rubocop-ast (>= 1.28.0, < 2.0)
       ruby-progressbar (~> 1.7)
       unicode-display_width (>= 2.4.0, < 3.0)
-    rubocop-ast (1.28.1)
+    rubocop-ast (1.29.0)
       parser (>= 3.2.1.0)
     rubocop-capybara (2.18.0)
       rubocop (~> 1.41)
+    rubocop-factory_bot (2.23.1)
+      rubocop (~> 1.33)
     rubocop-graphql (0.19.0)
       rubocop (>= 0.87, < 2)
     rubocop-performance (1.18.0)
       rubocop (>= 1.7.0, < 2.0)
       rubocop-ast (>= 0.4.0)
-    rubocop-rails (2.19.1)
+    rubocop-rails (2.20.2)
       activesupport (>= 4.2.0)
       rack (>= 1.1)
       rubocop (>= 1.33.0, < 2.0)
-    rubocop-rspec (2.18.1)
+    rubocop-rspec (2.22.0)
       rubocop (~> 1.33)
       rubocop-capybara (~> 2.17)
+      rubocop-factory_bot (~> 2.22)
     ruby-progressbar (1.13.0)
     thor (1.2.2)
     tzinfo (2.0.6)
@@ -167,12 +170,12 @@ PLATFORMS
 DEPENDENCIES
   factory_bot_rails (~> 6.2.0)
   gitlab-rspec!
-  gitlab-styles (~> 10.0.0)
+  gitlab-styles (~> 10.1.0)
   rspec-benchmark (~> 0.6.0)
   rspec-parameterized (~> 1.0)
   rspec-rails (~> 6.0.1)
-  rubocop (~> 1.21)
-  rubocop-rspec (~> 2.18.1)
+  rubocop (~> 1.50)
+  rubocop-rspec (~> 2.22)
 
 BUNDLED WITH
    2.4.4
diff --git a/gems/gitlab-rspec/gitlab-rspec.gemspec b/gems/gitlab-rspec/gitlab-rspec.gemspec
index 2fa17b257ce11..60bc84fbe3620 100644
--- a/gems/gitlab-rspec/gitlab-rspec.gemspec
+++ b/gems/gitlab-rspec/gitlab-rspec.gemspec
@@ -21,10 +21,10 @@ Gem::Specification.new do |spec|
   spec.add_runtime_dependency "rspec", "~> 3.0"
 
   spec.add_development_dependency "factory_bot_rails", "~> 6.2.0"
-  spec.add_development_dependency "gitlab-styles", "~> 10.0.0"
+  spec.add_development_dependency "gitlab-styles", "~> 10.1.0"
   spec.add_development_dependency "rspec-benchmark", "~> 0.6.0"
   spec.add_development_dependency "rspec-parameterized", "~> 1.0"
   spec.add_development_dependency "rspec-rails", "~> 6.0.1"
-  spec.add_development_dependency "rubocop", "~> 1.21"
-  spec.add_development_dependency "rubocop-rspec", "~> 2.18.1"
+  spec.add_development_dependency "rubocop", "~> 1.50"
+  spec.add_development_dependency "rubocop-rspec", "~> 2.22"
 end
diff --git a/gems/gitlab-rspec/lib/gitlab/rspec.rb b/gems/gitlab-rspec/lib/gitlab/rspec.rb
index 3c95a98ba6132..2d076e99614ce 100644
--- a/gems/gitlab-rspec/lib/gitlab/rspec.rb
+++ b/gems/gitlab-rspec/lib/gitlab/rspec.rb
@@ -2,3 +2,8 @@
 
 require "rspec"
 require_relative "rspec/version"
+
+module Gitlab
+  module Rspec
+  end
+end
diff --git a/gems/gitlab-rspec/lib/gitlab/rspec/stub_env.rb b/gems/gitlab-rspec/lib/gitlab/rspec/stub_env.rb
index afa501d627941..f8775d9f7b5ed 100644
--- a/gems/gitlab-rspec/lib/gitlab/rspec/stub_env.rb
+++ b/gems/gitlab-rspec/lib/gitlab/rspec/stub_env.rb
@@ -36,7 +36,7 @@ def add_stubbed_value(key, value)
   end
 
   def env_stubbed?
-    ENV[STUBBED_KEY]
+    ENV.fetch(STUBBED_KEY, false)
   end
 
   def init_stub
diff --git a/gems/gitlab-utils/.rubocop.yml b/gems/gitlab-utils/.rubocop.yml
index 7f0d48d1b2bc3..caaa0787be2dd 100644
--- a/gems/gitlab-utils/.rubocop.yml
+++ b/gems/gitlab-utils/.rubocop.yml
@@ -1,31 +1,31 @@
 inherit_from:
-  - ../../.rubocop.yml
+  - ../config/rubocop.yml
 
-CodeReuse/ActiveRecord:
-  Enabled: false
-
-Gitlab/DocUrl:
-  Enabled: false
-
-Gitlab/NamespacedClass:
-  Enabled: false
-
-AllCops:
-  TargetRubyVersion: 3.0
-
-Naming/FileName:
+RSpec/InstanceVariable:
   Exclude:
     - spec/**/*.rb
-    - lib/gitlab/utils/all.rb
 
-Lint/AmbiguousRegexpLiteral:
+Lint/BinaryOperatorWithIdenticalOperands:
   Exclude:
     - spec/**/*.rb
 
-RSpec/InstanceVariable:
+# We use EnforcedStyle of comparison here due to it being better
+# performing code as seen in https://gitlab.com/gitlab-org/gitlab/-/merge_requests/36221#note_375659681
+Style/NumericPredicate:
+  EnforcedStyle: comparison
+
+# FIXME
+Gitlab/RSpec/AvoidSetup:
+  Enabled: false
+
+# FIXME: When enabled, there's a spec failure in ee/spec/requests/api/graphql/mutations/merge_requests/update_approval_rule_spec.rb:51,
+# due to the `default_value` of `remove_hidden_groups` set to `[]`, most probably instead of `false`, in ee/app/graphql/mutations/merge_requests/update_approval_rule.rb.
+# The problem is that `Object#=~` exists (even though it's deprecated), hence calling it on an `Array` doesn't blow up, but `Array#match?` doesn't exist.
+Performance/RegexpMatch:
   Exclude:
-    - spec/**/*.rb
+    - lib/gitlab/utils.rb
 
-Lint/BinaryOperatorWithIdenticalOperands:
+Rails/OutputSafety:
+  Details: grace period
   Exclude:
-    - spec/**/*.rb
+    - 'lib/gitlab/utils.rb'
diff --git a/gems/gitlab-utils/Gemfile.lock b/gems/gitlab-utils/Gemfile.lock
index e7f954eeea3e8..2a571c9551715 100644
--- a/gems/gitlab-utils/Gemfile.lock
+++ b/gems/gitlab-utils/Gemfile.lock
@@ -55,12 +55,12 @@ GEM
     factory_bot_rails (6.2.0)
       factory_bot (~> 6.2.0)
       railties (>= 5.0.0)
-    gitlab-styles (10.0.0)
-      rubocop (~> 1.43.0)
+    gitlab-styles (10.1.0)
+      rubocop (~> 1.50.2)
       rubocop-graphql (~> 0.18)
       rubocop-performance (~> 1.15)
       rubocop-rails (~> 2.17)
-      rubocop-rspec (~> 2.18)
+      rubocop-rspec (~> 2.22)
     i18n (1.14.1)
       concurrent-ruby (~> 1.0)
     json (2.6.3)
@@ -73,9 +73,10 @@ GEM
     nokogiri (1.15.2)
       mini_portile2 (~> 2.8.2)
       racc (~> 1.4)
-    parallel (1.22.1)
-    parser (3.2.0.0)
+    parallel (1.23.0)
+    parser (3.2.2.3)
       ast (~> 2.4.1)
+      racc
     proc_to_ast (0.1.0)
       coderay
       parser
@@ -100,7 +101,7 @@ GEM
       zeitwerk (~> 2.5)
     rainbow (3.1.1)
     rake (13.0.6)
-    regexp_parser (2.6.0)
+    regexp_parser (2.8.1)
     rexml (3.2.5)
     rspec (3.12.0)
       rspec-core (~> 3.12.0)
@@ -139,33 +140,36 @@ GEM
       rspec-mocks (~> 3.11)
       rspec-support (~> 3.11)
     rspec-support (3.12.0)
-    rubocop (1.43.0)
+    rubocop (1.50.2)
       json (~> 2.3)
       parallel (~> 1.10)
       parser (>= 3.2.0.0)
       rainbow (>= 2.2.2, < 4.0)
       regexp_parser (>= 1.8, < 3.0)
       rexml (>= 3.2.5, < 4.0)
-      rubocop-ast (>= 1.24.1, < 2.0)
+      rubocop-ast (>= 1.28.0, < 2.0)
       ruby-progressbar (~> 1.7)
       unicode-display_width (>= 2.4.0, < 3.0)
-    rubocop-ast (1.24.1)
-      parser (>= 3.1.1.0)
+    rubocop-ast (1.29.0)
+      parser (>= 3.2.1.0)
     rubocop-capybara (2.18.0)
       rubocop (~> 1.41)
+    rubocop-factory_bot (2.23.1)
+      rubocop (~> 1.33)
     rubocop-graphql (0.19.0)
       rubocop (>= 0.87, < 2)
     rubocop-performance (1.18.0)
       rubocop (>= 1.7.0, < 2.0)
       rubocop-ast (>= 0.4.0)
-    rubocop-rails (2.19.1)
+    rubocop-rails (2.20.2)
       activesupport (>= 4.2.0)
       rack (>= 1.1)
       rubocop (>= 1.33.0, < 2.0)
-    rubocop-rspec (2.18.1)
+    rubocop-rspec (2.22.0)
       rubocop (~> 1.33)
       rubocop-capybara (~> 2.17)
-    ruby-progressbar (1.11.0)
+      rubocop-factory_bot (~> 2.22)
+    ruby-progressbar (1.13.0)
     thor (1.2.2)
     tzinfo (2.0.6)
       concurrent-ruby (~> 1.0)
@@ -181,13 +185,14 @@ PLATFORMS
 DEPENDENCIES
   factory_bot_rails (~> 6.2.0)
   gitlab-rspec!
-  gitlab-styles (~> 10.0.0)
+  gitlab-styles (~> 10.1.0)
   gitlab-utils!
+  rspec (~> 3.12)
   rspec-benchmark (~> 0.6.0)
   rspec-parameterized (~> 1.0)
   rspec-rails (~> 6.0.1)
-  rubocop (~> 1.21)
-  rubocop-rspec (~> 2.18.1)
+  rubocop (~> 1.50)
+  rubocop-rspec (~> 2.22)
 
 BUNDLED WITH
    2.4.4
diff --git a/gems/gitlab-utils/gitlab-utils.gemspec b/gems/gitlab-utils/gitlab-utils.gemspec
index ec11ed271e117..d5f6deb7fe6e2 100644
--- a/gems/gitlab-utils/gitlab-utils.gemspec
+++ b/gems/gitlab-utils/gitlab-utils.gemspec
@@ -25,10 +25,11 @@ Gem::Specification.new do |spec|
   spec.add_runtime_dependency "rake", "~> 13.0"
 
   spec.add_development_dependency "factory_bot_rails", "~> 6.2.0"
-  spec.add_development_dependency "gitlab-styles", "~> 10.0.0"
+  spec.add_development_dependency "gitlab-styles", "~> 10.1.0"
+  spec.add_development_dependency "rspec", "~> 3.12"
   spec.add_development_dependency "rspec-benchmark", "~> 0.6.0"
   spec.add_development_dependency "rspec-parameterized", "~> 1.0"
   spec.add_development_dependency "rspec-rails", "~> 6.0.1"
-  spec.add_development_dependency "rubocop", "~> 1.21"
-  spec.add_development_dependency "rubocop-rspec", "~> 2.18.1"
+  spec.add_development_dependency "rubocop", "~> 1.50"
+  spec.add_development_dependency "rubocop-rspec", "~> 2.22"
 end
diff --git a/gems/gitlab-utils/lib/gitlab/version_info.rb b/gems/gitlab-utils/lib/gitlab/version_info.rb
index 0f94aea04adc4..00a9b4ddc6ed4 100644
--- a/gems/gitlab-utils/lib/gitlab/version_info.rb
+++ b/gems/gitlab-utils/lib/gitlab/version_info.rb
@@ -12,13 +12,16 @@ class VersionInfo
     MAX_VERSION_LENGTH = 128
 
     def self.parse(str, parse_suffix: false)
-      if str.is_a?(self)
-        str
-      elsif str && str.length <= MAX_VERSION_LENGTH && m = str.match(VERSION_REGEX)
-        VersionInfo.new(m[1].to_i, m[2].to_i, m[3].to_i, parse_suffix ? m.post_match : nil)
-      else
-        VersionInfo.new
+      return str if str.is_a?(self)
+
+      if str && str.length <= MAX_VERSION_LENGTH
+        match = str.match(VERSION_REGEX)
+        if match
+          return VersionInfo.new(match[1].to_i, match[2].to_i, match[3].to_i, parse_suffix ? match.post_match : nil)
+        end
       end
+
+      VersionInfo.new
     end
 
     def initialize(major = 0, minor = 0, patch = 0, suffix = nil) # rubocop:disable Metrics/ParameterLists
@@ -71,7 +74,7 @@ def to_json(*_args)
 
     def suffix
       @suffix ||= @suffix_s.strip.gsub('-', '.pre.').scan(/\d+|[a-z]+/i).map do |s|
-        /^\d+$/ =~ s ? s.to_i : s
+        /^\d+$/.match?(s) ? s.to_i : s
       end.freeze
     end
 
diff --git a/gems/gitlab-utils/spec/gitlab/utils/strong_memoize_spec.rb b/gems/gitlab-utils/spec/gitlab/utils/strong_memoize_spec.rb
index 05b2568104349..bb0641d9a27d0 100644
--- a/gems/gitlab-utils/spec/gitlab/utils/strong_memoize_spec.rb
+++ b/gems/gitlab-utils/spec/gitlab/utils/strong_memoize_spec.rb
@@ -1,7 +1,5 @@
 # frozen_string_literal: true
 
-# rubocop:disable GitlabSecurity/PublicSend
-
 require 'spec_helper'
 require 'active_support/testing/time_helpers'
 
@@ -23,7 +21,7 @@ def self.method_added(name)
       end
 
       def method_name
-        strong_memoize(:method_name) do # rubocop: disable Gitlab/StrongMemoizeAttr
+        strong_memoize(:method_name) do # rubocop:disable Gitlab/StrongMemoizeAttr
           trace << value
           value
         end
@@ -111,12 +109,12 @@ def public_method; end
         it_behaves_like 'caching the value'
 
         it 'raises exception for invalid type as key' do
-          expect { object.strong_memoize(10) { 20 } }.to raise_error /Invalid type of '10'/
+          expect { object.strong_memoize(10) { 20 } }.to raise_error(/Invalid type of '10'/)
         end
 
         it 'raises exception for invalid characters in key' do
           expect { object.strong_memoize(:enabled?) { 20 } }
-            .to raise_error /is not allowed as an instance variable name/
+            .to raise_error(/is not allowed as an instance variable name/)
         end
       end
     end
@@ -129,7 +127,7 @@ def public_method; end
       end
 
       [:method_name, "method_name"].each do |argument|
-        context "for #{argument.class}" do
+        context "when argument is a #{argument.class}" do
           it 'does allocate exactly one string when fetching value' do
             expect do
               object.strong_memoize(argument) { 10 }
@@ -157,12 +155,12 @@ def public_method; end
         it_behaves_like 'caching the value'
 
         it 'raises exception for invalid type as key' do
-          expect { object.strong_memoize_with_expiration(10, 1) { 20 } }.to raise_error /Invalid type of '10'/
+          expect { object.strong_memoize_with_expiration(10, 1) { 20 } }.to raise_error(/Invalid type of '10'/)
         end
 
         it 'raises exception for invalid characters in key' do
           expect { object.strong_memoize_with_expiration(:enabled?, 1) { 20 } }
-            .to raise_error /is not allowed as an instance variable name/
+            .to raise_error(/is not allowed as an instance variable name/)
         end
       end
     end
@@ -217,19 +215,19 @@ def public_method; end
 
   describe '#strong_memoized?' do
     shared_examples 'memoization check' do |method_name|
-      context "for #{method_name}" do
+      context "when method is :#{method_name}" do
         let(:value) { :anything }
 
         subject { object.strong_memoized?(method_name) }
 
         it 'returns false if the value is uncached' do
-          is_expected.to be(false)
+          expect(subject).to be(false)
         end
 
         it 'returns true if the value is cached' do
           object.public_send(method_name)
 
-          is_expected.to be(true)
+          expect(subject).to be(true)
         end
       end
     end
@@ -309,7 +307,7 @@ def public_method; end
       subject { klass.strong_memoize_attr(:nonexistent_method) }
 
       it 'fails when strong-memoizing a nonexistent method' do
-        expect { subject }.to raise_error(NameError, %r{undefined method `nonexistent_method' for class})
+        expect { subject }.to raise_error(NameError, /undefined method `nonexistent_method' for class/)
       end
     end
 
@@ -355,7 +353,7 @@ def method_with_parameters(params); end
 
       it { is_expected.to eq(output) }
 
-      if params[:valid]
+      if params[:valid] # rubocop:disable RSpec/AvoidConditionalStatements
         it 'is a valid ivar name' do
           expect { instance_variable_defined?(ivar) }.not_to raise_error
         end
@@ -368,5 +366,3 @@ def method_with_parameters(params); end
     end
   end
 end
-
-# rubocop:enable GitlabSecurity/PublicSend
diff --git a/rubocop/cop/background_migration/feature_category.rb b/rubocop/cop/background_migration/feature_category.rb
index c6611a65e49cf..f6b68e0373680 100644
--- a/rubocop/cop/background_migration/feature_category.rb
+++ b/rubocop/cop/background_migration/feature_category.rb
@@ -10,7 +10,7 @@ module BackgroundMigration
       class FeatureCategory < RuboCop::Cop::Base
         include MigrationHelpers
 
-        FEATURE_CATEGORIES_FILE_PATH = "config/feature_categories.yml"
+        FEATURE_CATEGORIES_FILE_PATH = File.expand_path("../../../config/feature_categories.yml", __dir__)
 
         MSG = "'feature_category' should be defined to better assign the ownership for batched migration jobs. " \
               "For more details refer: " \
diff --git a/rubocop/cop/rake/require.rb b/rubocop/cop/rake/require.rb
index e3e1696943dd5..eff0d45fe191a 100644
--- a/rubocop/cop/rake/require.rb
+++ b/rubocop/cop/rake/require.rb
@@ -59,6 +59,8 @@ class Require < RuboCop::Cop::Base
         PATTERN
 
         def on_send(node)
+          return unless in_rake_file?(node)
+
           method, file = require_method(node)
           return unless method
 
@@ -70,6 +72,14 @@ def on_send(node)
 
         private
 
+        def in_rake_file?(node)
+          File.extname(filepath(node)) == '.rake'
+        end
+
+        def filepath(node)
+          node.location.expression.source_buffer.name
+        end
+
         # Allow `require "foo/rake_task"`
         def requires_task?(file)
           file.source.include?('task')
diff --git a/rubocop/cop/usage_data/distinct_count_by_large_foreign_key.rb b/rubocop/cop/usage_data/distinct_count_by_large_foreign_key.rb
index a083318288b03..19f6e393e1f58 100644
--- a/rubocop/cop/usage_data/distinct_count_by_large_foreign_key.rb
+++ b/rubocop/cop/usage_data/distinct_count_by_large_foreign_key.rb
@@ -1,5 +1,7 @@
 # frozen_string_literal: true
 
+require_relative '../../usage_data_helpers'
+
 module RuboCop
   module Cop
     module UsageData
@@ -13,6 +15,8 @@ module UsageData
       #   distinct_count(Ci::Build, :commit_id)
       #
       class DistinctCountByLargeForeignKey < RuboCop::Cop::Base
+        include UsageDataHelpers
+
         MSG = 'Avoid doing `%s` on foreign keys for large tables having above 100 million rows.'
 
         def_node_matcher :distinct_count?, <<-PATTERN
@@ -20,6 +24,8 @@ class DistinctCountByLargeForeignKey < RuboCop::Cop::Base
         PATTERN
 
         def on_send(node)
+          return unless in_usage_data_file?(node)
+
           distinct_count?(node) do |method_name, method_arguments|
             next unless method_arguments && method_arguments.length >= 2
             next if batch_set_to_false?(method_arguments[2])
diff --git a/rubocop/cop/usage_data/histogram_with_large_table.rb b/rubocop/cop/usage_data/histogram_with_large_table.rb
index 35ec568792cfc..0ff3b0b3c81e6 100644
--- a/rubocop/cop/usage_data/histogram_with_large_table.rb
+++ b/rubocop/cop/usage_data/histogram_with_large_table.rb
@@ -1,5 +1,7 @@
 # frozen_string_literal: true
 
+require_relative '../../usage_data_helpers'
+
 module RuboCop
   module Cop
     module UsageData
@@ -12,6 +14,8 @@ module UsageData
       # histogram(Issue, buckets: 1..100)
       # histogram(User.active, buckets: 1..100)
       class HistogramWithLargeTable < RuboCop::Cop::Base
+        include UsageDataHelpers
+
         MSG = 'Avoid histogram method on %{model_name}'
 
         # Match one level const as Issue, Gitlab
@@ -31,6 +35,8 @@ class HistogramWithLargeTable < RuboCop::Cop::Base
         PATTERN
 
         def on_send(node)
+          return unless in_usage_data_file?(node)
+
           one_level_matches = one_level_node(node)
           two_level_matches = two_level_node(node)
 
diff --git a/rubocop/cop/usage_data/instrumentation_superclass.rb b/rubocop/cop/usage_data/instrumentation_superclass.rb
index 601f234058211..80eed19dafa0a 100644
--- a/rubocop/cop/usage_data/instrumentation_superclass.rb
+++ b/rubocop/cop/usage_data/instrumentation_superclass.rb
@@ -1,5 +1,7 @@
 # frozen_string_literal: true
 
+require_relative '../../usage_data_helpers'
+
 module RuboCop
   module Cop
     module UsageData
@@ -17,6 +19,8 @@ module UsageData
       #    # ...
       #  end
       class InstrumentationSuperclass < RuboCop::Cop::Base
+        include UsageDataHelpers
+
         MSG = "Instrumentation classes should subclass one of the following: %{allowed_classes}."
 
         BASE_PATTERN = "(const nil? !#allowed_class?)"
@@ -32,12 +36,16 @@ class InstrumentationSuperclass < RuboCop::Cop::Base
         PATTERN
 
         def on_class(node)
+          return unless in_instrumentation_file?(node)
+
           class_definition(node) do
             register_offense(node.children[1])
           end
         end
 
         def on_send(node)
+          return unless in_instrumentation_file?(node)
+
           class_new_definition(node) do
             register_offense(node.children.last)
           end
diff --git a/rubocop/cop/usage_data/large_table.rb b/rubocop/cop/usage_data/large_table.rb
index 7d50eebaa8311..414c89209ed4e 100644
--- a/rubocop/cop/usage_data/large_table.rb
+++ b/rubocop/cop/usage_data/large_table.rb
@@ -1,9 +1,13 @@
 # frozen_string_literal: true
 
+require_relative '../../usage_data_helpers'
+
 module RuboCop
   module Cop
     module UsageData
       class LargeTable < RuboCop::Cop::Base
+        include UsageDataHelpers
+
         # This cop checks that batch count and distinct_count are used in usage_data.rb files in metrics based on ActiveRecord models.
         #
         # @example
@@ -38,6 +42,8 @@ class LargeTable < RuboCop::Cop::Base
         PATTERN
 
         def on_send(node)
+          return unless in_usage_data_file?(node)
+
           one_level_matches = one_level_node(node)
           two_level_matches = two_level_node(node)
 
diff --git a/rubocop/rubocop-usage-data.yml b/rubocop/rubocop-usage-data.yml
index 129dbc75acf03..033cdb89e7e91 100644
--- a/rubocop/rubocop-usage-data.yml
+++ b/rubocop/rubocop-usage-data.yml
@@ -1,8 +1,5 @@
 UsageData/LargeTable:
   Enabled: true
-  Include:
-    - 'lib/gitlab/usage_data.rb'
-    - 'ee/lib/ee/gitlab/usage_data.rb'
   NonRelatedClasses:
     - :ActionMailer::Base
     - :Date
@@ -41,9 +38,6 @@ UsageData/LargeTable:
     - :maximum
 UsageData/HistogramWithLargeTable:
   Enabled: true
-  Include:
-    - 'lib/gitlab/usage_data.rb'
-    - 'ee/lib/ee/gitlab/usage_data.rb'
   HighTrafficModels: &high_traffic_models # models for all high traffic tables in Migration/UpdateLargeTable
     - 'AuditEvent'
     - 'CommitStatus'
@@ -98,9 +92,6 @@ UsageData/HistogramWithLargeTable:
     - 'WebHookLog'
 UsageData/DistinctCountByLargeForeignKey:
   Enabled: true
-  Include:
-    - 'lib/gitlab/usage_data.rb'
-    - 'ee/lib/ee/gitlab/usage_data.rb'
   AllowedForeignKeys:
     - 'agent_id'
     - 'author_id'
@@ -116,8 +107,6 @@ UsageData/DistinctCountByLargeForeignKey:
     - 'requirement_id'
 UsageData/InstrumentationSuperclass:
   Enabled: true
-  Include:
-    - 'lib/gitlab/usage/metrics/instrumentations/**/*.rb'
   AllowedClasses:
     - :DatabaseMetric
     - :GenericMetric
diff --git a/rubocop/usage_data_helpers.rb b/rubocop/usage_data_helpers.rb
new file mode 100644
index 0000000000000..a625259477845
--- /dev/null
+++ b/rubocop/usage_data_helpers.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module RuboCop
+  module UsageDataHelpers
+    def in_usage_data_file?(node)
+      filepath(node).end_with?('gitlab/usage_data.rb')
+    end
+
+    def in_instrumentation_file?(node)
+      filepath(node).start_with?('lib/gitlab/usage/metrics/instrumentations') && File.extname(filepath(node)) == '.rb'
+    end
+
+    private
+
+    def filepath(node)
+      node.location.expression.source_buffer.name
+    end
+  end
+end
diff --git a/scripts/lint-vendored-gems.sh b/scripts/lint-vendored-gems.sh
deleted file mode 100755
index 2df89043caa6d..0000000000000
--- a/scripts/lint-vendored-gems.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/sh
-
-# Rubocop doesn't have a good way to run excluded files without a separate invocation:
-# https://github.com/rubocop/rubocop/issues/6323
-find gems vendor/gems -name \*.gemspec | xargs bundle exec rubocop --only Gemspec/AvoidExecutingGit
diff --git a/scripts/static-analysis b/scripts/static-analysis
index 0d03dd42c73c7..41583166e041a 100755
--- a/scripts/static-analysis
+++ b/scripts/static-analysis
@@ -51,8 +51,7 @@ class StaticAnalysis
     Task.new(%w[yarn run block-dependencies], 1),
     Task.new(%w[yarn run check-dependencies], 1),
     Task.new(%w[scripts/lint-rugged], 1),
-    Task.new(%w[scripts/gemfile_lock_changed.sh], 1),
-    Task.new(%w[scripts/lint-vendored-gems.sh], 1)
+    Task.new(%w[scripts/gemfile_lock_changed.sh], 1)
   ].compact.freeze
 
   def run_tasks!(options = {})
diff --git a/spec/rubocop/cop/qa/element_with_pattern_spec.rb b/spec/rubocop/cop/qa/element_with_pattern_spec.rb
index 1febdaf9c3bb5..ccc03d7f5ae83 100644
--- a/spec/rubocop/cop/qa/element_with_pattern_spec.rb
+++ b/spec/rubocop/cop/qa/element_with_pattern_spec.rb
@@ -40,7 +40,7 @@
     end
   end
 
-  context 'outside of a migration spec file' do
+  context 'when outside of a QA spec file' do
     it "does not register an offense" do
       expect_no_offenses(<<-RUBY)
         describe 'foo' do
diff --git a/spec/rubocop/cop/rake/require_spec.rb b/spec/rubocop/cop/rake/require_spec.rb
index bb8c6a1f0639f..de484643d6e8a 100644
--- a/spec/rubocop/cop/rake/require_spec.rb
+++ b/spec/rubocop/cop/rake/require_spec.rb
@@ -7,54 +7,84 @@
 RSpec.describe RuboCop::Cop::Rake::Require do
   let(:msg) { described_class::MSG }
 
-  it 'registers an offenses for require methods' do
-    expect_offense(<<~RUBY)
-      require 'json'
-      ^^^^^^^^^^^^^^ #{msg}
-      require_relative 'gitlab/json'
-      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{msg}
-    RUBY
+  describe '#in_rake_file?' do
+    context 'in a Rake file' do
+      let(:node) { double(location: double(expression: double(source_buffer: double(name: 'foo/bar.rake')))) } # rubocop:disable RSpec/VerifiedDoubles
+
+      it { expect(subject.__send__(:in_rake_file?, node)).to be(true) }
+    end
+
+    context 'when outside of a Rake file' do
+      let(:node) { double(location: double(expression: double(source_buffer: double(name: 'foo/bar.rb')))) } # rubocop:disable RSpec/VerifiedDoubles
+
+      it { expect(subject.__send__(:in_rake_file?, node)).to be(false) }
+    end
   end
 
-  it 'does not register offense inside `task` definition' do
-    expect_no_offenses(<<~RUBY)
-      task :parse do
+  context 'in a Rake file' do
+    before do
+      allow(cop).to receive(:in_rake_file?).and_return(true)
+    end
+
+    it 'registers an offenses for require methods' do
+      expect_offense(<<~RUBY)
         require 'json'
-      end
+        ^^^^^^^^^^^^^^ #{msg}
+        require_relative 'gitlab/json'
+        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{msg}
+      RUBY
+    end
 
-      namespace :some do
-        task parse: :env do
-          require_relative 'gitlab/json'
+    it 'does not register offense inside `task` definition' do
+      expect_no_offenses(<<~RUBY)
+        task :parse do
+          require 'json'
         end
-      end
-    RUBY
-  end
 
-  it 'does not register offense inside a block definition' do
-    expect_no_offenses(<<~RUBY)
-      RSpec::Core::RakeTask.new(:parse_json) do |t, args|
-        require 'json'
-      end
-    RUBY
-  end
+        namespace :some do
+          task parse: :env do
+            require_relative 'gitlab/json'
+          end
+        end
+      RUBY
+    end
 
-  it 'does not register offense inside a method definition' do
-    expect_no_offenses(<<~RUBY)
-      def load_deps
-        require 'json'
-      end
+    it 'does not register offense inside a block definition' do
+      expect_no_offenses(<<~RUBY)
+        RSpec::Core::RakeTask.new(:parse_json) do |t, args|
+          require 'json'
+        end
+      RUBY
+    end
+
+    it 'does not register offense inside a method definition' do
+      expect_no_offenses(<<~RUBY)
+        def load_deps
+          require 'json'
+        end
 
-      task :parse do
-        load_deps
-      end
-    RUBY
+        task :parse do
+          load_deps
+        end
+      RUBY
+    end
+
+    it 'does not register offense when require task related files' do
+      expect_no_offenses(<<~RUBY)
+        require 'rubocop/rake_tasks'
+        require 'gettext_i18n_rails/tasks'
+        require_relative '../../rubocop/check_graceful_task'
+      RUBY
+    end
   end
 
-  it 'does not register offense when require task related files' do
-    expect_no_offenses(<<~RUBY)
-      require 'rubocop/rake_tasks'
-      require 'gettext_i18n_rails/tasks'
-      require_relative '../../rubocop/check_graceful_task'
-    RUBY
+  context 'when outside of a Rake file' do
+    before do
+      allow(cop).to receive(:in_rake_file?).and_return(false)
+    end
+
+    it 'registers an offenses for require methods' do
+      expect_no_offenses("require 'json'")
+    end
   end
 end
diff --git a/spec/rubocop/cop/usage_data/distinct_count_by_large_foreign_key_spec.rb b/spec/rubocop/cop/usage_data/distinct_count_by_large_foreign_key_spec.rb
index b4d113a9bccdb..53bf5de624317 100644
--- a/spec/rubocop/cop/usage_data/distinct_count_by_large_foreign_key_spec.rb
+++ b/spec/rubocop/cop/usage_data/distinct_count_by_large_foreign_key_spec.rb
@@ -13,33 +13,45 @@
                         })
   end
 
-  context 'when counting by disallowed key' do
-    it 'registers an offense' do
-      expect_offense(<<~CODE)
-        distinct_count(Issue, :creator_id)
-        ^^^^^^^^^^^^^^ #{msg}
-      CODE
+  context 'in an usage data file' do
+    before do
+      allow(cop).to receive(:in_usage_data_file?).and_return(true)
     end
 
-    it 'does not register an offense when batch is false' do
-      expect_no_offenses('distinct_count(Issue, :creator_id, batch: false)')
+    context 'when counting by disallowed key' do
+      it 'registers an offense' do
+        expect_offense(<<~CODE)
+          distinct_count(Issue, :creator_id)
+          ^^^^^^^^^^^^^^ #{msg}
+        CODE
+      end
+
+      it 'does not register an offense when batch is false' do
+        expect_no_offenses('distinct_count(Issue, :creator_id, batch: false)')
+      end
+
+      it 'registers an offense when batch is true' do
+        expect_offense(<<~CODE)
+          distinct_count(Issue, :creator_id, batch: true)
+          ^^^^^^^^^^^^^^ #{msg}
+        CODE
+      end
     end
 
-    it 'registers an offense when batch is true' do
-      expect_offense(<<~CODE)
-        distinct_count(Issue, :creator_id, batch: true)
-        ^^^^^^^^^^^^^^ #{msg}
-      CODE
-    end
-  end
+    context 'when calling by allowed key' do
+      it 'does not register an offense with symbol' do
+        expect_no_offenses('distinct_count(Issue, :author_id)')
+      end
 
-  context 'when calling by allowed key' do
-    it 'does not register an offense with symbol' do
-      expect_no_offenses('distinct_count(Issue, :author_id)')
+      it 'does not register an offense with string' do
+        expect_no_offenses("distinct_count(Issue, 'merge_requests.target_project_id')")
+      end
     end
+  end
 
-    it 'does not register an offense with string' do
-      expect_no_offenses("distinct_count(Issue, 'merge_requests.target_project_id')")
+  context 'when outside of an usage data file' do
+    it 'does not register an offense' do
+      expect_no_offenses('distinct_count(Issue, :creator_id)')
     end
   end
 end
diff --git a/spec/rubocop/cop/usage_data/histogram_with_large_table_spec.rb b/spec/rubocop/cop/usage_data/histogram_with_large_table_spec.rb
index efa4e27dc9c12..0de14310e1362 100644
--- a/spec/rubocop/cop/usage_data/histogram_with_large_table_spec.rb
+++ b/spec/rubocop/cop/usage_data/histogram_with_large_table_spec.rb
@@ -14,93 +14,105 @@
                         })
   end
 
-  context 'with large tables' do
-    context 'with one-level constants' do
-      context 'when calling histogram(Issue)' do
-        it 'registers an offense' do
-          expect_offense(<<~CODE)
-            histogram(Issue, :project_id, buckets: 1..100)
-            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{msg} Issue
-          CODE
+  context 'in an usage data file' do
+    before do
+      allow(cop).to receive(:in_usage_data_file?).and_return(true)
+    end
+
+    context 'with large tables' do
+      context 'with one-level constants' do
+        context 'when calling histogram(Issue)' do
+          it 'registers an offense' do
+            expect_offense(<<~CODE)
+              histogram(Issue, :project_id, buckets: 1..100)
+              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{msg} Issue
+            CODE
+          end
         end
-      end
 
-      context 'when calling histogram(::Issue)' do
-        it 'registers an offense' do
-          expect_offense(<<~CODE)
-            histogram(::Issue, :project_id, buckets: 1..100)
-            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{msg} Issue
-          CODE
+        context 'when calling histogram(::Issue)' do
+          it 'registers an offense' do
+            expect_offense(<<~CODE)
+              histogram(::Issue, :project_id, buckets: 1..100)
+              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{msg} Issue
+            CODE
+          end
         end
-      end
 
-      context 'when calling histogram(Issue.closed)' do
-        it 'registers an offense' do
-          expect_offense(<<~CODE)
-            histogram(Issue.closed, :project_id, buckets: 1..100)
-            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{msg} Issue
-          CODE
+        context 'when calling histogram(Issue.closed)' do
+          it 'registers an offense' do
+            expect_offense(<<~CODE)
+              histogram(Issue.closed, :project_id, buckets: 1..100)
+              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{msg} Issue
+            CODE
+          end
         end
-      end
 
-      context 'when calling histogram(::Issue.closed)' do
-        it 'registers an offense' do
-          expect_offense(<<~CODE)
-            histogram(::Issue.closed, :project_id, buckets: 1..100)
-            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{msg} Issue
-          CODE
+        context 'when calling histogram(::Issue.closed)' do
+          it 'registers an offense' do
+            expect_offense(<<~CODE)
+              histogram(::Issue.closed, :project_id, buckets: 1..100)
+              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{msg} Issue
+            CODE
+          end
         end
       end
-    end
 
-    context 'with two-level constants' do
-      context 'when calling histogram(::Ci::Build)' do
-        it 'registers an offense' do
-          expect_offense(<<~CODE)
-            histogram(::Ci::Build, buckets: 1..100)
-            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{msg} Ci::Build
-          CODE
+      context 'with two-level constants' do
+        context 'when calling histogram(::Ci::Build)' do
+          it 'registers an offense' do
+            expect_offense(<<~CODE)
+              histogram(::Ci::Build, buckets: 1..100)
+              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{msg} Ci::Build
+            CODE
+          end
         end
-      end
 
-      context 'when calling histogram(::Ci::Build.active)' do
-        it 'registers an offense' do
-          expect_offense(<<~CODE)
-            histogram(::Ci::Build.active, buckets: 1..100)
-            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{msg} Ci::Build
-          CODE
+        context 'when calling histogram(::Ci::Build.active)' do
+          it 'registers an offense' do
+            expect_offense(<<~CODE)
+              histogram(::Ci::Build.active, buckets: 1..100)
+              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{msg} Ci::Build
+            CODE
+          end
         end
-      end
 
-      context 'when calling histogram(Ci::Build)' do
-        it 'registers an offense' do
-          expect_offense(<<~CODE)
-            histogram(Ci::Build, buckets: 1..100)
-            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{msg} Ci::Build
-          CODE
+        context 'when calling histogram(Ci::Build)' do
+          it 'registers an offense' do
+            expect_offense(<<~CODE)
+              histogram(Ci::Build, buckets: 1..100)
+              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{msg} Ci::Build
+            CODE
+          end
         end
-      end
 
-      context 'when calling histogram(Ci::Build.active)' do
-        it 'registers an offense' do
-          expect_offense(<<~CODE)
-            histogram(Ci::Build.active, buckets: 1..100)
-            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{msg} Ci::Build
-          CODE
+        context 'when calling histogram(Ci::Build.active)' do
+          it 'registers an offense' do
+            expect_offense(<<~CODE)
+              histogram(Ci::Build.active, buckets: 1..100)
+              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{msg} Ci::Build
+            CODE
+          end
         end
       end
     end
-  end
 
-  context 'with non related class' do
-    it 'does not register an offense' do
-      expect_no_offenses('histogram(MergeRequest, buckets: 1..100)')
+    context 'with non related class' do
+      it 'does not register an offense' do
+        expect_no_offenses('histogram(MergeRequest, buckets: 1..100)')
+      end
+    end
+
+    context 'with non related method' do
+      it 'does not register an offense' do
+        expect_no_offenses('count(Issue, buckets: 1..100)')
+      end
     end
   end
 
-  context 'with non related method' do
+  context 'when outside of an usage data file' do
     it 'does not register an offense' do
-      expect_no_offenses('count(Issue, buckets: 1..100)')
+      expect_no_offenses('histogram(Issue, :project_id, buckets: 1..100)')
     end
   end
 end
diff --git a/spec/rubocop/cop/usage_data/instrumentation_superclass_spec.rb b/spec/rubocop/cop/usage_data/instrumentation_superclass_spec.rb
index a55f0852f3580..f208a5451cb37 100644
--- a/spec/rubocop/cop/usage_data/instrumentation_superclass_spec.rb
+++ b/spec/rubocop/cop/usage_data/instrumentation_superclass_spec.rb
@@ -14,49 +14,63 @@
                         })
   end
 
-  context 'with class definition' do
-    context 'when inheriting from allowed superclass' do
-      it 'does not register an offense' do
-        expect_no_offenses('class NewMetric < GenericMetric; end')
-      end
+  context 'when in an instrumentation file' do
+    before do
+      allow(cop).to receive(:in_instrumentation_file?).and_return(true)
     end
 
-    context 'when inheriting from some other superclass' do
-      it 'registers an offense' do
-        expect_offense(<<~CODE)
-          class NewMetric < BaseMetric; end
-                            ^^^^^^^^^^ #{msg}
-        CODE
+    context 'with class definition' do
+      context 'when inheriting from allowed superclass' do
+        it 'does not register an offense' do
+          expect_no_offenses('class NewMetric < GenericMetric; end')
+        end
       end
-    end
 
-    context 'when not inheriting' do
-      it 'does not register an offense' do
-        expect_no_offenses('class NewMetric; end')
+      context 'when inheriting from some other superclass' do
+        it 'registers an offense' do
+          expect_offense(<<~CODE)
+            class NewMetric < BaseMetric; end
+                              ^^^^^^^^^^ #{msg}
+          CODE
+        end
       end
-    end
-  end
 
-  context 'with dynamic class definition' do
-    context 'when inheriting from allowed superclass' do
-      it 'does not register an offense' do
-        expect_no_offenses('NewMetric = Class.new(GenericMetric)')
+      context 'when not inheriting' do
+        it 'does not register an offense' do
+          expect_no_offenses('class NewMetric; end')
+        end
       end
     end
 
-    context 'when inheriting from some other superclass' do
-      it 'registers an offense' do
-        expect_offense(<<~CODE)
-          NewMetric = Class.new(BaseMetric)
-                                ^^^^^^^^^^ #{msg}
-        CODE
+    context 'with dynamic class definition' do
+      context 'when inheriting from allowed superclass' do
+        it 'does not register an offense' do
+          expect_no_offenses('NewMetric = Class.new(GenericMetric)')
+        end
       end
-    end
 
-    context 'when not inheriting' do
-      it 'does not register an offense' do
-        expect_no_offenses('NewMetric = Class.new')
+      context 'when inheriting from some other superclass' do
+        it 'registers an offense' do
+          expect_offense(<<~CODE)
+            NewMetric = Class.new(BaseMetric)
+                                  ^^^^^^^^^^ #{msg}
+          CODE
+        end
       end
+
+      context 'when not inheriting' do
+        it 'does not register an offense' do
+          expect_no_offenses('NewMetric = Class.new')
+        end
+      end
+    end
+  end
+
+  context 'when outside of an instrumentation file' do
+    it "does not register an offense" do
+      expect_no_offenses(<<-RUBY)
+        class NewMetric < BaseMetric; end
+      RUBY
     end
   end
 end
diff --git a/spec/rubocop/cop/usage_data/large_table_spec.rb b/spec/rubocop/cop/usage_data/large_table_spec.rb
index fa94f878cea6c..ceeb114369039 100644
--- a/spec/rubocop/cop/usage_data/large_table_spec.rb
+++ b/spec/rubocop/cop/usage_data/large_table_spec.rb
@@ -18,9 +18,9 @@
                         })
   end
 
-  context 'when in usage_data files' do
+  context 'in an usage data file' do
     before do
-      allow(cop).to receive(:usage_data_files?).and_return(true)
+      allow(cop).to receive(:in_usage_data_file?).and_return(true)
     end
 
     context 'with large tables' do
@@ -76,4 +76,10 @@
       end
     end
   end
+
+  context 'when outside of an usage data file' do
+    it 'does not register an offense' do
+      expect_no_offenses('Issue.active.count')
+    end
+  end
 end
-- 
GitLab