Module: Legion::Settings::ProjectEnv
- Extended by:
- Logging::Helper
- Defined in:
- lib/legion/settings/project_env.rb
Overview
Per-project ‘.legionio.env` config file loader.
Walks up from Dir.pwd searching for a ‘.legionio.env` file. When found, parses `KEY=VALUE` lines with dot-notation keys and merges them into the loader at a priority between global settings and the request overlay.
File format:
# comment lines are ignored
llm.default_model=claude-sonnet-4-5-20241022
cache.driver=redis
Keys use dot notation to address nested settings paths. Values are always strings; callers should coerce as needed.
Resolution order (lowest → highest priority):
global settings < .legionio.env < request overlay (#9)
Constant Summary collapse
- ENV_FILENAME =
'.legionio.env'
Class Method Summary collapse
-
.find_project_env_file(start_dir: nil) ⇒ String?
Walk up from
start_dir(defaults to Dir.pwd) looking for ‘.legionio.env`. -
.load_into(settings, start_dir: nil) ⇒ String?
Find and load the project env file into the given settings hash, merging overrides (env file values win over existing values).
-
.parse_env_file(path) ⇒ Hash
Parse a ‘.legionio.env` file and return a nested hash of overrides.
Class Method Details
.find_project_env_file(start_dir: nil) ⇒ String?
Walk up from start_dir (defaults to Dir.pwd) looking for ‘.legionio.env`. Returns the first file found, or nil.
34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/legion/settings/project_env.rb', line 34 def find_project_env_file(start_dir: nil) dir = File.(start_dir || Dir.pwd) loop do candidate = File.join(dir, ENV_FILENAME) return candidate if File.file?(candidate) && File.readable?(candidate) parent = File.dirname(dir) break if parent == dir # filesystem root dir = parent end nil end |
.load_into(settings, start_dir: nil) ⇒ String?
Find and load the project env file into the given settings hash, merging overrides (env file values win over existing values).
82 83 84 85 86 87 88 89 90 |
# File 'lib/legion/settings/project_env.rb', line 82 def load_into(settings, start_dir: nil) path = find_project_env_file(start_dir: start_dir) return nil unless path overrides = parse_env_file(path) deep_merge_into!(settings, overrides) log.debug("ProjectEnv: loaded #{path}") path end |
.parse_env_file(path) ⇒ Hash
Parse a ‘.legionio.env` file and return a nested hash of overrides.
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/legion/settings/project_env.rb', line 52 def parse_env_file(path) result = {} File.readlines(path, chomp: true).each_with_index do |line, idx| next if line.strip.empty? next if line.strip.start_with?('#') parts = line.split('=', 2) unless parts.length == 2 log.warn("#{path}:#{idx + 1}: skipping malformed line (no '=' found)") next end raw_key, value = parts key_parts = raw_key.strip.split('.') if key_parts.empty? || key_parts.any?(&:empty?) log.warn("#{path}:#{idx + 1}: skipping invalid key '#{raw_key.strip}'") next end set_nested(result, key_parts.map(&:to_sym), value.strip) end result end |