mirror of
https://gitlab.com/gitlab-org/gitlab-foss.git
synced 2025-08-06 10:19:48 +00:00
108 lines
4.3 KiB
Ruby
108 lines
4.3 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Gitlab
|
|
module Fp
|
|
module Settings
|
|
class DefaultSettingsParser
|
|
# @param [String] module_name
|
|
# @param [Array] requested_setting_names
|
|
# @param [Hash] default_settings
|
|
# @param [Array] mutually_dependent_settings_groups
|
|
# @return [Array<(Hash, Hash)>] settings, setting_types
|
|
# @raise [RuntimeError]
|
|
def self.parse(
|
|
module_name:,
|
|
requested_setting_names:,
|
|
default_settings:,
|
|
mutually_dependent_settings_groups: []
|
|
)
|
|
settings = {}
|
|
setting_types = {}
|
|
|
|
default_settings.each do |setting_name, setting_value_and_type|
|
|
next unless requested_setting_names.include?(setting_name)
|
|
|
|
unless setting_value_and_type.is_a?(Array) && setting_value_and_type.length == 2
|
|
raise "#{module_name} Setting entry for '#{setting_name}' must " \
|
|
"be a two-element array containing the value and type."
|
|
end
|
|
|
|
setting_value, setting_type = setting_value_and_type
|
|
|
|
unless setting_type.is_a?(Class) || setting_type == :Boolean
|
|
raise "#{module_name} Setting type for '#{setting_name}' " \
|
|
"must be a class or :Boolean, but it was a #{setting_type.class}."
|
|
end
|
|
|
|
validate_setting_type(setting_value, setting_type, setting_name, module_name) unless setting_value.nil?
|
|
|
|
settings[setting_name] = setting_value
|
|
setting_types[setting_name] = setting_type
|
|
end
|
|
|
|
mutually_dependent_settings_groups.each do |mutually_dependent_settings|
|
|
validate_mutually_dependent_settings(
|
|
requested_setting_names: requested_setting_names,
|
|
mutually_dependent_settings: mutually_dependent_settings,
|
|
default_setting_names: default_settings.keys
|
|
)
|
|
end
|
|
|
|
[settings, setting_types]
|
|
end
|
|
|
|
# @param [array] requested_setting_names
|
|
# @param [array] mutually_dependent_settings
|
|
# @param [array] default_setting_names
|
|
# @return boolean
|
|
# @raise [RuntimeError]
|
|
def self.validate_mutually_dependent_settings(
|
|
requested_setting_names:,
|
|
mutually_dependent_settings:,
|
|
default_setting_names:
|
|
)
|
|
# No blank line here (satisfies Layout/EmptyLinesAroundMethodBody)
|
|
|
|
if (mutually_dependent_settings - default_setting_names).any?
|
|
raise "Unknown mutually dependent setting(s): " \
|
|
"#{(mutually_dependent_settings - default_setting_names).join(', ')}"
|
|
end
|
|
|
|
at_least_one_mutually_dependent_setting_exists =
|
|
requested_setting_names.intersect?(mutually_dependent_settings)
|
|
|
|
return true unless at_least_one_mutually_dependent_setting_exists
|
|
|
|
both_mutually_dependent_settings_exist =
|
|
(requested_setting_names & mutually_dependent_settings).size == mutually_dependent_settings.size
|
|
|
|
return true if both_mutually_dependent_settings_exist
|
|
|
|
raise "#{mutually_dependent_settings.join(' and ')} " \
|
|
"are mutually dependent and must always be specified together"
|
|
end
|
|
|
|
# @param [Object] setting_value
|
|
# @param [Class, Symbol] setting_type
|
|
# @param [Symbol] setting_name
|
|
# @param [String] module_name
|
|
# @return boolean
|
|
# @raise [RuntimeError]
|
|
def self.validate_setting_type(setting_value, setting_type, setting_name, module_name)
|
|
return true if setting_type == :Boolean && (setting_value == true || setting_value == false)
|
|
|
|
# noinspection RubyMismatchedArgumentType -- RubyMine type checker doesn't recognize guard clause above
|
|
return true if setting_type != :Boolean && setting_value.is_a?(setting_type)
|
|
|
|
# NOTE: We are raising an exception here instead of returning a Result.err, because this is
|
|
# a coding syntax error in the 'default_settings', not a user or data error.
|
|
raise "#{module_name} Setting '#{setting_name}' has a type of '#{setting_value.class}', " \
|
|
"which does not match declared type of '#{setting_type}'."
|
|
end
|
|
|
|
private_class_method :validate_mutually_dependent_settings, :validate_setting_type
|
|
end
|
|
end
|
|
end
|
|
end
|