Class: TTY::Config
- Inherits:
-
Object
- Object
- TTY::Config
- Includes:
- Marshallers
- Defined in:
- lib/tty/config.rb,
lib/tty/config/version.rb,
lib/tty/config/generator.rb,
lib/tty/config/marshaller.rb,
lib/tty/config/marshallers.rb,
lib/tty/config/dependency_loader.rb,
lib/tty/config/marshaller_registry.rb,
lib/tty/config/marshallers/hcl_marshaller.rb,
lib/tty/config/marshallers/ini_marshaller.rb,
lib/tty/config/marshallers/xml_marshaller.rb,
lib/tty/config/marshallers/json_marshaller.rb,
lib/tty/config/marshallers/toml_marshaller.rb,
lib/tty/config/marshallers/yaml_marshaller.rb,
lib/tty/config/marshallers/java_props_marshaller.rb
Overview
Responsible for managing application configuration
Defined Under Namespace
Modules: DependencyLoader, Generator, Marshaller, Marshallers Classes: MarshallerRegistry
Constant Summary collapse
- DependencyLoadError =
Error raised when failed to load a dependency
Class.new(StandardError)
- ReadError =
Error raised when key fails validation
Class.new(StandardError)
- WriteError =
Error raised when issues writing configuration to a file
Class.new(StandardError)
- UnsupportedExtError =
Erorrr raised when setting unknown file extension
Class.new(StandardError)
- ValidationError =
Error raised when validation assertion fails
Class.new(StandardError)
- VERSION =
"0.6.0"
Constants included from Marshallers
Instance Attribute Summary collapse
-
#env_prefix ⇒ Object
The prefix used for searching ENV variables.
-
#env_separator ⇒ Object
The string used to separate parts in ENV variable name.
-
#extname ⇒ Object
The name of the configuration file extension.
-
#filename ⇒ Object
The name of the configuration file without extension.
-
#key_delim ⇒ Object
readonly
The key delimiter used for specifying deeply nested keys.
-
#location_paths ⇒ Object
readonly
A collection of config paths.
-
#validators ⇒ Object
readonly
The validations for this configuration.
Class Method Summary collapse
-
.coerce(hash, &block) ⇒ TTY::Config
private
Coerce a hash object into Config instance.
-
.normalize_hash(hash, method = :to_sym) ⇒ Hash{Symbol => Object}
private
Convert string keys via method.
Instance Method Summary collapse
-
#alias_setting(*keys, to: nil) ⇒ Object
Define an alias to a nested key.
-
#append(*values, to: nil) ⇒ Array<Object>
Append values to an already existing nested key.
-
#append_path(path) ⇒ Array<String>
Add path to locations to search in.
-
#autoload_env ⇒ Object
Auto load env variables.
-
#autoload_env? ⇒ Boolean
Check if env variables are auto loaded.
-
#delete(*keys) {|key| ... } ⇒ Object
Delete a value from a nested key.
-
#exist? ⇒ Boolean
(also: #persisted?)
Check if configuration file exists.
-
#fetch(*keys, default: nil, &block) ⇒ Object
Fetch value under a composite key.
-
#find_file ⇒ Object
(also: #source_file)
private
Find configuration file matching filename and extension.
-
#initialize(settings = {}) {|_self| ... } ⇒ Config
constructor
Create a configuration instance.
-
#merge(other_settings) ⇒ Hash?
Merge in other configuration settings.
-
#prepend_path(path) ⇒ Array<String>
Insert location path at the begining.
-
#read(file = find_file, format: :auto) ⇒ Object
Find and read a configuration file.
-
#remove(*values, from: nil) ⇒ Object
Remove a set of values from a nested key.
-
#set(*keys, value: nil, &block) ⇒ Object
Set a value for a composite key and overrides any existing keys Keys are case-insensitive.
-
#set_file_metadata(file) ⇒ Object
Set file name and extension.
-
#set_from_env(*keys, &block) ⇒ Object
Bind a key to ENV variable.
-
#set_if_empty(*keys, value: nil, &block) ⇒ Object?
Set a value for a composite key if not present already.
-
#to_env_key(key) ⇒ String
private
Convert config key to standard ENV var name.
-
#to_hash ⇒ Object
(also: #to_h)
Current configuration.
-
#validate(*keys, &validator) ⇒ Object
Register a validation rule for a nested key.
-
#write(file = find_file, create: false, force: false, format: :auto, path: nil) ⇒ Object
Write current configuration to a file.
Methods included from Marshallers
#extensions, #marshaller_registry, #marshallers, #register_marshaller, #registered_marshaller?, #unregister_marshaller
Constructor Details
#initialize(settings = {}) {|_self| ... } ⇒ Config
Create a configuration instance
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/tty/config.rb', line 91 def initialize(settings = {}) @settings = settings @location_paths = [] @validators = {} @filename = "config" @extname = ".yml" @key_delim = "." @envs = {} @env_prefix = "" @env_separator = "_" @autoload_env = false @aliases = {} register_marshaller :yaml, Marshallers::YAMLMarshaller register_marshaller :json, Marshallers::JSONMarshaller register_marshaller :toml, Marshallers::TOMLMarshaller register_marshaller :ini, Marshallers::INIMarshaller register_marshaller :xml, Marshallers::XMLMarshaller register_marshaller :hcl, Marshallers::HCLMarshaller register_marshaller :jprops, Marshallers::JavaPropsMarshaller yield(self) if block_given? end |
Instance Attribute Details
#env_prefix ⇒ Object
The prefix used for searching ENV variables
82 83 84 |
# File 'lib/tty/config.rb', line 82 def env_prefix @env_prefix end |
#env_separator ⇒ Object
The string used to separate parts in ENV variable name
86 87 88 |
# File 'lib/tty/config.rb', line 86 def env_separator @env_separator end |
#extname ⇒ Object
The name of the configuration file extension
74 75 76 |
# File 'lib/tty/config.rb', line 74 def extname @extname end |
#filename ⇒ Object
The name of the configuration file without extension
70 71 72 |
# File 'lib/tty/config.rb', line 70 def filename @filename end |
#key_delim ⇒ Object (readonly)
The key delimiter used for specifying deeply nested keys
66 67 68 |
# File 'lib/tty/config.rb', line 66 def key_delim @key_delim end |
#location_paths ⇒ Object (readonly)
A collection of config paths
62 63 64 |
# File 'lib/tty/config.rb', line 62 def location_paths @location_paths end |
#validators ⇒ Object (readonly)
The validations for this configuration
78 79 80 |
# File 'lib/tty/config.rb', line 78 def validators @validators end |
Class Method Details
.coerce(hash, &block) ⇒ TTY::Config
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Coerce a hash object into Config instance
38 39 40 |
# File 'lib/tty/config.rb', line 38 def self.coerce(hash, &block) new(normalize_hash(hash), &block) end |
.normalize_hash(hash, method = :to_sym) ⇒ Hash{Symbol => Object}
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Convert string keys via method
53 54 55 56 57 58 |
# File 'lib/tty/config.rb', line 53 def self.normalize_hash(hash, method = :to_sym) hash.each_with_object({}) do |(key, val), acc| value = val.is_a?(::Hash) ? normalize_hash(val, method) : val acc[key.public_send(method)] = value end end |
Instance Method Details
#alias_setting(*keys, to: nil) ⇒ Object
Define an alias to a nested key
392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 |
# File 'lib/tty/config.rb', line 392 def alias_setting(*keys, to: nil) flat_setting = flatten_keys(keys) alias_keys = Array(to) alias_key = flatten_keys(alias_keys) if alias_key == flat_setting raise ArgumentError, "Alias matches setting key" end if fetch(alias_key) raise ArgumentError, "Setting already exists with an alias " \ "'#{alias_keys.map(&:inspect).join(', ')}'" end @aliases[alias_key] = flat_setting end |
#append(*values, to: nil) ⇒ Array<Object>
Append values to an already existing nested key
335 336 337 338 |
# File 'lib/tty/config.rb', line 335 def append(*values, to: nil) keys = Array(to) set(*keys, value: Array(fetch(*keys)) + values) end |
#append_path(path) ⇒ Array<String>
Add path to locations to search in
139 140 141 |
# File 'lib/tty/config.rb', line 139 def append_path(path) @location_paths << path end |
#autoload_env ⇒ Object
Auto load env variables
170 171 172 |
# File 'lib/tty/config.rb', line 170 def autoload_env @autoload_env = true end |
#autoload_env? ⇒ Boolean
Check if env variables are auto loaded
163 164 165 |
# File 'lib/tty/config.rb', line 163 def autoload_env? @autoload_env == true end |
#delete(*keys) {|key| ... } ⇒ Object
Delete a value from a nested key
378 379 380 381 |
# File 'lib/tty/config.rb', line 378 def delete(*keys, &default) keys = convert_to_keys(keys) deep_delete(*keys, @settings, &default) end |
#exist? ⇒ Boolean Also known as: persisted?
Check if configuration file exists
441 442 443 |
# File 'lib/tty/config.rb', line 441 def exist? !find_file.nil? end |
#fetch(*keys, default: nil, &block) ⇒ Object
Fetch value under a composite key
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 |
# File 'lib/tty/config.rb', line 285 def fetch(*keys, default: nil, &block) # check alias real_key = @aliases[flatten_keys(keys)] keys = real_key.split(key_delim) if real_key keys = convert_to_keys(keys) env_key = autoload_env? ? to_env_key(keys[0]) : @envs[flatten_keys(keys)] # first try settings value = deep_fetch(@settings, *keys) # then try ENV var if value.nil? && env_key value = ENV[env_key] end # then try default value = block || default if value.nil? while callable_without_params?(value) value = value.() end value end |
#find_file ⇒ Object Also known as: source_file
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Find configuration file matching filename and extension
427 428 429 430 431 432 433 |
# File 'lib/tty/config.rb', line 427 def find_file @location_paths.each do |location_path| path = search_in_path(location_path) return path if path end nil end |
#merge(other_settings) ⇒ Hash?
Merge in other configuration settings
315 316 317 318 319 |
# File 'lib/tty/config.rb', line 315 def merge(other_settings) return unless other_settings.respond_to?(:to_hash) @settings = deep_merge(@settings, other_settings) end |
#prepend_path(path) ⇒ Array<String>
Insert location path at the begining
154 155 156 |
# File 'lib/tty/config.rb', line 154 def prepend_path(path) @location_paths.unshift(path) end |
#read(file = find_file, format: :auto) ⇒ Object
Find and read a configuration file.
If the file doesn’t exist or if there is an error loading it the TTY::Config::ReadError will be raised.
460 461 462 463 464 465 466 467 468 469 470 471 472 473 |
# File 'lib/tty/config.rb', line 460 def read(file = find_file, format: :auto) if file.nil? raise ReadError, "No file found to read configuration from!" elsif !::File.exist?(file) raise ReadError, "Configuration file `#{file}` does not exist!" end (file) ext = (format == :auto ? extname : ".#{format}") content = ::File.read(file) merge(unmarshal(content, ext: ext)) end |
#remove(*values, from: nil) ⇒ Object
Remove a set of values from a nested key
354 355 356 357 358 359 |
# File 'lib/tty/config.rb', line 354 def remove(*values, from: nil) keys = Array(from) raise ArgumentError, "Need to set key to remove from" if keys.empty? set(*keys, value: Array(fetch(*keys)) - values) end |
#set(*keys, value: nil, &block) ⇒ Object
Set a value for a composite key and overrides any existing keys Keys are case-insensitive
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
# File 'lib/tty/config.rb', line 195 def set(*keys, value: nil, &block) assert_either_value_or_block(value, block) keys = convert_to_keys(keys) key = flatten_keys(keys) value_to_eval = block || value if validators.key?(key) if callable_without_params?(value_to_eval) value_to_eval = delay_validation(key, value_to_eval) else assert_valid(key, value) end end deepest_setting = deep_set(@settings, *keys[0...-1]) deepest_setting[keys.last] = value_to_eval deepest_setting[keys.last] end |
#set_file_metadata(file) ⇒ Object
Set file name and extension
517 518 519 520 |
# File 'lib/tty/config.rb', line 517 def (file) self.extname = ::File.extname(file) self.filename = ::File.basename(file, extname) end |
#set_from_env(*keys, &block) ⇒ Object
Bind a key to ENV variable
246 247 248 249 250 251 |
# File 'lib/tty/config.rb', line 246 def set_from_env(*keys, &block) key = flatten_keys(keys) env_key = block.nil? ? key : block.() env_key = to_env_key(env_key) @envs[key.to_s.downcase] = env_key end |
#set_if_empty(*keys, value: nil, &block) ⇒ Object?
Set a value for a composite key if not present already
229 230 231 232 233 234 |
# File 'lib/tty/config.rb', line 229 def set_if_empty(*keys, value: nil, &block) keys = convert_to_keys(keys) return unless deep_fetch(@settings, *keys).nil? block ? set(*keys, &block) : set(*keys, value: value) end |
#to_env_key(key) ⇒ String
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Convert config key to standard ENV var name
260 261 262 263 264 265 266 267 |
# File 'lib/tty/config.rb', line 260 def to_env_key(key) env_key = key.to_s.gsub(key_delim, env_separator).upcase if @env_prefix == "" env_key else "#{@env_prefix.to_s.upcase}#{env_separator}#{env_key}" end end |
#to_hash ⇒ Object Also known as: to_h
Current configuration
525 526 527 |
# File 'lib/tty/config.rb', line 525 def to_hash @settings.dup end |
#validate(*keys, &validator) ⇒ Object
Register a validation rule for a nested key
417 418 419 420 421 422 |
# File 'lib/tty/config.rb', line 417 def validate(*keys, &validator) key = flatten_keys(keys) values = validators[key] || [] values << validator validators[key] = values end |
#write(file = find_file, create: false, force: false, format: :auto, path: nil) ⇒ Object
Write current configuration to a file.
494 495 496 497 498 499 500 501 502 503 504 505 506 |
# File 'lib/tty/config.rb', line 494 def write(file = find_file, create: false, force: false, format: :auto, path: nil) file = fullpath(file, path) check_can_write(file, force) (file) ext = (format == :auto ? extname : ".#{format}") content = marshal(@settings, ext: ext) filepath = Pathname.new(file) create_missing_dirs(filepath, create) ::File.write(filepath, content) end |