Class: Sxn::Config::Manager

Inherits:
Object
  • Object
show all
Defined in:
lib/sxn/config.rb

Overview

Main configuration manager that integrates discovery, caching, and validation

Features:

  • Hierarchical configuration loading with caching

  • Configuration validation and migration

  • Environment variable overrides

  • Thread-safe configuration access

Constant Summary collapse

DEFAULT_CACHE_TTL =

5 minutes

300

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(start_directory: Dir.pwd, cache_ttl: DEFAULT_CACHE_TTL) ⇒ Manager

Returns a new instance of Manager.



21
22
23
24
25
26
27
# File 'lib/sxn/config.rb', line 21

def initialize(start_directory: Dir.pwd, cache_ttl: DEFAULT_CACHE_TTL)
  @discovery = ConfigDiscovery.new(start_directory)
  @cache = ConfigCache.new(ttl: cache_ttl)
  @validator = ConfigValidator.new
  @current_config = nil
  @config_mutex = Mutex.new
end

Instance Attribute Details

#cacheObject (readonly)

Returns the value of attribute cache.



19
20
21
# File 'lib/sxn/config.rb', line 19

def cache
  @cache
end

#current_configObject (readonly)

Returns the value of attribute current_config.



19
20
21
# File 'lib/sxn/config.rb', line 19

def current_config
  @current_config
end

#discoveryObject (readonly)

Returns the value of attribute discovery.



19
20
21
# File 'lib/sxn/config.rb', line 19

def discovery
  @discovery
end

#validatorObject (readonly)

Returns the value of attribute validator.



19
20
21
# File 'lib/sxn/config.rb', line 19

def validator
  @validator
end

Instance Method Details

#cache_statsHash

Get cache statistics

Returns:

  • (Hash)

    Cache statistics



123
124
125
126
127
128
129
# File 'lib/sxn/config.rb', line 123

def cache_stats
  config_files = discovery.find_config_files
  cache.stats(config_files).merge(
    config_files: config_files,
    discovery_time: measure_discovery_time
  )
end

#config(cli_options: {}, force_reload: false) ⇒ Hash

Get the current configuration with caching

Parameters:

  • cli_options (Hash) (defaults to: {})

    Command-line options to override

  • force_reload (Boolean) (defaults to: false)

    Force reload ignoring cache

Returns:

  • (Hash)

    Merged and validated configuration



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/sxn/config.rb', line 33

def config(cli_options: {}, force_reload: false)
  @config_mutex.synchronize do
    # Check if we need to reload due to file changes
    if @current_config && !force_reload
      config_files = discovery.find_config_files
      unless cache.valid?(config_files)
        @current_config = nil # Invalidate memory cache
      end
    end

    return @current_config if @current_config && !force_reload

    @current_config = load_and_validate_config(cli_options, force_reload)
  end
end

#config_file_pathsArray<String>

Get all configuration file paths in precedence order

Returns:

  • (Array<String>)

    Configuration file paths



142
143
144
# File 'lib/sxn/config.rb', line 142

def config_file_paths
  discovery.find_config_files
end

#debug_infoHash

Get configuration summary for debugging

Returns:

  • (Hash)

    Configuration debug information



148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/sxn/config.rb', line 148

def debug_info
  config_files = discovery.find_config_files

  {
    start_directory: discovery.start_directory.to_s,
    config_files: config_files,
    cache_stats: cache.stats,
    validation_errors: validator.errors,
    environment_variables: discovery.send(:load_env_config),
    discovery_performance: measure_discovery_time
  }
end

#errors(cli_options: {}) ⇒ Array<String>

Get validation errors for current configuration

Parameters:

  • cli_options (Hash) (defaults to: {})

    Command-line options to override

Returns:

  • (Array<String>)

    List of validation errors



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/sxn/config.rb', line 102

def errors(cli_options: {})
  # Try to load the actual configuration that would be used
  config(cli_options: cli_options)
  [] # : Array[String] # If config() succeeds, there are no errors
rescue ConfigurationError => e
  # Parse the validation errors from the exception message
  error_message = e.message
  if error_message.include?("Configuration validation failed:")
    # Extract the numbered error list
    lines = error_message.split("\n")
    errors = lines[1..].map { |line| line.strip.sub(/^\d+\.\s*/, "") }
    errors.reject(&:empty?)
  else
    [e.message]
  end
rescue StandardError => e
  [e.message]
end

#get(key_path, default: nil) ⇒ Object

Get configuration value by key path

Parameters:

  • key_path (String)

    Dot-separated key path (e.g., ‘settings.auto_cleanup’)

  • default (Object) (defaults to: nil)

    Default value if key not found

Returns:

  • (Object)

    Configuration value



60
61
62
63
64
65
66
67
68
69
# File 'lib/sxn/config.rb', line 60

def get(key_path, default: nil)
  current_config = config
  keys = key_path.split(".")

  keys.reduce(current_config) do |current, key|
    break default unless current.is_a?(Hash) && current.key?(key)

    current[key]
  end
end

#invalidate_cacheBoolean

Invalidate configuration cache

Returns:

  • (Boolean)

    Success status



133
134
135
136
137
138
# File 'lib/sxn/config.rb', line 133

def invalidate_cache
  @config_mutex.synchronize do
    @current_config = nil
    cache.invalidate
  end
end

#reload(cli_options: {}) ⇒ Hash

Reload configuration from disk

Parameters:

  • cli_options (Hash) (defaults to: {})

    Command-line options to override

Returns:

  • (Hash)

    Reloaded configuration



52
53
54
# File 'lib/sxn/config.rb', line 52

def reload(cli_options: {})
  config(cli_options: cli_options, force_reload: true)
end

#set(key_path, value) ⇒ Object

Set configuration value by key path (for runtime modifications)

Parameters:

  • key_path (String)

    Dot-separated key path

  • value (Object)

    Value to set

Returns:

  • (Object)

    The set value



75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/sxn/config.rb', line 75

def set(key_path, value)
  @config_mutex.synchronize do
    # Don't call config() here as it would cause deadlock
    # Get the current config directly if it exists
    current_config = @current_config || load_and_validate_config({}, false)
    keys = key_path.split(".")
    target = keys[0..-2].reduce(current_config) do |current, key|
      current[key] ||= {} # : Hash[String, untyped]
    end
    target[keys.last] = value
    value
  end
end

#valid?(cli_options: {}) ⇒ Boolean

Check if configuration is valid

Parameters:

  • cli_options (Hash) (defaults to: {})

    Command-line options to override

Returns:

  • (Boolean)

    True if configuration is valid



92
93
94
95
96
97
# File 'lib/sxn/config.rb', line 92

def valid?(cli_options: {})
  config(cli_options: cli_options)
  true
rescue ConfigurationError
  false
end