lib/runger/config.rb in runger_config-4.0.0 vs lib/runger/config.rb in runger_config-5.0.0
- old
+ new
@@ -1,10 +1,10 @@
# frozen_string_literal: true
-require "active_support/all"
-require "runger/optparse_config"
-require "runger/dynamic_config"
+require 'active_support/all'
+require 'runger/dynamic_config'
+require 'runger/optparse_config'
module Runger # :nodoc:
using Runger::Ext::DeepDup
using Runger::Ext::DeepFreeze
using Runger::Ext::Hash
@@ -18,10 +18,12 @@
# Base config class
# Provides `attr_config` method to describe
# configuration parameters and set defaults
class Config
+ include OptparseConfig
+ include DynamicConfig
PARAM_NAME = /^[a-z_](\w+)?$/
# List of names that couldn't be used as config names
# (the class instance methods we use)
RESERVED_NAMES = %i[
@@ -51,13 +53,10 @@
class Error < StandardError; end
class ValidationError < Error; end
- include OptparseConfig
- include DynamicConfig
-
class BlockCallback
attr_reader :block
def initialize(block)
@block = block
@@ -81,77 +80,88 @@
class << self
def attr_config(*args, **hargs)
new_defaults = hargs.deep_dup
new_defaults.stringify_keys!
- defaults.merge! new_defaults
+ defaults.merge!(new_defaults)
new_keys = ((args + new_defaults.keys) - config_attributes)
- validate_param_names! new_keys.map(&:to_s)
+ validate_param_names!(new_keys.map(&:to_s))
new_keys.map!(&:to_sym)
unless (reserved_names = (new_keys & RESERVED_NAMES)).empty?
- raise ArgumentError, "Can not use the following reserved names as config attrubutes: " \
- "#{reserved_names.sort.map(&:to_s).join(", ")}"
+ raise(ArgumentError,
+ 'Can not use the following reserved names as config attrubutes: ' \
+ "#{reserved_names.sort.map(&:to_s).join(', ')}")
end
config_attributes.push(*new_keys)
define_config_accessor(*new_keys)
# Define predicate methods ("param?") for attributes
# having `true` or `false` as default values
new_defaults.each do |key, val|
next unless val.is_a?(TrueClass) || val.is_a?(FalseClass)
- alias_method :"#{key}?", :"#{key}"
+
+ alias_method(:"#{key}?", :"#{key}")
end
end
def defaults
return @defaults if instance_variable_defined?(:@defaults)
- @defaults = if superclass < Runger::Config
- superclass.defaults.deep_dup
- else
- new_empty_config
- end
+ @defaults =
+ if superclass < Runger::Config
+ superclass.defaults.deep_dup
+ else
+ new_empty_config
+ end
end
def config_attributes
return @config_attributes if instance_variable_defined?(:@config_attributes)
- @config_attributes = if superclass < Runger::Config
- superclass.config_attributes.dup
- else
- []
- end
+ @config_attributes =
+ if superclass < Runger::Config
+ superclass.config_attributes.dup
+ else
+ []
+ end
end
def required(*names, env: nil, **nested)
unknown_names = names + nested.keys - config_attributes
- raise ArgumentError, "Unknown config param: #{unknown_names.join(",")}" if unknown_names.any?
+ if unknown_names.any?
+ raise(ArgumentError,
+ "Unknown config param: #{unknown_names.join(',')}")
+ end
return unless Settings.matching_env?(env)
required_attributes.push(*names)
required_attributes.push(*nested.flatten_names)
end
def required_attributes
return @required_attributes if instance_variable_defined?(:@required_attributes)
- @required_attributes = if superclass < Runger::Config
- superclass.required_attributes.dup
- else
- []
- end
+ @required_attributes =
+ if superclass < Runger::Config
+ superclass.required_attributes.dup
+ else
+ []
+ end
end
def on_load(*names, &block)
- raise ArgumentError, "Either methods or block should be specified, not both" if block && !names.empty?
+ if block && !names.empty?
+ raise(ArgumentError,
+ 'Either methods or block should be specified, not both')
+ end
if block
load_callbacks << BlockCallback.new(block)
else
load_callbacks.push(*names.map { NamedCallback.new(_1) })
@@ -159,15 +169,16 @@
end
def load_callbacks
return @load_callbacks if instance_variable_defined?(:@load_callbacks)
- @load_callbacks = if superclass <= Runger::Config
- superclass.load_callbacks.dup
- else
- []
- end
+ @load_callbacks =
+ if superclass <= Runger::Config
+ superclass.load_callbacks.dup
+ else
+ []
+ end
end
def config_name(val = nil)
return (@explicit_config_name = val.to_s) unless val.nil?
@@ -190,50 +201,53 @@
def env_prefix(val = nil)
return (@env_prefix = val.to_s.upcase) unless val.nil?
return @env_prefix if instance_variable_defined?(:@env_prefix)
- @env_prefix = if superclass < Runger::Config && superclass.explicit_config_name?
- superclass.env_prefix
- else
- config_name.upcase
- end
+ @env_prefix =
+ if superclass < Runger::Config && superclass.explicit_config_name?
+ superclass.env_prefix
+ else
+ config_name.upcase
+ end
end
def loader_options(val = nil)
return (@loader_options = val) unless val.nil?
return @loader_options if instance_variable_defined?(:@loader_options)
- @loader_options = if superclass < Runger::Config
- superclass.loader_options
- else
- {}
- end
+ @loader_options =
+ if superclass < Runger::Config
+ superclass.loader_options
+ else
+ {}
+ end
end
def new_empty_config = {}
def coerce_types(mapping)
- Utils.deep_merge!(coercion_mapping, mapping)
+ ::Runger::Utils.deep_merge!(coercion_mapping, mapping)
mapping.each do |key, val|
type = val.is_a?(::Hash) ? val[:type] : val
next if type != :boolean
- alias_method :"#{key}?", :"#{key}"
+ alias_method(:"#{key}?", :"#{key}")
end
end
def coercion_mapping
return @coercion_mapping if instance_variable_defined?(:@coercion_mapping)
- @coercion_mapping = if superclass < Runger::Config
- superclass.coercion_mapping.deep_dup
- else
- {}
- end
+ @coercion_mapping =
+ if superclass < Runger::Config
+ superclass.coercion_mapping.deep_dup
+ else
+ {}
+ end
end
def type_caster(val = nil)
return @type_caster unless val.nil?
@@ -248,26 +262,27 @@
def fallback_type_caster(val = nil)
return (@fallback_type_caster = val) unless val.nil?
return @fallback_type_caster if instance_variable_defined?(:@fallback_type_caster)
- @fallback_type_caster = if superclass < Runger::Config
- superclass.fallback_type_caster.deep_dup
- else
- ::Runger::AutoCast
- end
+ @fallback_type_caster =
+ if superclass < Runger::Config
+ superclass.fallback_type_caster.deep_dup
+ else
+ ::Runger::AutoCast
+ end
end
def disable_auto_cast!
@fallback_type_caster = ::Runger::NoCast
end
private
def define_config_accessor(*names)
names.each do |name|
- accessors_module.module_eval <<~RUBY, __FILE__, __LINE__ + 1
+ accessors_module.module_eval(<<~RUBY, __FILE__, __LINE__ + 1)
def #{name}=(val)
__trace__&.record_value(val, "#{name}", **Tracing.current_trace_source)
values[:#{name}] = val
end
@@ -279,35 +294,37 @@
end
def accessors_module
return @accessors_module if instance_variable_defined?(:@accessors_module)
- @accessors_module = Module.new.tap do |mod|
- include mod
- end
+ @accessors_module =
+ Module.new.tap do |mod|
+ include mod
+ end
end
def build_config_name
unless name
- raise "Please, specify config name explicitly for anonymous class " \
- "via `config_name :my_config`"
+ raise('Please, specify config name explicitly for anonymous class ' \
+ 'via `config_name :my_config`')
end
- unless name.underscore.gsub("/", "_") =~ /(\w+)_config\z/
- raise "Couldn't infer config name, please, specify it explicitly " \
- "via `config_name :my_config`"
+ unless name.underscore.tr('/', '_') =~ /(\w+)_config\z/
+ raise("Couldn't infer config name, please, specify it explicitly " \
+ 'via `config_name :my_config`')
end
- Regexp.last_match[1].delete_suffix("_config").tap(&:downcase!)
+ Regexp.last_match[1].delete_suffix('_config').tap(&:downcase!)
end
def validate_param_names!(names)
- invalid_names = names.reject { |name| name =~ PARAM_NAME }
+ invalid_names = names.grep_v(PARAM_NAME)
return if invalid_names.empty?
- raise ArgumentError, "Invalid attr_config name: #{invalid_names.join(", ")}.\n" \
- "Valid names must satisfy /#{PARAM_NAME.source}/."
+ raise(ArgumentError,
+ "Invalid attr_config name: #{invalid_names.join(', ')}.\n" \
+ "Valid names must satisfy /#{PARAM_NAME.source}/.")
end
end
on_load :validate_required_attributes!
@@ -323,11 +340,11 @@
# my_config = Runger::Config.new({some: :value})
#
def initialize(overrides = nil)
@config_name = self.class.config_name
- raise ArgumentError, "Config name is missing" unless @config_name
+ raise(ArgumentError, 'Config name is missing') unless @config_name
@env_prefix = self.class.env_prefix
@values = {}
load(overrides)
@@ -346,29 +363,30 @@
end
def load(overrides = nil)
base_config = self.class.defaults.deep_dup
- trace = Tracing.capture do
- Tracing.trace!(:defaults) { base_config }
+ trace =
+ Tracing.capture do
+ Tracing.trace!(:defaults) { base_config }
- config_path = resolve_config_path(config_name, env_prefix)
+ config_path = resolve_config_path(config_name, env_prefix)
- load_from_sources(
- base_config,
- name: config_name,
- env_prefix:,
- config_path:,
- **self.class.loader_options
- )
+ load_from_sources(
+ base_config,
+ name: config_name,
+ env_prefix:,
+ config_path:,
+ **self.class.loader_options,
+ )
- if overrides
- Tracing.trace!(:load) { overrides }
+ if overrides
+ Tracing.trace!(:load) { overrides }
- Utils.deep_merge!(base_config, overrides)
+ ::Runger::Utils.deep_merge!(base_config, overrides)
+ end
end
- end
base_config.each do |key, val|
write_config_attr(key.to_sym, val)
end
@@ -383,13 +401,13 @@
@__trace__ = trace
self
end
- def load_from_sources(base_config, **)
+ def load_from_sources(base_config, **options)
Runger.loaders.each do |(_id, loader)|
- Utils.deep_merge!(base_config, loader.call(**))
+ ::Runger::Utils.deep_merge!(base_config, loader.call(**options))
end
base_config
end
def dig(*) = values.dig(*)
@@ -404,32 +422,33 @@
new_config.instance_variable_set(:@values, values.deep_dup)
end
end
def resolve_config_path(name, env_prefix)
- Runger.env.fetch(env_prefix).delete("conf") || Settings.default_config_path.call(name)
+ Runger.env.fetch(env_prefix).delete('conf') || Settings.default_config_path.call(name)
end
def deconstruct_keys(keys) = values.deconstruct_keys(keys)
def to_source_trace = __trace__&.to_h
def inspect
- "#<#{self.class}:0x#{vm_object_id.rjust(16, "0")} config_name=\"#{config_name}\" env_prefix=\"#{env_prefix}\" " \
- "values=#{values.inspect}>"
+ "#<#{self.class}:0x#{vm_object_id.rjust(16,
+ '0')} config_name=\"#{config_name}\" env_prefix=\"#{env_prefix}\" " \
+ "values=#{values.inspect}>"
end
def pretty_print(q)
- q.object_group self do
+ q.object_group(self) do
q.nest(1) do
q.breakable
q.text "config_name=#{config_name.inspect}"
q.breakable
q.text "env_prefix=#{env_prefix.inspect}"
q.breakable
- q.text "values:"
- q.pp __trace__
+ q.text 'values:'
+ q.pp(__trace__)
end
end
end
def as_env
@@ -440,15 +459,16 @@
attr_reader :values, :__trace__
def validate_required_attributes!
self.class.required_attributes.select do |name|
- val = values.dig(*name.to_s.split(".").map(&:to_sym))
+ val = values.dig(*name.to_s.split('.').map(&:to_sym))
val.nil? || (val.is_a?(String) && val.empty?)
end.then do |missing|
next if missing.empty?
- raise_validation_error "The following config parameters for `#{self.class.name}(config_name: #{self.class.config_name})` are missing or empty: #{missing.join(", ")}"
+
+ raise_validation_error("The following config parameters for `#{self.class.name}(config_name: #{self.class.config_name})` are missing or empty: #{missing.join(', ')}")
end
end
def write_config_attr(key, val)
key = key.to_sym
@@ -457,10 +477,10 @@
val = __type_caster__.coerce(key, val)
public_send(:"#{key}=", val)
end
def raise_validation_error(msg)
- raise ValidationError, msg
+ raise(ValidationError, msg)
end
def __type_caster__
self.class.type_caster
end