Class: Railpack::Config
- Inherits:
-
Object
- Object
- Railpack::Config
- Defined in:
- lib/railpack/config.rb
Overview
Configuration handler for Railpack bundling settings.
This class provides immutable, environment-aware configuration management with:
- YAML-based config loading from config/railpack.yml
- Three-level merge order: defaults → bundler-specific → environment-specific
- Deep-frozen configs for immutability and thread safety
- Explicit accessors for common config keys with method_missing fallback
Example config/railpack.yml:
default:
bundler: bun
outdir: app/assets/builds
development:
sourcemap: true
production:
minify: true
All configs are immutable after loading. Set values in config/railpack.yml only.
Defined Under Namespace
Classes: Error
Constant Summary collapse
- CONFIG_KEYS =
Known config keys that get explicit accessors
%w[ target format minify sourcemap splitting entrypoint entrypoints outdir platform mode analyze_bundle ].freeze
Instance Attribute Summary collapse
-
#config ⇒ Object
readonly
Returns the value of attribute config.
Instance Method Summary collapse
-
#build_args(env = current_env) ⇒ Object
Build command arguments.
-
#build_flags(env = current_env) ⇒ Object
Build command flags (for dynamic bundler construction).
- #bundler(env = current_env) ⇒ Object
-
#bundler_command_overrides(env = current_env) ⇒ Object
Get bundler-specific command overrides from config.
- #bundler_config(env = current_env) ⇒ Object
- #current_env ⇒ Object
- #for_environment(env = current_env) ⇒ Object
-
#initialize ⇒ Config
constructor
A new instance of Config.
- #method_missing(method, *args) ⇒ Object
-
#reload! ⇒ Object
Reload configuration (useful for development/testing).
- #respond_to_missing?(method, include_private = false) ⇒ Boolean
-
#watch_args(env = current_env) ⇒ Object
Watch command arguments (can be overridden in config).
-
#watch_flags(env = current_env) ⇒ Object
Watch command flags (can be overridden in config).
Constructor Details
#initialize ⇒ Config
Returns a new instance of Config.
33 34 35 36 |
# File 'lib/railpack/config.rb', line 33 def initialize @config = load_config @merged_cache = {} end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args) ⇒ Object
97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/railpack/config.rb', line 97 def method_missing(method, *args) config_key = method.to_s if method.end_with?('=') # Setter - no longer allowed, config is immutable raise Error, "Config is immutable. Set values in config/railpack.yml" else # Getter - read from merged config (backward compatibility) # TODO: In v2.0, remove this fallback and require explicit accessors warn "DEPRECATED: Dynamic config access via '#{config_key}' will be removed in v2.0. Use explicit accessors instead." if defined?(Rails) && Rails.logger env = args.first || current_env return for_environment(env)[config_key] if for_environment(env).key?(config_key) super end end |
Instance Attribute Details
#config ⇒ Object (readonly)
Returns the value of attribute config.
31 32 33 |
# File 'lib/railpack/config.rb', line 31 def config @config end |
Instance Method Details
#build_args(env = current_env) ⇒ Object
Build command arguments
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/railpack/config.rb', line 119 def build_args(env = current_env) cfg = for_environment(env) args = [] # Support multiple entrypoints or single entrypoint entrypoints = cfg['entrypoints'] if entrypoints.is_a?(Array) && entrypoints.any? args.concat(entrypoints) elsif cfg['entrypoint'].is_a?(String) && !cfg['entrypoint'].empty? args << cfg['entrypoint'] end args << "--outdir=#{cfg['outdir']}" if cfg['outdir'] args.concat(build_flags(env)) args end |
#build_flags(env = current_env) ⇒ Object
Build command flags (for dynamic bundler construction)
138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/railpack/config.rb', line 138 def build_flags(env = current_env) cfg = for_environment(env) flags = [] flags << "--target=#{cfg['target']}" if cfg['target'] flags << "--format=#{cfg['format']}" if cfg['format'] flags << "--minify" if cfg['minify'] flags << "--sourcemap" if cfg['sourcemap'] flags << "--splitting" if cfg['splitting'] flags end |
#bundler(env = current_env) ⇒ Object
77 78 79 80 81 82 |
# File 'lib/railpack/config.rb', line 77 def bundler(env = current_env) # Look directly in config to avoid circular dependency env_config = @config[env.to_s] || {} default_config = @config["default"] || {} env_config['bundler'] || default_config['bundler'] || 'bun' end |
#bundler_command_overrides(env = current_env) ⇒ Object
Get bundler-specific command overrides from config
90 91 92 93 94 95 |
# File 'lib/railpack/config.rb', line 90 def bundler_command_overrides(env = current_env) bundler_name = bundler(env) overrides = @config.dig('bundlers', bundler_name, 'commands') || {} # Deep freeze for immutability deep_freeze(overrides) end |
#bundler_config(env = current_env) ⇒ Object
84 85 86 87 |
# File 'lib/railpack/config.rb', line 84 def bundler_config(env = current_env) bundler_name = bundler(env) @config[bundler_name] || {} end |
#current_env ⇒ Object
38 39 40 41 42 43 44 |
# File 'lib/railpack/config.rb', line 38 def current_env if defined?(Rails) && Rails.respond_to?(:env) Rails.env else :development end end |
#for_environment(env = current_env) ⇒ Object
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/railpack/config.rb', line 53 def for_environment(env = current_env) @merged_cache[env.to_s] ||= begin base_config = @config["default"] || {} bundler_config = bundler_config(env) env_config = @config[env.to_s] || {} # Merge: default <- bundler <- environment merged = deep_merge(deep_merge(base_config, bundler_config), env_config) # Validate critical config values validate_config!(merged, env) # Deep freeze for immutability deep_freeze(merged) end end |
#reload! ⇒ Object
Reload configuration (useful for development/testing)
71 72 73 74 75 |
# File 'lib/railpack/config.rb', line 71 def reload! @config = load_config @merged_cache.clear self end |
#respond_to_missing?(method, include_private = false) ⇒ Boolean
112 113 114 115 116 |
# File 'lib/railpack/config.rb', line 112 def respond_to_missing?(method, include_private = false) config_key = method.to_s.chomp('=') env = current_env for_environment(env).key?(config_key) || super end |
#watch_args(env = current_env) ⇒ Object
Watch command arguments (can be overridden in config)
152 153 154 |
# File 'lib/railpack/config.rb', line 152 def watch_args(env = current_env) build_args(env) # Default to same as build end |
#watch_flags(env = current_env) ⇒ Object
Watch command flags (can be overridden in config)
157 158 159 |
# File 'lib/railpack/config.rb', line 157 def watch_flags(env = current_env) build_flags(env) # Default to same as build end |