diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-12-20 16:37:47 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-12-20 16:37:47 +0300 |
commit | aee0a117a889461ce8ced6fcf73207fe017f1d99 (patch) | |
tree | 891d9ef189227a8445d83f35c1b0fc99573f4380 /config/initializers | |
parent | 8d46af3258650d305f53b819eabf7ab18d22f59e (diff) |
Add latest changes from gitlab-org/gitlab@14-6-stable-eev14.6.0-rc42
Diffstat (limited to 'config/initializers')
-rw-r--r-- | config/initializers/1_settings.rb | 14 | ||||
-rw-r--r-- | config/initializers/7_prometheus_metrics.rb | 20 | ||||
-rw-r--r-- | config/initializers/active_record_database_tasks.rb | 7 | ||||
-rw-r--r-- | config/initializers/active_record_transaction_observer.rb | 4 | ||||
-rw-r--r-- | config/initializers/backtrace_silencers.rb | 4 | ||||
-rw-r--r-- | config/initializers/database_config.rb | 8 | ||||
-rw-r--r-- | config/initializers/doorkeeper_openid_connect.rb | 9 | ||||
-rw-r--r-- | config/initializers/forbid_sidekiq_in_transactions.rb | 8 | ||||
-rw-r--r-- | config/initializers/gitlab_experiment.rb | 2 | ||||
-rw-r--r-- | config/initializers/kaminari_active_record_relation_methods_with_limit.rb | 4 | ||||
-rw-r--r-- | config/initializers/postgres_partitioning.rb | 3 | ||||
-rw-r--r-- | config/initializers/session_store.rb | 45 | ||||
-rw-r--r-- | config/initializers/sidekiq.rb | 5 | ||||
-rw-r--r-- | config/initializers/validate_database_config.rb | 4 | ||||
-rw-r--r-- | config/initializers/wikicloth_patch.rb | 159 |
15 files changed, 244 insertions, 52 deletions
diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb index 8fb2161b14e..6444215421d 100644 --- a/config/initializers/1_settings.rb +++ b/config/initializers/1_settings.rb @@ -690,7 +690,7 @@ Gitlab.ee do Settings.cron_jobs['elastic_migration_worker']['cron'] ||= '*/30 * * * *' Settings.cron_jobs['elastic_migration_worker']['job_class'] ||= 'Elastic::MigrationWorker' Settings.cron_jobs['sync_seat_link_worker'] ||= Settingslogic.new({}) - Settings.cron_jobs['sync_seat_link_worker']['cron'] ||= "#{rand(60)} 3 * * * UTC" + Settings.cron_jobs['sync_seat_link_worker']['cron'] ||= "#{rand(60)} #{rand(3..4)} * * * UTC" Settings.cron_jobs['sync_seat_link_worker']['job_class'] = 'SyncSeatLinkWorker' Settings.cron_jobs['users_create_statistics_worker'] ||= Settingslogic.new({}) Settings.cron_jobs['users_create_statistics_worker']['cron'] ||= '2 15 * * *' @@ -919,11 +919,23 @@ Settings.webpack.dev_server['https'] ||= false # Settings['monitoring'] ||= Settingslogic.new({}) Settings.monitoring['ip_whitelist'] ||= ['127.0.0.1/8'] + Settings.monitoring['sidekiq_exporter'] ||= Settingslogic.new({}) Settings.monitoring.sidekiq_exporter['enabled'] ||= false Settings.monitoring.sidekiq_exporter['log_enabled'] ||= false Settings.monitoring.sidekiq_exporter['address'] ||= 'localhost' Settings.monitoring.sidekiq_exporter['port'] ||= 8082 + +# TODO: Once we split out health checks from SidekiqExporter, we +# should not let this default to the same settings anymore; we only +# do this for back-compat currently. +# https://gitlab.com/gitlab-org/gitlab/-/issues/345804 +Settings.monitoring['sidekiq_health_checks'] ||= Settingslogic.new({}) +Settings.monitoring.sidekiq_health_checks['enabled'] ||= Settings.monitoring.sidekiq_exporter['enabled'] +Settings.monitoring.sidekiq_health_checks['log_enabled'] ||= Settings.monitoring.sidekiq_exporter['log_enabled'] +Settings.monitoring.sidekiq_health_checks['address'] ||= Settings.monitoring.sidekiq_exporter['address'] +Settings.monitoring.sidekiq_health_checks['port'] ||= Settings.monitoring.sidekiq_exporter['port'] + Settings.monitoring['web_exporter'] ||= Settingslogic.new({}) Settings.monitoring.web_exporter['enabled'] ||= false Settings.monitoring.web_exporter['address'] ||= 'localhost' diff --git a/config/initializers/7_prometheus_metrics.rb b/config/initializers/7_prometheus_metrics.rb index 28f3da9b3df..8ef11b83131 100644 --- a/config/initializers/7_prometheus_metrics.rb +++ b/config/initializers/7_prometheus_metrics.rb @@ -28,11 +28,21 @@ Gitlab::Application.configure do |config| config.middleware.insert_after(Labkit::Middleware::Rack, Gitlab::Metrics::RequestsRackMiddleware) end -Sidekiq.configure_server do |config| - config.on(:startup) do - # Do not clean the metrics directory here - the supervisor script should - # have already taken care of that - Gitlab::Metrics::Exporter::SidekiqExporter.instance.start +if Gitlab::Runtime.sidekiq? && (!ENV['SIDEKIQ_WORKER_ID'] || ENV['SIDEKIQ_WORKER_ID'] == '0') + # The single worker outside of a sidekiq-cluster, or the first worker (sidekiq_0) + # in a cluster of processes, is responsible for serving health checks. + # + # Do not clean the metrics directory here - the supervisor script should + # have already taken care of that. + Sidekiq.configure_server do |config| + config.on(:startup) do + # In https://gitlab.com/gitlab-org/gitlab/-/issues/345804 we are looking to + # only serve health-checks from a worker process; for backwards compatibility + # we still go through the metrics exporter server, but start to configure it + # with the new settings keys. + exporter_settings = Settings.monitoring.sidekiq_health_checks + Gitlab::Metrics::Exporter::SidekiqExporter.instance(exporter_settings).start + end end end diff --git a/config/initializers/active_record_database_tasks.rb b/config/initializers/active_record_database_tasks.rb new file mode 100644 index 00000000000..f06174262a9 --- /dev/null +++ b/config/initializers/active_record_database_tasks.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +return unless Gitlab.ee? + +ActiveSupport.on_load(:active_record) do + ActiveRecord::Tasks::DatabaseTasks.singleton_class.prepend(Gitlab::Patch::GeoDatabaseTasks) +end diff --git a/config/initializers/active_record_transaction_observer.rb b/config/initializers/active_record_transaction_observer.rb index fc9b73d656e..a1d4b13344e 100644 --- a/config/initializers/active_record_transaction_observer.rb +++ b/config/initializers/active_record_transaction_observer.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -return unless Gitlab.com? || Gitlab.dev_or_test_env? - def feature_flags_available? # When the DBMS is not available, an exception (e.g. PG::ConnectionBad) is raised active_db_connection = ActiveRecord::Base.connection.active? rescue false @@ -11,6 +9,8 @@ rescue ActiveRecord::NoDatabaseError false end +return unless Gitlab.com? || Gitlab.dev_or_test_env? + Gitlab::Application.configure do if feature_flags_available? && ::Feature.enabled?(:active_record_transactions_tracking, type: :ops, default_enabled: :yaml) Gitlab::Database::Transaction::Observer.register! diff --git a/config/initializers/backtrace_silencers.rb b/config/initializers/backtrace_silencers.rb index 4fd41bd4c75..249b021c680 100644 --- a/config/initializers/backtrace_silencers.rb +++ b/config/initializers/backtrace_silencers.rb @@ -3,8 +3,8 @@ Rails.backtrace_cleaner.remove_silencers! # This allows us to see the proper caller of SQL calls in {development,test}.log -if (Rails.env.development? || Rails.env.test?) && Gitlab.ee? - Rails.backtrace_cleaner.add_silencer { |line| %r(^lib/gitlab/database/load_balancing).match?(line) } +if Rails.env.development? || Rails.env.test? + Rails.backtrace_cleaner.add_silencer { |line| %r{^lib/gitlab/database/load_balancing}.match?(line) } end Rails.backtrace_cleaner.add_silencer { |line| !Gitlab::APP_DIRS_PATTERN.match?(line) } diff --git a/config/initializers/database_config.rb b/config/initializers/database_config.rb index 1eb9d12812a..a3172fae027 100644 --- a/config/initializers/database_config.rb +++ b/config/initializers/database_config.rb @@ -8,11 +8,11 @@ Gitlab.ee do config.geo_database = config_for(:database_geo) end end -end -Gitlab.ee do if Gitlab::Runtime.sidekiq? && Gitlab::Geo.geo_database_configured? - Rails.configuration.geo_database['pool'] = Gitlab::Database.default_pool_size - Geo::TrackingBase.establish_connection(Rails.configuration.geo_database) + # The Geo::TrackingBase model does not yet use connects_to. So, + # this will not properly support geo: from config/databse.yml + # file yet. This is ACK of the current state and will be fixed. + Geo::TrackingBase.establish_connection(Gitlab::Database.geo_db_config_with_default_pool_size) end end diff --git a/config/initializers/doorkeeper_openid_connect.rb b/config/initializers/doorkeeper_openid_connect.rb index 476230d0f70..b2cb1843fab 100644 --- a/config/initializers/doorkeeper_openid_connect.rb +++ b/config/initializers/doorkeeper_openid_connect.rb @@ -59,6 +59,15 @@ Doorkeeper::OpenidConnect.configure do o.claim(:picture) { |user| user.avatar_url(only_path: false) } o.claim(:groups) { |user| user.membership_groups.joins(:route).with_route.map(&:full_path) } o.claim(:groups_direct, response: [:id_token]) { |user| user.groups.joins(:route).with_route.map(&:full_path) } + o.claim('https://gitlab.org/claims/groups/owner') do |user| + user.owned_groups.joins(:route).with_route.map(&:full_path).presence + end + o.claim('https://gitlab.org/claims/groups/maintainer') do |user| + user.maintainers_groups.joins(:route).with_route.map(&:full_path).presence + end + o.claim('https://gitlab.org/claims/groups/developer') do |user| + user.developer_groups.joins(:route).with_route.map(&:full_path).presence + end end end end diff --git a/config/initializers/forbid_sidekiq_in_transactions.rb b/config/initializers/forbid_sidekiq_in_transactions.rb index e5e17672c4e..2ea6c9a7343 100644 --- a/config/initializers/forbid_sidekiq_in_transactions.rb +++ b/config/initializers/forbid_sidekiq_in_transactions.rb @@ -20,7 +20,7 @@ module Sidekiq module NoEnqueueingFromTransactions %i(perform_async perform_at perform_in).each do |name| define_method(name) do |*args| - if !Sidekiq::Worker.skip_transaction_check && ApplicationRecord.inside_transaction? + if !Sidekiq::Worker.skip_transaction_check && inside_transaction? begin raise Sidekiq::Worker::EnqueueFromTransactionError, <<~MSG `#{self}.#{name}` cannot be called inside a transaction as this can lead to @@ -38,6 +38,12 @@ module Sidekiq super(*args) end end + + private + + def inside_transaction? + ::ApplicationRecord.inside_transaction? || ::Ci::ApplicationRecord.inside_transaction? + end end prepend NoEnqueueingFromTransactions diff --git a/config/initializers/gitlab_experiment.rb b/config/initializers/gitlab_experiment.rb index 5582c642b3c..5878b8702b9 100644 --- a/config/initializers/gitlab_experiment.rb +++ b/config/initializers/gitlab_experiment.rb @@ -42,7 +42,7 @@ Gitlab::Experiment.configure do |config| # This behavior doesn't make perfect sense for self managed installs either, # so we don't think we should redirect in those cases. # - valid_domains = %w[about.gitlab.com docs.gitlab.com gitlab.com] + valid_domains = %w[about.gitlab.com docs.gitlab.com gitlab.com gdk.test localhost] config.redirect_url_validator = lambda do |url| Gitlab.dev_env_or_com? && (url = URI.parse(url)) && valid_domains.include?(url.host) rescue URI::InvalidURIError diff --git a/config/initializers/kaminari_active_record_relation_methods_with_limit.rb b/config/initializers/kaminari_active_record_relation_methods_with_limit.rb index 9a5a95403ad..982cb69e532 100644 --- a/config/initializers/kaminari_active_record_relation_methods_with_limit.rb +++ b/config/initializers/kaminari_active_record_relation_methods_with_limit.rb @@ -4,7 +4,6 @@ module Kaminari # Active Record specific page scope methods implementations module ActiveRecordRelationMethodsWithLimit MAX_COUNT_LIMIT = 10_000 - MAX_COUNT_NEW_LOWER_LIMIT = 1_000 # This is a modified version of # https://github.com/kaminari/kaminari/blob/c5186f5d9b7f23299d115408e62047447fd3189d/kaminari-activerecord/lib/kaminari/activerecord/active_record_relation_methods.rb#L17-L41 @@ -22,8 +21,7 @@ module Kaminari return @total_count = (current_page - 1) * limit_value + @records.length if @records.any? && (@records.length < limit_value) end - max_limit = Feature.enabled?(:lower_relation_max_count_limit, type: :ops) ? MAX_COUNT_NEW_LOWER_LIMIT : MAX_COUNT_LIMIT - limit = options.fetch(:limit, max_limit).to_i + limit = options.fetch(:limit, MAX_COUNT_LIMIT).to_i # #count overrides the #select which could include generated columns referenced in #order, so skip #order here, where it's irrelevant to the result anyway c = except(:offset, :limit, :order) # Remove includes only if they are irrelevant diff --git a/config/initializers/postgres_partitioning.rb b/config/initializers/postgres_partitioning.rb index 5af8cf52656..f99333f7c82 100644 --- a/config/initializers/postgres_partitioning.rb +++ b/config/initializers/postgres_partitioning.rb @@ -2,7 +2,8 @@ Gitlab::Database::Partitioning.register_models([ AuditEvent, - WebHookLog + WebHookLog, + LooseForeignKeys::DeletedRecord ]) if Gitlab.ee? diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb index 75328dcd891..bb2e01a30f1 100644 --- a/config/initializers/session_store.rb +++ b/config/initializers/session_store.rb @@ -19,31 +19,22 @@ cookie_key = if Rails.env.development? "_gitlab_session" end -if Gitlab::Utils.to_boolean(ENV['GITLAB_REDIS_STORE_WITH_SESSION_STORE'], default: true) - store = Gitlab::Redis::SharedState.store( - namespace: Gitlab::Redis::SharedState::SESSION_NAMESPACE - ) +store = if Gitlab::Utils.to_boolean(ENV['GITLAB_USE_REDIS_SESSIONS_STORE'], default: true) + Gitlab::Redis::Sessions.store( + namespace: Gitlab::Redis::Sessions::SESSION_NAMESPACE + ) + else + Gitlab::Redis::SharedState.store( + namespace: Gitlab::Redis::Sessions::SESSION_NAMESPACE + ) + end - Gitlab::Application.config.session_store( - :redis_store, # Using the cookie_store would enable session replay attacks. - redis_store: store, - key: cookie_key, - secure: Gitlab.config.gitlab.https, - httponly: true, - expires_in: Settings.gitlab['session_expire_delay'] * 60, - path: Rails.application.config.relative_url_root.presence || '/' - ) -else - sessions_config = Gitlab::Redis::SharedState.params - sessions_config[:namespace] = Gitlab::Redis::SharedState::SESSION_NAMESPACE - - Gitlab::Application.config.session_store( - :redis_store, # Using the cookie_store would enable session replay attacks. - servers: sessions_config, - key: cookie_key, - secure: Gitlab.config.gitlab.https, - httponly: true, - expires_in: Settings.gitlab['session_expire_delay'] * 60, - path: Rails.application.config.relative_url_root.presence || '/' - ) -end +Gitlab::Application.config.session_store( + :redis_store, # Using the cookie_store would enable session replay attacks. + redis_store: store, + key: cookie_key, + secure: Gitlab.config.gitlab.https, + httponly: true, + expires_in: Settings.gitlab['session_expire_delay'] * 60, + path: Rails.application.config.relative_url_root.presence || '/' +) diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb index 23052e7ac57..baf252a5d10 100644 --- a/config/initializers/sidekiq.rb +++ b/config/initializers/sidekiq.rb @@ -29,7 +29,6 @@ use_sidekiq_legacy_memory_killer = !use_sidekiq_daemon_memory_killer Sidekiq.configure_server do |config| config.options[:strict] = false config.options[:queues] = Gitlab::SidekiqConfig.expand_queues(config.options[:queues]) - config.options[:scheduled_enq] = Gitlab::SidekiqEnq Sidekiq.logger.info "Listening on queues #{config.options[:queues].uniq.sort}" @@ -115,5 +114,5 @@ Sidekiq.configure_client do |config| config.client_middleware(&Gitlab::SidekiqMiddleware.client_configurator) end -Sidekiq::Client.prepend Gitlab::Patch::SidekiqClient -Sidekiq::Cron::Poller.prepend Gitlab::Patch::SidekiqCronPoller +Sidekiq::Scheduled::Poller.prepend Gitlab::Patch::SidekiqPoller +Sidekiq::Cron::Poller.prepend Gitlab::Patch::SidekiqPoller diff --git a/config/initializers/validate_database_config.rb b/config/initializers/validate_database_config.rb index a651db8b783..d5e73cdc1ee 100644 --- a/config/initializers/validate_database_config.rb +++ b/config/initializers/validate_database_config.rb @@ -16,11 +16,11 @@ if configurations = ActiveRecord::Base.configurations.configurations "The `main:` database needs to be defined as a first configuration item instead of `#{configurations.first.name}`." end - rejected_config_names = configurations.map(&:name).to_set - Gitlab::Database::DATABASE_NAMES + rejected_config_names = configurations.map(&:name).to_set - Gitlab::Database.all_database_names if rejected_config_names.any? raise "ERROR: This installation of GitLab uses unsupported database names " \ "in 'config/database.yml': #{rejected_config_names.to_a.join(", ")}. The only supported ones are " \ - "#{Gitlab::Database::DATABASE_NAMES.join(", ")}." + "#{Gitlab::Database.all_database_names.join(", ")}." end replicas_config_names = configurations.select(&:replica?).map(&:name) diff --git a/config/initializers/wikicloth_patch.rb b/config/initializers/wikicloth_patch.rb new file mode 100644 index 00000000000..13180180c32 --- /dev/null +++ b/config/initializers/wikicloth_patch.rb @@ -0,0 +1,159 @@ +# frozen_string_literal: true + +require 'wikicloth' +require 'wikicloth/wiki_buffer/var' + +# Adds patch for changes in this PR: https://github.com/nricciar/wikicloth/pull/112/files +# +# That fix has already been merged, but the maintainers are not releasing new versions, so we +# need to patch it here. +# +# If they ever do release a version, then we can remove this file. +# +# See: https://gitlab.com/gitlab-org/gitlab/-/issues/334056#note_745336618 + +# Guard to ensure we remember to delete this patch if they ever release a new version of wikicloth +raise 'New version of WikiCloth detected, please remove this patch' unless Gem::Version.new(WikiCloth::VERSION) == Gem::Version.new('0.8.1') + +# rubocop:disable Style/ClassAndModuleChildren +# rubocop:disable Layout/SpaceAroundEqualsInParameterDefault +# rubocop:disable Style/HashSyntax +# rubocop:disable Layout/SpaceAfterComma +# rubocop:disable Style/RescueStandardError +# rubocop:disable Rails/Output +# rubocop:disable Style/MethodCallWithoutArgsParentheses +# rubocop:disable Layout/EmptyLinesAroundClassBody +# rubocop:disable Metrics/AbcSize +# rubocop:disable Metrics/CyclomaticComplexity +# rubocop:disable Metrics/PerceivedComplexity +# rubocop:disable Cop/LineBreakAroundConditionalBlock +# rubocop:disable Layout/EmptyLineAfterGuardClause +# rubocop:disable Performance/ReverseEach +# rubocop:disable Style/BlockDelimiters +# rubocop:disable Cop/LineBreakAroundConditionalBlock +# rubocop:disable Layout/MultilineBlockLayout +# rubocop:disable Layout/BlockEndNewline +module WikiCloth + class WikiCloth + def render(opt={}) + self.options = { :noedit => false, :locale => I18n.default_locale, :fast => true, :output => :html, :link_handler => self.link_handler, + :params => self.params, :sections => self.sections }.merge(self.options).merge(opt) + self.options[:link_handler].params = options[:params] + + I18n.locale = self.options[:locale] + + data = self.sections.collect { |s| s.render(self.options) }.join + + # This is the first patched line from: + # https://github.com/nricciar/wikicloth/pull/112/files#diff-eed3de11b953105f9181a6859d58f52af8912d28525fd2a289f8be184e66f531R69 + data.gsub!(/<!--.*?-->/m,"") + + data << "\n" if data.last(1) != "\n" + data << "garbage" + + buffer = WikiBuffer.new("",options) + + begin + if self.options[:fast] + until data.empty? + case data + when /\A\w+/ + data = $' + @current_row += $&.length + buffer.add_word($&) + when /\A[^\w]+(\w|)/m + data = $' + $&.each_char { |c| add_current_char(buffer,c) } + end + end + else + data.each_char { |c| add_current_char(buffer,c) } + end + rescue => err + debug_tree = buffer.buffers.collect { |b| b.debug }.join("-->") + puts I18n.t("unknown error on line", :line => @current_line, :row => @current_row, :tree => debug_tree) + raise err + end + + buffer.eof() + buffer.send("to_#{self.options[:output]}") + end + + end + + class WikiBuffer::Var < WikiBuffer + def to_html + return "" if will_not_be_rendered + + if self.is_function? + if Extension.function_exists?(function_name) + return Extension.functions[function_name][:klass].new(@options).instance_exec( params.collect { |p| p.strip }, &Extension.functions[function_name][:block] ).to_s + end + ret = default_functions(function_name,params.collect { |p| p.strip }) + ret ||= @options[:link_handler].function(function_name, params.collect { |p| p.strip }) + ret.to_s + elsif self.is_param? + ret = nil + @options[:buffer].buffers.reverse.each do |b| + ret = b.get_param(params[0],params[1]) if b.instance_of?(WikiBuffer::HTMLElement) && b.element_name == "template" + break unless ret.nil? + end + ret.to_s + else + # put template at beginning of buffer + template_stack = @options[:buffer].buffers.collect { |b| b.get_param("__name") if b.instance_of?(WikiBuffer::HTMLElement) && + b.element_name == "template" }.compact + if template_stack.last == params[0] + debug_tree = @options[:buffer].buffers.collect { |b| b.debug }.join("-->") + "<span class=\"error\">#{I18n.t('template loop detected', :tree => debug_tree)}</span>" + else + key = params[0].to_s.strip + key_options = params[1..].collect { |p| p.is_a?(Hash) ? { :name => p[:name].strip, :value => p[:value].strip } : p.strip } + key_options ||= [] + key_digest = Digest::MD5.hexdigest(key_options.to_a.sort {|x,y| (x.is_a?(Hash) ? x[:name] : x) <=> (y.is_a?(Hash) ? y[:name] : y) }.inspect) + + return @options[:params][key] if @options[:params].has_key?(key) + # if we have a valid cache fragment use it + return @options[:cache][key][key_digest] unless @options[:cache].nil? || @options[:cache][key].nil? || @options[:cache][key][key_digest].nil? + + ret = @options[:link_handler].include_resource(key,key_options).to_s + + # This is the second patched line from: + # https://github.com/nricciar/wikicloth/pull/112/files#diff-f262faf4fadb222cca87185be0fb65b3f49659abc840794cc83a736d41310fb1R83 + ret.gsub!(/<!--.*?-->/m,"") unless ret.frozen? + + count = 0 + tag_attr = key_options.collect { |p| + if p.instance_of?(Hash) + "#{p[:name]}=\"#{p[:value].gsub(/"/,'"')}\"" + else + count += 1 + "#{count}=\"#{p.gsub(/"/,'"')}\"" + end + }.join(" ") + + self.data = ret.blank? ? "" : "<template __name=\"#{key}\" __hash=\"#{key_digest}\" #{tag_attr}>#{ret}</template>" + "" + end + end + end + end +end +# rubocop:enable Style/ClassAndModuleChildren +# rubocop:enable Layout/SpaceAroundEqualsInParameterDefault +# rubocop:enable Style/HashSyntax +# rubocop:enable Layout/SpaceAfterComma +# rubocop:enable Style/RescueStandardError +# rubocop:enable Rails/Output +# rubocop:enable Style/MethodCallWithoutArgsParentheses +# rubocop:enable Layout/EmptyLinesAroundClassBody +# rubocop:enable Metrics/AbcSize +# rubocop:enable Metrics/CyclomaticComplexity +# rubocop:enable Metrics/PerceivedComplexity +# rubocop:enable Cop/LineBreakAroundConditionalBlock +# rubocop:enable Layout/EmptyLineAfterGuardClause +# rubocop:enable Performance/ReverseEach +# rubocop:enable Style/BlockDelimiters +# rubocop:enable Cop/LineBreakAroundConditionalBlock +# rubocop:enable Layout/MultilineBlockLayout +# rubocop:enable Layout/BlockEndNewline |