Module: Lich::Common::FrontendSettings
- Defined in:
- documented/common/frontend_settings.rb
Overview
Owns user-configurable frontend definitions and built-in launch overrides.
The persisted schema deliberately lives outside entry.yaml so frontend configuration never enters the credential lifecycle. Callers replace the complete configuration; validation, atomic persistence, catalog cleanup, and immutable process state stay behind this module's small interface.
Defined Under Namespace
Classes: UnsupportedVersionError
Constant Summary collapse
- FILE_NAME =
'frontends.yml'- SCHEMA_VERSION =
1- CUSTOM_ID_PATTERN =
Pattern for valid custom frontend identifiers.
Custom IDs must start with a lowercase letter or digit, followed by 0-63 lowercase letters, digits, hyphens, or underscores.
/\A[a-z0-9][a-z0-9_-]{0,63}\z/- MAX_SCALAR_BYTES =
4096- MAX_ARGUMENTS =
256- MUTEX =
Synchronization lock protecting access to the current frontend configuration.
All public methods that read or write @current must hold this lock to ensure thread-safe changes to the in-memory catalog and process state.
Mutex.new
- EMPTY_CONFIGURATION =
The pristine baseline configuration with no built-in overrides or custom definitions.
Used to restore a known-good state when load! encounters errors or unsupported schemas. The returned structure is frozen and cannot be mutated.
Lich::Util.deep_freeze( { 'version' => SCHEMA_VERSION, 'builtins' => {}, 'custom' => {} } )
Class Method Summary collapse
-
.current ⇒ Hash
Returns a detached snapshot so callers cannot mutate applied settings.
-
.load!(data_dir: nil) ⇒ Hash
Loads, validates, and applies frontends.yml from a Lich data directory.
-
.replace!(data_dir: nil, builtins: {}, custom: {}) ⇒ Hash
Validates, atomically persists, and applies a complete configuration.
-
.settings_for(frontend_id) ⇒ Hash?
Returns persisted settings for a built-in or custom frontend identifier.
-
.validate_arguments(value) ⇒ Array<String>
Validates literal argv values without trimming or dropping positions.
Class Method Details
.current ⇒ Hash
Returns a detached snapshot so callers cannot mutate applied settings.
111 112 113 |
# File 'documented/common/frontend_settings.rb', line 111 def current MUTEX.synchronize { deep_copy(@current) } end |
.load!(data_dir: nil) ⇒ Hash
Loads, validates, and applies frontends.yml from a Lich data directory. Missing, unreadable, or malformed files become an empty configuration and restore the pristine built-in catalog. A document from a newer schema is left untouched and the last known-good catalog remains active. Invalid argument lists likewise retain the previous catalog and are logged.
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'documented/common/frontend_settings.rb', line 69 def load!(data_dir: nil) directory = resolve_data_dir(data_dir) MUTEX.synchronize do path = File.join(directory, FILE_NAME) raw = read_file(path) if unsupported_version?(raw) warn_unsupported_file(raw) return deep_copy(@current) end apply_configuration(normalize_configuration(raw)) rescue ArgumentError => error log_warning("could not apply #{FILE_NAME}: #{error.}") deep_copy(@current) end end |
.replace!(data_dir: nil, builtins: {}, custom: {}) ⇒ Hash
Validates, atomically persists, and applies a complete configuration. Replacing the whole document makes deletion explicit and prevents stale custom definitions from accumulating across settings reloads.
94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'documented/common/frontend_settings.rb', line 94 def replace!(data_dir: nil, builtins: {}, custom: {}) directory = resolve_data_dir(data_dir) MUTEX.synchronize do path = File.join(directory, FILE_NAME) refuse_unsupported_overwrite!(path) configuration = normalize_configuration( 'version' => SCHEMA_VERSION, 'builtins' => builtins, 'custom' => custom ) write_file(path, configuration) apply_configuration(configuration) end end |
.settings_for(frontend_id) ⇒ Hash?
Returns persisted settings for a built-in or custom frontend identifier. Aliases such as wrayth resolve to their stable built-in id.
120 121 122 123 124 125 126 127 |
# File 'documented/common/frontend_settings.rb', line 120 def settings_for(frontend_id) frontend_id = Frontend.canonical_name(frontend_id) MUTEX.synchronize do settings = @current.fetch('builtins').fetch(frontend_id, nil) || @current.fetch('custom').fetch(frontend_id, nil) settings && deep_copy(settings) end end |
.validate_arguments(value) ⇒ Array<String>
Validates literal argv values without trimming or dropping positions.
134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'documented/common/frontend_settings.rb', line 134 def validate_arguments(value) unless value.is_a?(Array) && value.length <= MAX_ARGUMENTS raise ArgumentError, "Additional arguments must be an array of at most #{MAX_ARGUMENTS} strings." end unless value.all? { |argument| argument.is_a?(String) && argument.valid_encoding? && argument.bytesize <= MAX_SCALAR_BYTES && !argument.match?(/[\x00-\x1f\x7f]/) } raise ArgumentError, 'Arguments must be bounded strings without control characters.' end value.map(&:dup) end |