summaryrefslogtreecommitdiff
path: root/lib/gitlab_settings
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-04-25 00:08:36 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2023-04-25 00:08:36 +0000
commit15e5a05bcd3525dd6c046dca2682b04532ba9bd1 (patch)
treed7336c9eab9716f541eb9548d51d4c59ff34aa3c /lib/gitlab_settings
parent3d911c6c1f34df47036f1d7e0838e4d5876ee923 (diff)
downloadgitlab-ce-15e5a05bcd3525dd6c046dca2682b04532ba9bd1.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib/gitlab_settings')
-rw-r--r--lib/gitlab_settings/options.rb80
-rw-r--r--lib/gitlab_settings/settings.rb37
2 files changed, 117 insertions, 0 deletions
diff --git a/lib/gitlab_settings/options.rb b/lib/gitlab_settings/options.rb
new file mode 100644
index 00000000000..b5f86a814e2
--- /dev/null
+++ b/lib/gitlab_settings/options.rb
@@ -0,0 +1,80 @@
+# frozen_string_literal: true
+
+module GitlabSettings
+ class Options
+ # Recursively build GitlabSettings::Options
+ def self.build(obj)
+ case obj
+ when Hash
+ new(obj.transform_values { |value| build(value) })
+ when Array
+ obj.map { |value| build(value) }
+ else
+ obj
+ end
+ end
+
+ def initialize(value)
+ @options = value.deep_stringify_keys
+ end
+
+ def [](key)
+ @options[key.to_s]
+ end
+
+ def []=(key, value)
+ @options[key.to_s] = Options.build(value)
+ end
+
+ def key?(name)
+ @options.key?(name.to_s) || @options.key?(name.to_sym)
+ end
+ alias_method :has_key?, :key?
+
+ def to_hash
+ @options.deep_transform_values do |option|
+ case option
+ when GitlabSettings::Options
+ option.to_hash
+ else
+ option
+ end
+ end
+ end
+ alias_method :to_h, :to_hash
+
+ def merge(other)
+ Options.build(to_hash.merge(other.deep_stringify_keys))
+ end
+
+ def deep_merge(other)
+ Options.build(to_hash.deep_merge(other.deep_stringify_keys))
+ end
+
+ def is_a?(klass)
+ return true if klass == Hash
+
+ super(klass)
+ end
+
+ def method_missing(name, *args, &block)
+ name_string = +name.to_s
+
+ if name_string.chomp!("=")
+ return self[name_string] = args.first if key?(name_string)
+ elsif key?(name_string)
+ return self[name_string]
+ end
+
+ return @options.public_send(name, *args, &block) if @options.respond_to?(name) # rubocop: disable GitlabSecurity/PublicSend
+
+ raise ::GitlabSettings::MissingSetting, "option '#{name}' not defined"
+ end
+
+ def respond_to_missing?(name, include_all = false)
+ return true if key?(name)
+
+ @options.respond_to?(name, include_all)
+ end
+ end
+end
diff --git a/lib/gitlab_settings/settings.rb b/lib/gitlab_settings/settings.rb
new file mode 100644
index 00000000000..79d006fb118
--- /dev/null
+++ b/lib/gitlab_settings/settings.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+module GitlabSettings
+ class Settings
+ attr_reader :source
+
+ def initialize(source, section)
+ raise(ArgumentError, 'config source is required') if source.blank?
+ raise(ArgumentError, 'config section is required') if section.blank?
+
+ @source = source
+ @section = section
+
+ reload!
+ end
+
+ def reload!
+ yaml = ActiveSupport::ConfigurationFile.parse(source)
+ all_configs = yaml.deep_stringify_keys
+ configs = all_configs[section]
+
+ @config = Options.build(configs)
+ end
+
+ def method_missing(name, *args)
+ config.public_send(name, *args) # rubocop: disable GitlabSecurity/PublicSend
+ end
+
+ def respond_to_missing?(name, include_all = false)
+ config.respond_to?(name, include_all)
+ end
+
+ private
+
+ attr_reader :config, :section
+ end
+end