Module: Gitlab::Utils::Override

Included in:
API::Helpers::Packages::BasicAuthHelpers, API::Helpers::Packages::Maven::BasicAuthHelpers, API::Helpers::Packages::Npm, API::Helpers::PackagesHelpers, AlertManagement::ProcessPrometheusAlertService, Analytics::UsageTrends::CountJobTriggerWorker, Analytics::UsageTrends::CounterJobWorker, Backup::Database, Backup::Files, Backup::Repositories, Banzai::Filter::TaskListFilter, BlocksUnsafeSerialization, Boards::Lists::BaseUpdateService, Ci::Build, Ci::PipelineSchedule, Ci::Processable, Ci::Runner, Commit, ContainerRegistry::DeleteContainerRepositoryWorker, DesignManagement::GitRepository, ExtractsPath, FinderWithCrossProjectAccess, Git::BranchHooksService, AlertManagement::Payload::Prometheus, Analytics::CycleAnalytics::Aggregated::LabelFilter, Analytics::CycleAnalytics::StageEvents::StageEvent, Asciidoc::IncludeProcessor, Auth::Atlassian::IdentityLinker, Auth::Ldap::User, Auth::Saml::IdentityLinker, Auth::Saml::User, BufferedIo, Ci::Config::External::File::Artifact, Ci::Config::External::File::Component, Ci::Config::External::File::Local, Ci::Config::External::File::Project, Ci::Config::Yaml::Tags::Base, Ci::Pipeline::Chain::Limit::Deployments, Ci::ProjectConfig::Repository, Database::AsyncConstraints::Validators::Base, Database::AsyncIndexes::IndexBase, Database::Migrations::PgBackendPid::MigratorPgBackendPid, Diff::FileCollection::MergeRequestDiffBase, Diff::FileCollection::PaginatedDiffs, Email::HtmlToMarkdownParser, ExceptionsApp, Git::RuggedImpl::Blob::ClassMethods, Git::RuggedImpl::Commit, Git::RuggedImpl::Commit::ClassMethods, Git::RuggedImpl::Repository, Git::RuggedImpl::Tree::ClassMethods, GitAccessDesign, GitAccessProject, GitAccessSnippet, GitAccessWiki, Graphql::Subscriptions::ActionCableWithLoadBalancing, HTTPConnectionAdapter, HealthChecks::MasterCheck, ImportExport::DesignRepoRestorer, ImportExport::DesignRepoSaver, ImportExport::WikiRepoSaver, Jira::HttpClient, NetHttpAdapter, Pagination::Keyset::InOperatorOptimization::OrderByColumnData, SidekiqDaemon::Monitor, SidekiqMiddleware::DuplicateJobs::Strategies::DeduplicatesWhenScheduling, SidekiqMiddleware::PauseControl::Strategies::Base, Template::GitlabCiYmlTemplate, Tracking::Destinations::DatabaseEventsSnowplow, Tracking::Destinations::Snowplow, Tracking::Destinations::SnowplowMicro, Gitlab::Usage::Metrics::Instrumentations::MergeRequestWidgetExtensionMetric, Gitlab::UserAccessSnippet, WorkItems::WorkItemHierarchy, GraphqlController, Group, GroupClusterablePresenter, Groups::ChildrenController, Groups::FeatureSetting, GroupsController, Import::BitbucketController, Import::BitbucketServerController, Import::FogbugzController, Import::GiteaController, Import::GithubController, Import::ManifestController, InstanceClusterablePresenter, Integration, Issuable::ImportCsv::BaseService, Issue, IssueLinks::ListService, Issues::BaseService, Issues::MoveService, Issues::PrepareImportCsvService, IssuesFinder, Jira::Requests::Projects::ListService, Ldap::OmniauthCallbacksController, LooseForeignKeys::TurboModificationTracker, Measurable, Member, Members::InviteService, MergeRequest, MergeRequests::BaseService, MergeRequests::MergeToRefService, MergeRequests::UpdateService, MergeRequestsFinder, Note, ObjectStorage::Concern, ObjectStorage::DirectUploadStorage, PersonalAccessToken, Project, ProjectClusterablePresenter, ProjectFeature, ProjectHook, Projects::Alerting::NotifyService, Projects::Analytics::CycleAnalytics::SummaryController, Projects::BlobController, Projects::CycleAnalyticsController, Projects::GitGarbageCollectWorker, Projects::HashedStorage::MigrateAttachmentsService, Projects::NotesController, Projects::RepositoryStorageMove, Projects::ScheduleBulkRepositoryShardMovesService, Projects::Settings::IntegrationHookLogsController, Projects::SnippetsController, Projects::UpdateRepositoryStorageWorker, Projects::WorkItemsController, Resolvers::BaseResolver, Resolvers::IssuesResolver, ServiceHook, SessionsController, Sidebars::Groups::SuperSidebarPanel, Sidebars::Menu, Sidebars::NilMenuItem, Sidebars::Organizations::SuperSidebarPanel, Sidebars::Panel, Sidebars::Projects::SuperSidebarPanel, Snippet, Snippets::RepositoryStorageMove, Snippets::ScheduleBulkRepositoryShardMovesService, Snippets::UpdateRepositoryStorageWorker, Todos::Destroy::ConfidentialIssueService, Todos::Destroy::EntityLeaveService, Todos::Destroy::GroupPrivateService, Todos::Destroy::ProjectPrivateService, Uploads::Fog, UserDetail, Users::AuthorizedBuildService, Users::AuthorizedCreateService, Users::BanService, Users::RegistrationsBuildService, Wiki, Wikis::GitGarbageCollectWorker, WorkItems::CreateService, WorkItems::ImportCsvService, WorkItems::ParentLinks::BaseService, WorkItems::PrepareImportCsvService, WorkItems::RelatedWorkItemLink, WorkItems::RelatedWorkItemLinks::CreateService, WorkItems::UpdateService
Defined in:
lib/gitlab/utils/override.rb

Defined Under Namespace

Classes: Extension

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.extensionsObject



182
183
184
# File 'lib/gitlab/utils/override.rb', line 182

def self.extensions
  @extensions ||= {}
end

.verify!Object



186
187
188
# File 'lib/gitlab/utils/override.rb', line 186

def self.verify!
  extensions.each_value(&:verify!)
end

Instance Method Details

#extended(mod = nil) ⇒ Object



157
158
159
160
161
162
163
164
165
166
167
# File 'lib/gitlab/utils/override.rb', line 157

def extended(mod = nil)
  super

  # Hack to resolve https://gitlab.com/gitlab-org/gitlab/-/issues/23932
  is_not_concern_hack =
    (mod.is_a?(Class) || !name&.end_with?('::ClassMethods'))

  if mod && is_not_concern_hack
    queue_verification(mod.singleton_class)
  end
end

#included(base = nil) ⇒ Object



144
145
146
147
148
# File 'lib/gitlab/utils/override.rb', line 144

def included(base = nil)
  super

  queue_verification(base) if base
end

#method_added(method_name) ⇒ Object



130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/gitlab/utils/override.rb', line 130

def method_added(method_name)
  super

  return unless Gitlab::Environment.static_verification?
  return unless Override.extensions[self]&.verify_override?(method_name)

  method_arity = instance_method(method_name).arity
  if is_a?(Class)
    Extension.verify_class!(self, method_name, method_arity)
  else # We delay the check for modules
    Override.extensions[self].add_method_name(method_name, method_arity)
  end
end

#override(method_name) ⇒ Object

Instead of writing patterns like this:

def f
  raise NotImplementedError unless defined?(super)

  true
end

We could write it like:

extend ::Gitlab::Utils::Override

override :f
def f
  true
end

This would make sure we’re overriding something. See: gitlab.com/gitlab-org/gitlab/issues/1819



123
124
125
126
127
128
# File 'lib/gitlab/utils/override.rb', line 123

def override(method_name)
  return unless Gitlab::Environment.static_verification?

  Override.extensions[self] ||= Extension.new(self)
  Override.extensions[self].add_method_name(method_name)
end

#prepended(base = nil) ⇒ Object



150
151
152
153
154
155
# File 'lib/gitlab/utils/override.rb', line 150

def prepended(base = nil)
  super

  # prepend can override methods, thus we need to verify it like classes
  queue_verification(base, verify: true) if base
end

#queue_verification(base, verify: false) ⇒ Object



169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/gitlab/utils/override.rb', line 169

def queue_verification(base, verify: false)
  return unless Gitlab::Environment.static_verification?

  # We could check for Class in `override`
  # This could be `nil` if `override` was never called.
  # We also force verification for prepend because it can also override
  # a method like a class, but not the cases for include or extend.
  # This includes Rails helpers but not limited to.
  if base.is_a?(Class) || verify
    Override.extensions[self]&.add_class(base)
  end
end