Class: Rubino::Config::Loader
- Inherits:
-
Object
- Object
- Rubino::Config::Loader
- Defined in:
- lib/rubino/config/loader.rb
Overview
Responsible for loading configuration from YAML files and environment.
Config is GLOBAL by design (#50): there is ONE config.yml, under RUBINO_HOME (default ~/.rubino), shared by every rubino instance on the machine — the same single-home model Hermes uses (~/.hermes/config.yaml). So ‘/think` / `/config set` in one instance changes the setting for all of them; there is no per-project/per-cwd override layer. Per-project config (cf. Claude Code’s .claude/settings.json hierarchy) is a separate, unbuilt feature, not the current contract. The merge is: user config.yml over built-in defaults (with $ENV expansion).
Constant Summary collapse
- CONFIG_FILENAME =
"config.yml"- ENV_FILENAME =
".env"- ENV_VAR_PATTERN =
/\$\{([A-Z_][A-Z0-9_]*)\}/
Instance Attribute Summary collapse
-
#config_path ⇒ Object
readonly
Returns the value of attribute config_path.
-
#env_path ⇒ Object
readonly
Returns the value of attribute env_path.
-
#home_path ⇒ Object
readonly
Returns the value of attribute home_path.
Class Method Summary collapse
-
.default_home_path ⇒ Object
Single source of truth for the home directory: RUBINO_HOME when set, else ~/.rubino.
Instance Method Summary collapse
-
#config_exists? ⇒ Boolean
Returns true if a config file exists.
-
#create_default_config! ⇒ Object
Creates the initial config file with defaults.
-
#initialize(home_path: nil) ⇒ Loader
constructor
A new instance of Loader.
-
#load ⇒ Object
Loads configuration from file, merging with defaults.
-
#raw_config ⇒ Object
The RAW user config.yml as a Hash (NOT merged with defaults), or {} when no file exists.
Constructor Details
#initialize(home_path: nil) ⇒ Loader
Returns a new instance of Loader.
39 40 41 42 43 |
# File 'lib/rubino/config/loader.rb', line 39 def initialize(home_path: nil) @home_path = home_path || self.class.default_home_path @config_path = File.join(@home_path, CONFIG_FILENAME) @env_path = File.join(@home_path, ENV_FILENAME) end |
Instance Attribute Details
#config_path ⇒ Object (readonly)
Returns the value of attribute config_path.
25 26 27 |
# File 'lib/rubino/config/loader.rb', line 25 def config_path @config_path end |
#env_path ⇒ Object (readonly)
Returns the value of attribute env_path.
25 26 27 |
# File 'lib/rubino/config/loader.rb', line 25 def env_path @env_path end |
#home_path ⇒ Object (readonly)
Returns the value of attribute home_path.
25 26 27 |
# File 'lib/rubino/config/loader.rb', line 25 def home_path @home_path end |
Class Method Details
.default_home_path ⇒ Object
Single source of truth for the home directory: RUBINO_HOME when set, else ~/.rubino. Rubino.home_path delegates here so the server (which loads config via the Loader) and the CLI commands (config/setup/doctor) resolve the SAME directory — previously the server honoured $RUBINO_HOME while the CLI recomputed File.join(Rubino.home_path, “config.yml”) off the YAML ‘paths.home` default (~/.rubino), a split brain at first boot.
34 35 36 37 |
# File 'lib/rubino/config/loader.rb', line 34 def self.default_home_path env = ENV["RUBINO_HOME"].to_s.strip env.empty? ? File.("~/.rubino") : File.(env) end |
Instance Method Details
#config_exists? ⇒ Boolean
Returns true if a config file exists
74 75 76 |
# File 'lib/rubino/config/loader.rb', line 74 def config_exists? File.exist?(@config_path) end |
#create_default_config! ⇒ Object
Creates the initial config file with defaults
79 80 81 82 83 |
# File 'lib/rubino/config/loader.rb', line 79 def create_default_config! FileUtils.mkdir_p(@home_path) File.write(@config_path, Defaults.to_yaml) @config_path end |
#load ⇒ Object
Loads configuration from file, merging with defaults.
Every way a config.yml can be unusable is normalized into a single ConfigError with a clean, actionable message here — at the source —so no raw Ruby/Psych backtrace can escape to the boot path (CFG-1 / CFG-R2). Covers: a YAML syntax error, an alias/anchor reference (safe_load rejects aliases by design), a config path that is a directory or a symlink to one (Errno::EISDIR), a non-Hash top-level (a bare scalar like ‘foo`, or a sequence), and any other read/parse failure.
55 56 57 58 59 60 61 |
# File 'lib/rubino/config/loader.rb', line 55 def load raw = load_raw_config load_env_file if File.exist?(@env_path) deep_merge(Defaults.to_hash, (raw)) end |
#raw_config ⇒ Object
The RAW user config.yml as a Hash (NOT merged with defaults), or {} when no file exists. Public so the boot guard / doctor can run LOAD-time schema validation (F8) over exactly what the user hand-edited — defaults are valid by construction, so merging them in would hide the user’s mistakes. Same normalization as #load (a malformed shape raises ConfigError), so callers get a clean error, never a raw Psych backtrace.
69 70 71 |
# File 'lib/rubino/config/loader.rb', line 69 def raw_config load_raw_config end |