complex_config 0.22.3 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES.md +36 -19
- data/README.md +610 -105
- data/Rakefile +6 -4
- data/VERSION +1 -1
- data/bin/complex_config +31 -1
- data/complex_config.gemspec +4 -3
- data/lib/complex_config/config.rb +46 -1
- data/lib/complex_config/encryption.rb +58 -0
- data/lib/complex_config/errors.rb +88 -0
- data/lib/complex_config/key_source.rb +32 -0
- data/lib/complex_config/provider/shortcuts.rb +34 -0
- data/lib/complex_config/provider.rb +342 -0
- data/lib/complex_config/proxy.rb +32 -0
- data/lib/complex_config/railtie.rb +5 -0
- data/lib/complex_config/settings.rb +374 -2
- data/lib/complex_config/tree.rb +93 -0
- data/lib/complex_config/version.rb +1 -1
- data/lib/complex_config.rb +13 -0
- data/spec/spec_helper.rb +4 -5
- metadata +17 -3
data/Rakefile
CHANGED
@@ -11,10 +11,11 @@ GemHadar do
|
|
11
11
|
description 'This library allows you to access configuration files via a simple interface'
|
12
12
|
executables 'complex_config'
|
13
13
|
test_dir 'spec'
|
14
|
-
ignore '.*.sw[pon]', 'pkg', 'Gemfile.lock', 'coverage',
|
15
|
-
'.AppleDouble', '.DS_Store', 'errors.lst', 'tags'
|
14
|
+
ignore '.*.sw[pon]', 'pkg', 'Gemfile.lock', 'coverage',
|
15
|
+
'.AppleDouble', '.DS_Store', 'errors.lst', 'tags', 'cscope.out', 'doc',
|
16
|
+
'.yardoc'
|
16
17
|
package_ignore '.all_images.yml', '.utilsrc', '.rspec', '.tool-versions',
|
17
|
-
'.gitignore'
|
18
|
+
'.gitignore', '.contexts'
|
18
19
|
|
19
20
|
readme 'README.md'
|
20
21
|
title "#{name.camelize} -- configuration library"
|
@@ -31,7 +32,8 @@ GemHadar do
|
|
31
32
|
development_dependency 'rspec'
|
32
33
|
development_dependency 'monetize'
|
33
34
|
development_dependency 'debug'
|
34
|
-
development_dependency 'all_images',
|
35
|
+
development_dependency 'all_images', '~> 0.8'
|
36
|
+
development_dependency 'context_spook', '~> 0.4'
|
35
37
|
end
|
36
38
|
|
37
39
|
task :default => :spec
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.23.0
|
data/bin/complex_config
CHANGED
@@ -1,4 +1,14 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Complex Config Manager
|
4
|
+
#
|
5
|
+
# A command-line tool for managing encrypted configuration files.
|
6
|
+
#
|
7
|
+
# Features:
|
8
|
+
# - Edit, encrypt, decrypt, and display configuration files
|
9
|
+
# - Generate new encryption keys
|
10
|
+
# - Re-encrypt files with different keys
|
11
|
+
# - Secure file operations to prevent data corruption
|
2
12
|
|
3
13
|
require 'complex_config/rude'
|
4
14
|
require 'tins/xt'
|
@@ -9,6 +19,14 @@ include FileUtils
|
|
9
19
|
|
10
20
|
$opts = go 'o:n:h'
|
11
21
|
|
22
|
+
# The usage method displays help information and exits the program
|
23
|
+
#
|
24
|
+
# This method outputs a formatted help message to the standard output,
|
25
|
+
# including usage instructions, available commands, and options. It then
|
26
|
+
# terminates the program with the specified exit code.
|
27
|
+
#
|
28
|
+
# @param msg [String] the help message to display
|
29
|
+
# @param rc [Integer] the exit code to use when terminating the program
|
12
30
|
def usage(msg: 'Displaying help', rc: 0)
|
13
31
|
puts <<~end
|
14
32
|
#{msg}
|
@@ -32,6 +50,15 @@ def usage(msg: 'Displaying help', rc: 0)
|
|
32
50
|
exit rc
|
33
51
|
end
|
34
52
|
|
53
|
+
# The fetch_filename method processes and validates a configuration filename
|
54
|
+
#
|
55
|
+
# This method retrieves a filename from the command line arguments, verifies
|
56
|
+
# its existence, and optionally ensures it has the correct file extension
|
57
|
+
# suffix. It handles validation for encrypted configuration files and provides
|
58
|
+
# appropriate error messages when requirements are not met.
|
59
|
+
#
|
60
|
+
# @param suffix [TrueClass, FalseClass] whether to validate or remove the .enc suffix
|
61
|
+
# @return [String] the validated filename without the .enc suffix if requested
|
35
62
|
def fetch_filename(suffix: true)
|
36
63
|
fn = ARGV.shift.dup or usage msg: "config filename required", rc: 1
|
37
64
|
if suffix
|
@@ -105,7 +132,10 @@ when 'recrypt'
|
|
105
132
|
f.write(recrypted_text)
|
106
133
|
mv encrypted_fn + '.enc', encrypted_fn + '.enc.bak'
|
107
134
|
end
|
108
|
-
puts
|
135
|
+
puts <<~EOT
|
136
|
+
File was recrypted as #{(encrypted_fn + '.enc').inspect}.
|
137
|
+
You can remove #{(encrypted_fn + '.enc.bak').inspect} now.
|
138
|
+
EOT
|
109
139
|
else
|
110
140
|
usage msg: "Unknown command #{command.inspect}", rc: 1
|
111
141
|
end
|
data/complex_config.gemspec
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
# stub: complex_config 0.
|
2
|
+
# stub: complex_config 0.23.0 ruby lib
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "complex_config".freeze
|
6
|
-
s.version = "0.
|
6
|
+
s.version = "0.23.0".freeze
|
7
7
|
|
8
8
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
9
9
|
s.require_paths = ["lib".freeze]
|
@@ -23,13 +23,14 @@ Gem::Specification.new do |s|
|
|
23
23
|
|
24
24
|
s.specification_version = 4
|
25
25
|
|
26
|
-
s.add_development_dependency(%q<gem_hadar>.freeze, ["~> 2.
|
26
|
+
s.add_development_dependency(%q<gem_hadar>.freeze, ["~> 2.6".freeze])
|
27
27
|
s.add_development_dependency(%q<rake>.freeze, [">= 0".freeze])
|
28
28
|
s.add_development_dependency(%q<simplecov>.freeze, [">= 0".freeze])
|
29
29
|
s.add_development_dependency(%q<rspec>.freeze, [">= 0".freeze])
|
30
30
|
s.add_development_dependency(%q<monetize>.freeze, [">= 0".freeze])
|
31
31
|
s.add_development_dependency(%q<debug>.freeze, [">= 0".freeze])
|
32
32
|
s.add_development_dependency(%q<all_images>.freeze, ["~> 0.8".freeze])
|
33
|
+
s.add_development_dependency(%q<context_spook>.freeze, ["~> 0.4".freeze])
|
33
34
|
s.add_runtime_dependency(%q<json>.freeze, [">= 0".freeze])
|
34
35
|
s.add_runtime_dependency(%q<tins>.freeze, ["~> 1".freeze])
|
35
36
|
s.add_runtime_dependency(%q<mize>.freeze, ["~> 0.6".freeze])
|
@@ -1,10 +1,39 @@
|
|
1
1
|
module ComplexConfig
|
2
|
-
|
2
|
+
# Configuration class for setting up ComplexConfig behavior
|
3
|
+
#
|
4
|
+
# This class provides a structured way to configure the ComplexConfig system,
|
5
|
+
# including environment settings, deep freezing behavior, and plugin registration.
|
6
|
+
#
|
7
|
+
# @example Basic configuration
|
8
|
+
# ComplexConfig.configure do |config|
|
9
|
+
# config.deep_freeze = false
|
10
|
+
# config.env = 'production'
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# @example Adding custom plugins
|
14
|
+
# ComplexConfig.configure do |config|
|
15
|
+
# config.add_plugin -> id do
|
16
|
+
# if base64_string = ask_and_send("#{id}_base64")
|
17
|
+
# Base64.decode64(base64_string)
|
18
|
+
# else
|
19
|
+
# skip
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
# end
|
23
|
+
class Config < Struct.new(:config_dir, :env, :deep_freeze, :plugins)
|
24
|
+
# Initializes a new configuration instance
|
3
25
|
def initialize(*)
|
4
26
|
super
|
5
27
|
self.plugins = []
|
6
28
|
end
|
7
29
|
|
30
|
+
# Applies the configuration to a provider
|
31
|
+
#
|
32
|
+
# This method sets all configuration attributes on the provider and
|
33
|
+
# registers any plugins. It's called internally by ComplexConfig.configure.
|
34
|
+
#
|
35
|
+
# @param provider [ComplexConfig::Provider] The provider to configure
|
36
|
+
# @return [self] Returns self for chaining
|
8
37
|
def configure(provider)
|
9
38
|
each_pair do |name, value|
|
10
39
|
value.nil? and next
|
@@ -17,12 +46,28 @@ module ComplexConfig
|
|
17
46
|
self
|
18
47
|
end
|
19
48
|
|
49
|
+
# Adds a plugin to the configuration
|
50
|
+
#
|
51
|
+
# Plugins are lambda expressions that can provide custom behavior for
|
52
|
+
# configuration attributes.
|
53
|
+
#
|
54
|
+
# @param code [Proc] The plugin code to add
|
55
|
+
# @return [self] Returns self for chaining
|
20
56
|
def add_plugin(code)
|
21
57
|
plugins << code
|
22
58
|
self
|
23
59
|
end
|
24
60
|
end
|
25
61
|
|
62
|
+
# Configures the ComplexConfig system with the provided settings
|
63
|
+
#
|
64
|
+
# This is the main entry point for configuring ComplexConfig. It creates a
|
65
|
+
# configuration object, yields it to the provided block for customization,
|
66
|
+
# and applies the configuration to the provider.
|
67
|
+
#
|
68
|
+
# @yield [config] Yields the configuration object for setup
|
69
|
+
# @yieldparam config [Config] The configuration object to modify
|
70
|
+
# @return [Config] The configured object
|
26
71
|
def self.configure
|
27
72
|
config = Config.new
|
28
73
|
yield config
|
@@ -1,7 +1,27 @@
|
|
1
1
|
require "openssl"
|
2
2
|
require "base64"
|
3
3
|
|
4
|
+
# A class that provides encryption and decryption services using AES-128-GCM
|
5
|
+
#
|
6
|
+
# This class handles the encryption and decryption of configuration data using
|
7
|
+
# OpenSSL's AES-128-GCM cipher mode. It manages the encryption key validation,
|
8
|
+
# initialization vector generation, and authentication tag handling required
|
9
|
+
# for secure encrypted communication.
|
10
|
+
#
|
11
|
+
# @see ComplexConfig::EncryptionError
|
12
|
+
# @see ComplexConfig::EncryptionKeyInvalid
|
13
|
+
# @see ComplexConfig::DecryptionFailed
|
4
14
|
class ComplexConfig::Encryption
|
15
|
+
# Initializes a new encryption instance with the specified secret key
|
16
|
+
#
|
17
|
+
# This method sets up the encryption object by validating the secret key
|
18
|
+
# length and preparing the OpenSSL cipher for AES-128-GCM encryption
|
19
|
+
# operations
|
20
|
+
#
|
21
|
+
# @param secret [String] the encryption key to use, must be exactly 16 bytes
|
22
|
+
# long
|
23
|
+
# @raise [ComplexConfig::EncryptionKeyInvalid] if the secret key is not
|
24
|
+
# exactly 16 bytes in length
|
5
25
|
def initialize(secret)
|
6
26
|
@secret = secret
|
7
27
|
@secret.size != 16 and raise ComplexConfig::EncryptionKeyInvalid,
|
@@ -9,6 +29,19 @@ class ComplexConfig::Encryption
|
|
9
29
|
@cipher = OpenSSL::Cipher.new('aes-128-gcm')
|
10
30
|
end
|
11
31
|
|
32
|
+
# The encrypt method encodes text using AES-128-GCM encryption
|
33
|
+
#
|
34
|
+
# This method takes a text input and encrypts it using the OpenSSL cipher
|
35
|
+
# configured with AES-128-GCM mode. It generates a random initialization
|
36
|
+
# vector and authentication tag, then combines the encrypted data, IV, and
|
37
|
+
# auth tag into a base64-encoded string separated by '--'
|
38
|
+
#
|
39
|
+
# @param text [Object] the object to encrypt, which will be marshaled before
|
40
|
+
# encryption
|
41
|
+
#
|
42
|
+
# @return [String] the base64-encoded encrypted string including the
|
43
|
+
# encrypted data, initialization vector, and authentication tag separated
|
44
|
+
# by '--'
|
12
45
|
def encrypt(text)
|
13
46
|
@cipher.encrypt
|
14
47
|
@cipher.key = @secret
|
@@ -25,6 +58,15 @@ class ComplexConfig::Encryption
|
|
25
58
|
].map { |v| base64_encode(v) }.join('--')
|
26
59
|
end
|
27
60
|
|
61
|
+
# The decrypt method decodes encrypted text using AES-128-GCM decryption
|
62
|
+
#
|
63
|
+
# @param text [String] the base64-encoded encrypted string containing the
|
64
|
+
# encrypted data, initialization vector, and authentication tag separated
|
65
|
+
# by '--'
|
66
|
+
#
|
67
|
+
# @return [Object] the decrypted and marshaled object
|
68
|
+
# @raise [ComplexConfig::DecryptionFailed] if the authentication tag is
|
69
|
+
# invalid or decryption fails with the provided key
|
28
70
|
def decrypt(text)
|
29
71
|
encrypted, iv, auth_tag = text.split('--').map { |v| base64_decode(v) }
|
30
72
|
|
@@ -47,10 +89,26 @@ class ComplexConfig::Encryption
|
|
47
89
|
|
48
90
|
private
|
49
91
|
|
92
|
+
# The base64_encode method encodes binary data into a Base64 string format
|
93
|
+
#
|
94
|
+
# This method takes binary data as input and converts it into a
|
95
|
+
# Base64-encoded string representation using the strict encoding mode, which
|
96
|
+
# ensures that the output contains only valid Base64 characters and raises an
|
97
|
+
# error for invalid input
|
98
|
+
#
|
99
|
+
# @param x [Object] the binary data to encode, typically a String or binary buffer
|
100
|
+
# @return [String] the Base64-encoded representation of the input data
|
50
101
|
def base64_encode(x)
|
51
102
|
::Base64.strict_encode64(x)
|
52
103
|
end
|
53
104
|
|
105
|
+
# The base64_decode method decodes a Base64-encoded string back into its
|
106
|
+
# original binary data format.
|
107
|
+
#
|
108
|
+
# @param x [String] the Base64-encoded string to decode, which will have
|
109
|
+
# leading/trailing whitespace stripped
|
110
|
+
# @return [String] the decoded binary data as a string
|
111
|
+
# @see base64_encode for the corresponding encoding method
|
54
112
|
def base64_decode(x)
|
55
113
|
::Base64.strict_decode64(x.strip)
|
56
114
|
end
|
@@ -1,5 +1,27 @@
|
|
1
1
|
module ComplexConfig
|
2
|
+
|
3
|
+
# Abstract base class for ComplexConfig exceptions
|
4
|
+
#
|
5
|
+
# This class serves as the root of the exception hierarchy for the
|
6
|
+
# ComplexConfig library. All custom exceptions raised by ComplexConfig should
|
7
|
+
# inherit from this class.
|
8
|
+
#
|
9
|
+
# @abstract
|
2
10
|
class ComplexConfigError < StandardError
|
11
|
+
# Wraps an exception with a custom error class from the ComplexConfig
|
12
|
+
# hierarchy
|
13
|
+
#
|
14
|
+
# This method takes an exception and wraps it with a new error class that
|
15
|
+
# is derived from the ComplexConfig error hierarchy. It allows for more
|
16
|
+
# specific error handling by converting one type of exception into another
|
17
|
+
# while preserving the original message and backtrace.
|
18
|
+
#
|
19
|
+
# @param klass [Class, String] The error class to wrap the exception with,
|
20
|
+
# either as a Class object or a string name that can be resolved via
|
21
|
+
# ComplexConfig.const_get
|
22
|
+
# @param e [StandardError] The original exception to be wrapped
|
23
|
+
# @return [ComplexConfig::ComplexConfigError] A new instance of the specified
|
24
|
+
# error class containing the original exception's message and backtrace
|
3
25
|
def self.wrap(klass, e)
|
4
26
|
Class === klass or klass = ComplexConfig.const_get(klass)
|
5
27
|
error = klass.new(e.message)
|
@@ -8,24 +30,90 @@ module ComplexConfig
|
|
8
30
|
end
|
9
31
|
end
|
10
32
|
|
33
|
+
# An exception raised when an expected configuration attribute is missing
|
34
|
+
#
|
35
|
+
# This error is triggered when code attempts to access a configuration
|
36
|
+
# attribute that has not been defined or set within the configuration system.
|
37
|
+
# It inherits from ComplexConfigError, making it part of the library's
|
38
|
+
# standardized exception hierarchy for consistent error handling.
|
39
|
+
#
|
40
|
+
# @see ComplexConfigError
|
11
41
|
class AttributeMissing < ComplexConfigError
|
12
42
|
end
|
13
43
|
|
44
|
+
# An exception raised when a required configuration file is missing
|
45
|
+
#
|
46
|
+
# This error is triggered when the system attempts to access a configuration
|
47
|
+
# file that cannot be found at the expected location. It inherits from
|
48
|
+
# ComplexConfigError, making it part of the library's standardized exception
|
49
|
+
# hierarchy for consistent error handling.
|
50
|
+
#
|
51
|
+
# @see ComplexConfigError
|
52
|
+
# @see ComplexConfig::Provider#config
|
53
|
+
# @see ComplexConfig::Provider#decrypt_config_case
|
14
54
|
class ConfigurationFileMissing < ComplexConfigError
|
15
55
|
end
|
16
56
|
|
57
|
+
# An exception raised when a configuration file has invalid syntax
|
58
|
+
#
|
59
|
+
# This error is triggered when the system encounters YAML syntax errors in
|
60
|
+
# configuration files that prevent them from being properly parsed. It
|
61
|
+
# inherits from ComplexConfigError, making it part of the library's
|
62
|
+
# standardized exception hierarchy for consistent error handling.
|
63
|
+
#
|
64
|
+
# @see ComplexConfigError
|
65
|
+
# @see ComplexConfig::Provider#config
|
66
|
+
# @see ComplexConfig::Provider#decrypt_config_case
|
17
67
|
class ConfigurationSyntaxError < ComplexConfigError
|
18
68
|
end
|
19
69
|
|
70
|
+
# An abstract base class for encryption-related errors in the ComplexConfig
|
71
|
+
# library.
|
72
|
+
#
|
73
|
+
# This class serves as the root of the encryption exception hierarchy,
|
74
|
+
# providing a common base for all encryption-specific exceptions raised by
|
75
|
+
# ComplexConfig.
|
76
|
+
#
|
77
|
+
# @abstract
|
78
|
+
# @see ComplexConfigError
|
20
79
|
class EncryptionError < ComplexConfigError
|
21
80
|
end
|
22
81
|
|
82
|
+
# An exception raised when an encryption key has an invalid format or length
|
83
|
+
#
|
84
|
+
# This error is triggered when an encryption key does not meet the required
|
85
|
+
# specifications, such as having an incorrect byte length. It inherits from
|
86
|
+
# EncryptionError, making it part of the library's standardized exception
|
87
|
+
# hierarchy for consistent error handling.
|
88
|
+
#
|
89
|
+
# @see EncryptionError
|
90
|
+
# @see ComplexConfig::Encryption
|
23
91
|
class EncryptionKeyInvalid < EncryptionError
|
24
92
|
end
|
25
93
|
|
94
|
+
# An exception raised when a required encryption key is missing
|
95
|
+
#
|
96
|
+
# This error is triggered when the system attempts to access an encryption key
|
97
|
+
# that cannot be found through any of the configured sources. It inherits from
|
98
|
+
# EncryptionError, making it part of the library's standardized exception
|
99
|
+
# hierarchy for consistent error handling.
|
100
|
+
|
101
|
+
# @see EncryptionError
|
102
|
+
# @see ComplexConfig::Encryption
|
103
|
+
# @see ComplexConfig::KeySource
|
26
104
|
class EncryptionKeyMissing < EncryptionError
|
27
105
|
end
|
28
106
|
|
107
|
+
# An exception raised when decryption operations fail
|
108
|
+
#
|
109
|
+
# This error is triggered when the system encounters issues during the
|
110
|
+
# decryption process, such as invalid authentication tags or cipher errors
|
111
|
+
# that prevent successful decryption. It inherits from EncryptionError,
|
112
|
+
# making it part of the library's standardized exception hierarchy for
|
113
|
+
# consistent error handling.
|
114
|
+
#
|
115
|
+
# @see EncryptionError
|
116
|
+
# @see ComplexConfig::Encryption#decrypt
|
29
117
|
class DecryptionFailed < EncryptionError
|
30
118
|
end
|
31
119
|
end
|
@@ -1,4 +1,18 @@
|
|
1
|
+
# A key source class that provides encryption keys from various sources
|
2
|
+
#
|
3
|
+
# The KeySource class is responsible for managing and retrieving encryption
|
4
|
+
# keys from different possible sources such as files, environment variables, or
|
5
|
+
# direct values. It supports multiple configuration options and ensures that
|
6
|
+
# only one source is used at a time.
|
1
7
|
class ComplexConfig::KeySource
|
8
|
+
# The initialize method sets up the key source with one of several possible settings.
|
9
|
+
#
|
10
|
+
# @param pathname [String, nil] The path to a key file
|
11
|
+
# @param env_var [String, nil] The name of an environment variable containing the key
|
12
|
+
# @param var [String, nil] A string value representing the key
|
13
|
+
# @param master_key_pathname [String, nil] The path to a master key file
|
14
|
+
#
|
15
|
+
# @raise [ArgumentError] if more than one setting is provided
|
2
16
|
def initialize(pathname: nil, env_var: nil, var: nil, master_key_pathname: nil)
|
3
17
|
settings = [ pathname, env_var, var, master_key_pathname ].compact.size
|
4
18
|
if settings > 1
|
@@ -10,10 +24,22 @@ class ComplexConfig::KeySource
|
|
10
24
|
pathname, env_var, var, master_key_pathname
|
11
25
|
end
|
12
26
|
|
27
|
+
# The master_key? method checks whether a master key pathname has been set.
|
28
|
+
#
|
29
|
+
# @return [TrueClass, FalseClass] true if a master key pathname is
|
30
|
+
# configured, false otherwise
|
13
31
|
def master_key?
|
14
32
|
!!@master_key_pathname
|
15
33
|
end
|
16
34
|
|
35
|
+
# The key method retrieves the encryption key from the configured source.
|
36
|
+
#
|
37
|
+
# This method attempts to obtain the encryption key by checking various
|
38
|
+
# possible sources in order: a direct value, an environment variable,
|
39
|
+
# a master key file, or a key file associated with a pathname.
|
40
|
+
#
|
41
|
+
# @return [String, nil] the encryption key as a string if found, or nil if no
|
42
|
+
# key source is configured or accessible
|
17
43
|
def key
|
18
44
|
if @var
|
19
45
|
@var.ask_and_send(:chomp)
|
@@ -27,6 +53,12 @@ class ComplexConfig::KeySource
|
|
27
53
|
rescue Errno::ENOENT, Errno::ENOTDIR
|
28
54
|
end
|
29
55
|
|
56
|
+
# The key_bytes method converts the encryption key to bytes format.
|
57
|
+
#
|
58
|
+
# This method takes the encryption key value and packs it into a binary byte
|
59
|
+
# representation using hexadecimal encoding.
|
60
|
+
#
|
61
|
+
# @return [String] the encryption key as a binary string of bytes
|
30
62
|
def key_bytes
|
31
63
|
[ key ].pack('H*')
|
32
64
|
end
|
@@ -1,5 +1,26 @@
|
|
1
1
|
class ComplexConfig::Provider
|
2
|
+
# A module that provides convenient shortcuts for accessing configuration
|
3
|
+
# data
|
4
|
+
#
|
5
|
+
# This module defines methods that create proxy objects for easy
|
6
|
+
# configuration access with lazy evaluation and environment-specific lookups.
|
7
|
+
# It's designed to be included in classes that need quick access to
|
8
|
+
# configuration settings without explicit environment handling.
|
9
|
+
#
|
10
|
+
# @see ComplexConfig::Provider::Shortcuts
|
2
11
|
module Shortcuts
|
12
|
+
# The complex_config_with_env method provides access to configuration data
|
13
|
+
# with explicit environment targeting.
|
14
|
+
#
|
15
|
+
# @param name [String, nil] The name of the configuration to access, or nil
|
16
|
+
# to return a proxy object
|
17
|
+
#
|
18
|
+
# @param env [String] The environment name to use for configuration
|
19
|
+
# lookups, defaults to the current provider environment
|
20
|
+
#
|
21
|
+
# @return [ComplexConfig::Settings, ComplexConfig::Proxy] Returns either
|
22
|
+
# the configuration settings for the specified name and environment, or a
|
23
|
+
# proxy object if no name is provided
|
3
24
|
def complex_config_with_env(name = nil, env = ComplexConfig::Provider.env)
|
4
25
|
if name
|
5
26
|
ComplexConfig::Provider[name][env.to_s]
|
@@ -8,8 +29,21 @@ class ComplexConfig::Provider
|
|
8
29
|
end
|
9
30
|
end
|
10
31
|
|
32
|
+
# Alias for {complex_config_with_env}
|
33
|
+
# Provides a shorter syntax for accessing configuration with environment
|
34
|
+
# targeting.
|
35
|
+
#
|
36
|
+
# @see complex_config_with_env
|
11
37
|
alias cc complex_config_with_env
|
12
38
|
|
39
|
+
# The complex_config method provides access to configuration data with
|
40
|
+
# optional name parameter.
|
41
|
+
#
|
42
|
+
# @param name [String, nil] The name of the configuration to access, or nil
|
43
|
+
# to return a proxy object
|
44
|
+
# @return [ComplexConfig::Settings, ComplexConfig::Proxy] Returns either
|
45
|
+
# the configuration settings for the specified name, or a proxy object if
|
46
|
+
# no name is provided
|
13
47
|
def complex_config(name = nil)
|
14
48
|
if name
|
15
49
|
ComplexConfig::Provider[name]
|