Class: UltraSettings::Configuration
- Inherits:
-
Object
- Object
- UltraSettings::Configuration
- Includes:
- Singleton
- Defined in:
- lib/ultra_settings/configuration.rb
Constant Summary collapse
- ALLOWED_NAME_PATTERN =
/\A[a-z_][a-zA-Z0-9_]*\z/- ALLOWED_TYPES =
[:string, :symbol, :integer, :float, :boolean, :datetime, :array].freeze
Class Method Summary collapse
-
.configuration_file ⇒ Pathname?
Get the YAML file path.
-
.configuration_file=(value) ⇒ void
Override the default YAML config path.
-
.descendant_configurations ⇒ Array<Class>
Get all descendant configuration classes (subclasses and their subclasses, recursively).
-
.description(text = nil) ⇒ void
Set a description for the configuration.
-
.env_var_delimiter ⇒ String
Get the environment variable delimiter.
-
.env_var_delimiter=(value) ⇒ Object
Set the environment variable delimiter used to construct the environment variable name for a field.
-
.env_var_prefix ⇒ String
Get the environment variable prefix.
-
.env_var_prefix=(value) ⇒ void
Override the default environment variable prefix.
-
.env_var_upcase=(value) ⇒ void
Set to true to upcase the environment variable name for a field.
-
.env_var_upcase? ⇒ Boolean
Check if the environment variable name for a field should be upcased.
-
.environment_variables_disabled=(value) ⇒ void
Set to true to disable loading configuration from environment variables.
-
.environment_variables_disabled? ⇒ Boolean
Check if loading configuration from environment variables is disabled.
-
.field(name, type: :string, description: nil, default: nil, default_if: nil, static: nil, secret: nil, runtime_setting: nil, env_var: nil, yaml_key: nil) ⇒ void
Define a field on the configuration.
-
.fields ⇒ Array<UltraSettings::Field>
List of the defined fields for the configuration.
-
.fields_secret_by_default=(value) ⇒ void
Sets the default value for the secret property of fields.
-
.fields_secret_by_default? ⇒ Boolean
Check if fields are considered secret by default.
-
.include_field?(name) ⇒ Boolean
Check if the field is defined on the configuration.
-
.load_yaml_config ⇒ Hash
Load the YAML file for this configuration and return the values for the current environment.
-
.override!(values, &block) ⇒ Object
Override field values within a block.
-
.runtime_setting_delimiter ⇒ String
Get the runtime setting delimiter.
-
.runtime_setting_delimiter=(value) ⇒ void
Set the runtime setting delimiter used to construct the runtime setting name for a field.
-
.runtime_setting_prefix ⇒ String
Get the runtime setting prefix.
-
.runtime_setting_prefix=(value) ⇒ void
Override the default runtime setting prefix.
-
.runtime_setting_upcase=(value) ⇒ void
Set to true to upcase the runtime setting name for a field.
-
.runtime_setting_upcase? ⇒ Boolean
Check if the runtime setting name for a field should be upcased.
-
.runtime_settings_disabled=(value) ⇒ void
Set to true to disable loading configuration from runtime settings.
-
.runtime_settings_disabled? ⇒ Boolean
Check if loading configuration from runtime settings is disabled.
-
.yaml_config_disabled=(value) ⇒ void
Set to true to disable loading configuration from YAML files.
-
.yaml_config_disabled? ⇒ Boolean
Check if loading configuration from YAML files is disabled.
-
.yaml_config_env ⇒ String
Get the environment namespace used in YAML file name.
-
.yaml_config_env=(value) ⇒ void
Set the environment namespace used in YAML file name.
-
.yaml_config_path ⇒ Pathname?
Get the directory where YAML files will be loaded from.
-
.yaml_config_path=(value) ⇒ void
Set the directory where YAML files will be loaded from.
Instance Method Summary collapse
- #[](name) ⇒ Object
-
#__available_sources__(name) ⇒ Array<Symbol>
Returns an array of the available data sources for the field.
-
#__source__(name) ⇒ Symbol?
Get the current source for the field.
-
#__to_hash__ ⇒ Hash
Output the current state of the configuration as a hash.
-
#__value_from_source__(name, source) ⇒ Object
Get the value of the field from the specified source.
- #include?(name) ⇒ Boolean
-
#initialize ⇒ Configuration
constructor
A new instance of Configuration.
- #override!(values, &block) ⇒ Object
Constructor Details
#initialize ⇒ Configuration
Returns a new instance of Configuration.
493 494 495 496 497 498 |
# File 'lib/ultra_settings/configuration.rb', line 493 def initialize @ultra_settings_mutex = Mutex.new @ultra_settings_memoized_values = {} @ultra_settings_override_values = {} @ultra_settings_yaml_config = nil end |
Class Method Details
.configuration_file ⇒ Pathname?
Get the YAML file path.
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/ultra_settings/configuration.rb', line 181 def configuration_file unless defined?(@configuration_file) default_file = default_configuration_file return nil if default_file.nil? @configuration_file = default_configuration_file end return nil unless @configuration_file path = @configuration_file if path.relative? && yaml_config_path path = yaml_config_path.join(path) end path. end |
.configuration_file=(value) ⇒ void
This method returns an undefined value.
Override the default YAML config path. By default this will be the file matching the underscored name of the class in the configuration directory (i.e. MyServiceConfiguration has a default config path of "my_service.yml").
172 173 174 175 176 |
# File 'lib/ultra_settings/configuration.rb', line 172 def configuration_file=(value) value = nil if value == false value = Pathname.new(value) if value.is_a?(String) @configuration_file = value end |
.descendant_configurations ⇒ Array<Class>
Get all descendant configuration classes (subclasses and their subclasses, recursively).
Note that in Rails development mode this list can include stale classes from previous code reloads; callers that display the results should filter out classes that no longer resolve to a defined constant (see UltraSettings.configurations).
385 386 387 388 |
# File 'lib/ultra_settings/configuration.rb', line 385 def descendant_configurations descendants = DESCENDANTS_MUTEX.synchronize { (@descendants || []).dup } descendants.flat_map { |subclass| [subclass] + subclass.descendant_configurations } end |
.description(text = nil) ⇒ void
This method returns an undefined value.
Set a description for the configuration. This is optional. It will be displayed in the web UI if provided. On large projects with many configurations, this can help identify the purpose of each configuration.
25 26 27 28 |
# File 'lib/ultra_settings/configuration.rb', line 25 def description(text = nil) @description = text.to_s.strip unless text.nil? @description end |
.env_var_delimiter ⇒ String
Get the environment variable delimiter.
253 254 255 |
# File 'lib/ultra_settings/configuration.rb', line 253 def env_var_delimiter get_inheritable_class_attribute(:@env_var_delimiter, "_") end |
.env_var_delimiter=(value) ⇒ Object
Set the environment variable delimiter used to construct the environment variable name for a field. By default this is an underscore.
246 247 248 |
# File 'lib/ultra_settings/configuration.rb', line 246 def env_var_delimiter=(value) set_inheritable_class_attribute(:@env_var_delimiter, value.to_s) end |
.env_var_prefix ⇒ String
Get the environment variable prefix.
138 139 140 141 142 143 |
# File 'lib/ultra_settings/configuration.rb', line 138 def env_var_prefix unless defined?(@env_var_prefix) @env_var_prefix = default_env_var_prefix end @env_var_prefix end |
.env_var_prefix=(value) ⇒ void
This method returns an undefined value.
Override the default environment variable prefix. By default this wil be the underscored name of the class plus an underscore (i.e. MyServiceConfiguration has a prefix of "MY_SERVICE_").
131 132 133 |
# File 'lib/ultra_settings/configuration.rb', line 131 def env_var_prefix=(value) @env_var_prefix = value&.to_s end |
.env_var_upcase=(value) ⇒ void
This method returns an undefined value.
Set to true to upcase the environment variable name for a field. This is true by default.
278 279 280 |
# File 'lib/ultra_settings/configuration.rb', line 278 def env_var_upcase=(value) set_inheritable_class_attribute(:@env_var_upcase, !!value) end |
.env_var_upcase? ⇒ Boolean
Check if the environment variable name for a field should be upcased.
285 286 287 |
# File 'lib/ultra_settings/configuration.rb', line 285 def env_var_upcase? get_inheritable_class_attribute(:@env_var_upcase, true) end |
.environment_variables_disabled=(value) ⇒ void
This method returns an undefined value.
Set to true to disable loading configuration from environment variables.
201 202 203 |
# File 'lib/ultra_settings/configuration.rb', line 201 def environment_variables_disabled=(value) set_inheritable_class_attribute(:@environment_variables_disabled, !!value) end |
.environment_variables_disabled? ⇒ Boolean
Check if loading configuration from environment variables is disabled.
208 209 210 |
# File 'lib/ultra_settings/configuration.rb', line 208 def environment_variables_disabled? get_inheritable_class_attribute(:@environment_variables_disabled, false) end |
.field(name, type: :string, description: nil, default: nil, default_if: nil, static: nil, secret: nil, runtime_setting: nil, env_var: nil, yaml_key: nil) ⇒ void
This method returns an undefined value.
Define a field on the configuration. This will create a getter method for the field. The field value will be read from the environment, runtime settings, or a YAML file and coerced to the specified type. Empty strings will be converted to nil.
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/ultra_settings/configuration.rb', line 60 def field(name, type: :string, description: nil, default: nil, default_if: nil, static: nil, secret: nil, runtime_setting: nil, env_var: nil, yaml_key: nil) name = name.to_s type = type.to_sym static = !!static secret = lambda { fields_secret_by_default? } if secret.nil? unless name.match?(ALLOWED_NAME_PATTERN) raise ArgumentError.new("Invalid name: #{name.inspect}") end unless ALLOWED_TYPES.include?(type) raise ArgumentError.new("Invalid type: #{type.inspect}") end unless default_if.nil? || default_if.is_a?(Proc) || default_if.is_a?(Symbol) raise ArgumentError.new("default_if must be a Proc or Symbol") end defined_fields[name] = Field.new( name: name, type: type, description: description, default: default, default_if: default_if, env_var: construct_env_var(name, env_var), runtime_setting: construct_runtime_setting(name, runtime_setting), yaml_key: construct_yaml_key(name, yaml_key), static: static, secret: secret ) caller_location = caller_locations(1, 1).first class_eval <<~RUBY, caller_location.path, caller_location.lineno # rubocop:disable Security/Eval, Style/EvalWithLocation def #{name} __get_value__(#{name.inspect}) end RUBY if type == :boolean alias_method :"#{name}?", name end end |
.fields ⇒ Array<UltraSettings::Field>
List of the defined fields for the configuration.
106 107 108 |
# File 'lib/ultra_settings/configuration.rb', line 106 def fields defined_fields.values end |
.fields_secret_by_default=(value) ⇒ void
This method returns an undefined value.
Sets the default value for the secret property of fields. Individual fields can still override this value by explicitly setting the secret property. By default, fields are considered secret.
346 347 348 |
# File 'lib/ultra_settings/configuration.rb', line 346 def fields_secret_by_default=(value) set_inheritable_class_attribute(:@fields_secret_by_default, !!value) end |
.fields_secret_by_default? ⇒ Boolean
Check if fields are considered secret by default.
353 354 355 |
# File 'lib/ultra_settings/configuration.rb', line 353 def fields_secret_by_default? get_inheritable_class_attribute(:@fields_secret_by_default, true) end |
.include_field?(name) ⇒ Boolean
Check if the field is defined on the configuration.
114 115 116 117 118 119 120 121 122 123 |
# File 'lib/ultra_settings/configuration.rb', line 114 def include_field?(name) name = name.to_s return true if defined_fields.include?(name) if superclass < Configuration superclass.include_field?(name) else false end end |
.load_yaml_config ⇒ Hash
Load the YAML file for this configuration and return the values for the current environment.
370 371 372 373 374 375 |
# File 'lib/ultra_settings/configuration.rb', line 370 def load_yaml_config return nil unless configuration_file return nil unless configuration_file.exist? && configuration_file.file? YamlConfig.new(configuration_file, yaml_config_env).to_h end |
.override!(values, &block) ⇒ Object
Override field values within a block.
362 363 364 |
# File 'lib/ultra_settings/configuration.rb', line 362 def override!(values, &block) instance.override!(values, &block) end |
.runtime_setting_delimiter ⇒ String
Get the runtime setting delimiter.
269 270 271 |
# File 'lib/ultra_settings/configuration.rb', line 269 def runtime_setting_delimiter get_inheritable_class_attribute(:@runtime_setting_delimiter, ".") end |
.runtime_setting_delimiter=(value) ⇒ void
This method returns an undefined value.
Set the runtime setting delimiter used to construct the runtime setting name for a field. By default this is a dot.
262 263 264 |
# File 'lib/ultra_settings/configuration.rb', line 262 def runtime_setting_delimiter=(value) set_inheritable_class_attribute(:@runtime_setting_delimiter, value.to_s) end |
.runtime_setting_prefix ⇒ String
Get the runtime setting prefix.
158 159 160 161 162 163 |
# File 'lib/ultra_settings/configuration.rb', line 158 def runtime_setting_prefix unless defined?(@runtime_setting_prefix) @runtime_setting_prefix = default_runtime_setting_prefix end @runtime_setting_prefix end |
.runtime_setting_prefix=(value) ⇒ void
This method returns an undefined value.
Override the default runtime setting prefix. By default this wil be the underscored name of the class plus a dot (i.e. MyServiceConfiguration has a prefix of "my_service.").
151 152 153 |
# File 'lib/ultra_settings/configuration.rb', line 151 def runtime_setting_prefix=(value) @runtime_setting_prefix = value&.to_s end |
.runtime_setting_upcase=(value) ⇒ void
This method returns an undefined value.
Set to true to upcase the runtime setting name for a field. This is false by default.
294 295 296 |
# File 'lib/ultra_settings/configuration.rb', line 294 def runtime_setting_upcase=(value) set_inheritable_class_attribute(:@runtime_setting_upcase, !!value) end |
.runtime_setting_upcase? ⇒ Boolean
Check if the runtime setting name for a field should be upcased.
301 302 303 |
# File 'lib/ultra_settings/configuration.rb', line 301 def runtime_setting_upcase? get_inheritable_class_attribute(:@runtime_setting_upcase, false) end |
.runtime_settings_disabled=(value) ⇒ void
This method returns an undefined value.
Set to true to disable loading configuration from runtime settings.
216 217 218 |
# File 'lib/ultra_settings/configuration.rb', line 216 def runtime_settings_disabled=(value) set_inheritable_class_attribute(:@runtime_settings_disabled, !!value) end |
.runtime_settings_disabled? ⇒ Boolean
Check if loading configuration from runtime settings is disabled.
223 224 225 |
# File 'lib/ultra_settings/configuration.rb', line 223 def runtime_settings_disabled? get_inheritable_class_attribute(:@runtime_settings_disabled, false) end |
.yaml_config_disabled=(value) ⇒ void
This method returns an undefined value.
Set to true to disable loading configuration from YAML files.
231 232 233 |
# File 'lib/ultra_settings/configuration.rb', line 231 def yaml_config_disabled=(value) set_inheritable_class_attribute(:@yaml_config_disabled, !!value) end |
.yaml_config_disabled? ⇒ Boolean
Check if loading configuration from YAML files is disabled.
238 239 240 |
# File 'lib/ultra_settings/configuration.rb', line 238 def yaml_config_disabled? get_inheritable_class_attribute(:@yaml_config_disabled, false) || configuration_file.nil? end |
.yaml_config_env ⇒ String
Get the environment namespace used in YAML file name.
336 337 338 |
# File 'lib/ultra_settings/configuration.rb', line 336 def yaml_config_env get_inheritable_class_attribute(:@yaml_config_env, "development") end |
.yaml_config_env=(value) ⇒ void
This method returns an undefined value.
Set the environment namespace used in YAML file name. By default this is "development". Settings from the specific environment hash in the YAML file will be merged with base settings specified in the "shared" hash.
329 330 331 |
# File 'lib/ultra_settings/configuration.rb', line 329 def yaml_config_env=(value) set_inheritable_class_attribute(:@yaml_config_env, value) end |
.yaml_config_path ⇒ Pathname?
Get the directory where YAML files will be loaded from.
319 320 321 |
# File 'lib/ultra_settings/configuration.rb', line 319 def yaml_config_path get_inheritable_class_attribute(:@yaml_config_path, nil) end |
.yaml_config_path=(value) ⇒ void
This method returns an undefined value.
Set the directory where YAML files will be loaded from. By default this is the current working directory.
310 311 312 313 314 |
# File 'lib/ultra_settings/configuration.rb', line 310 def yaml_config_path=(value) value = Pathname.new(value) if value.is_a?(String) value = value. if value&.relative? set_inheritable_class_attribute(:@yaml_config_path, value) end |
Instance Method Details
#[](name) ⇒ Object
500 501 502 |
# File 'lib/ultra_settings/configuration.rb', line 500 def [](name) send(name.to_s) if include?(name) end |
#__available_sources__(name) ⇒ Array<Symbol>
Returns an array of the available data sources for the field.
574 575 576 577 578 579 580 581 582 583 584 |
# File 'lib/ultra_settings/configuration.rb', line 574 def __available_sources__(name) field = self.class.send(:defined_fields)[name.to_s] raise ArgumentError.new("Unknown field: #{name.inspect}") unless field sources = [] sources << :env if field.env_var sources << :settings if __runtime_setting_allowed?(field) sources << :yaml if field.yaml_key && self.class.configuration_file sources << :default unless field.default.nil? sources end |
#__source__(name) ⇒ Symbol?
Get the current source for the field.
539 540 541 542 543 544 545 |
# File 'lib/ultra_settings/configuration.rb', line 539 def __source__(name) field = self.class.send(:defined_fields)[name.to_s] raise ArgumentError.new("Unknown field: #{name.inspect}") unless field source = field.source(env: ENV, settings: UltraSettings.__runtime_settings__, yaml_config: __yaml_config__) source || :default end |
#__to_hash__ ⇒ Hash
Output the current state of the configuration as a hash. If the field is marked as a secret, then the value will be a secure hash of the value instead of the value itself.
The intent of this method is to provide a serializable value that captures the current state of the configuration without exposing any secrets. You could, for instance, use the output to compare the configuration of you application between two different environments.
594 595 596 597 598 599 600 601 602 603 604 |
# File 'lib/ultra_settings/configuration.rb', line 594 def __to_hash__ payload = {} self.class.fields.each do |field| value = self[field.name] if field.secret? && !value.nil? value = "securehash:#{Digest::MD5.hexdigest(Digest::SHA256.hexdigest(value.to_s))}" end payload[field.name] = value end payload end |
#__value_from_source__(name, source) ⇒ Object
Get the value of the field from the specified source.
552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 |
# File 'lib/ultra_settings/configuration.rb', line 552 def __value_from_source__(name, source) field = self.class.send(:defined_fields)[name.to_s] raise ArgumentError.new("Unknown field: #{name.inspect}") unless field case source when :env field.value(env: ENV) when :settings field.value(settings: UltraSettings.__runtime_settings__) when :yaml field.value(yaml_config: __yaml_config__) when :default field.default else raise ArgumentError.new("Unknown source: #{source.inspect}") end end |
#include?(name) ⇒ Boolean
504 505 506 |
# File 'lib/ultra_settings/configuration.rb', line 504 def include?(name) self.class.include_field?(name.to_s) end |
#override!(values, &block) ⇒ Object
508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 |
# File 'lib/ultra_settings/configuration.rb', line 508 def override!(values, &block) thread_id = Thread.current.object_id save_val = @ultra_settings_mutex.synchronize { @ultra_settings_override_values[thread_id] } temp_values = (save_val || {}).dup values.each do |key, value| temp_values[key.to_s] = value end begin @ultra_settings_mutex.synchronize do @ultra_settings_override_values[thread_id] = temp_values end yield ensure @ultra_settings_mutex.synchronize do if save_val.nil? # Remove the key entirely so the hash doesn't accumulate an entry # for every thread that has ever used override!. @ultra_settings_override_values.delete(thread_id) else @ultra_settings_override_values[thread_id] = save_val end end end end |