Module: Pangea::Presets

Defined in:
lib/pangea/presets.rb

Overview

Preset composition for infrastructure configurations.

Presets are frozen hashes of configuration overrides that can be composed (stacked) and merged with user config. Later values win.

Usage in architectures:

module MyArchitecture
  PROFILES = {
    dev:        { encryption: 'AES256', versioning: false }.freeze,
    production: { encryption: 'aws:kms', versioning: true }.freeze,
  }.freeze

  def self.build(synth, config = {})
    config = Pangea::Presets.apply(config, PROFILES)
    # config[:profile] consumed, defaults merged, user overrides on top
  end
end

Class Method Summary collapse

Class Method Details

.apply(config, profiles, default_profile: :dev) ⇒ Hash

Apply a named profile to a config hash.

Extracts :profile key from config, looks it up in profiles hash, deep-merges the profile defaults under user config (user wins).

Parameters:

  • config (Hash)

    User configuration (may contain :profile key)

  • profiles (Hash)

    Map of profile name → frozen defaults hash

  • default_profile (Symbol) (defaults to: :dev)

    Fallback profile if none specified

Returns:

  • (Hash)

    Merged config with profile defaults applied

Raises:

  • (ArgumentError)


33
34
35
36
37
38
39
40
41
# File 'lib/pangea/presets.rb', line 33

def self.apply(config, profiles, default_profile: :dev)
  config = config.dup
  profile_name = config.delete(:profile) || default_profile
  profile = profiles[profile_name]

  raise ArgumentError, "Unknown profile :#{profile_name}. Available: #{profiles.keys.join(', ')}" unless profile

  deep_merge(profile, config)
end

.compose(*presets) ⇒ Hash

Compose multiple preset hashes into one (left-to-right, later wins).

Parameters:

  • presets (Array<Hash>)

    Preset hashes to merge

Returns:

  • (Hash)

    Composed preset (frozen)



47
48
49
# File 'lib/pangea/presets.rb', line 47

def self.compose(*presets)
  presets.reduce({}) { |acc, p| deep_merge(acc, p) }.freeze
end

.deep_merge(base, overlay) ⇒ Hash

Deep merge two hashes. Values from ‘overlay` win over `base`. Nested hashes are recursively merged; all other types are replaced.

Parameters:

  • base (Hash)
  • overlay (Hash)

Returns:

  • (Hash)


57
58
59
60
61
62
63
64
65
# File 'lib/pangea/presets.rb', line 57

def self.deep_merge(base, overlay)
  base.merge(overlay) do |_key, base_val, overlay_val|
    if base_val.is_a?(Hash) && overlay_val.is_a?(Hash)
      deep_merge(base_val, overlay_val)
    else
      overlay_val
    end
  end
end