Class: ComplexConfig::Provider

Inherits:
Object
  • Object
show all
Includes:
Shortcuts, Tins::SexySingleton
Defined in:
lib/complex_config/provider.rb,
lib/complex_config/provider/shortcuts.rb

Defined Under Namespace

Modules: Shortcuts

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Shortcuts

#complex_config, #complex_config_with_env

Constructor Details

#initializeProvider

Returns a new instance of Provider.



12
13
14
15
# File 'lib/complex_config/provider.rb', line 12

def initialize
  @plugins             = Set.new
  @deep_freeze         = true
end

Instance Attribute Details

#envObject



176
177
178
# File 'lib/complex_config/provider.rb', line 176

def env
  @env || defined?(Rails) && Rails.env || ENV['RAILS_ENV'] || 'development'
end

#key(pathname = nil) ⇒ Object



192
193
194
# File 'lib/complex_config/provider.rb', line 192

def key(pathname = nil)
  key_source(pathname).ask_and_send(:key)
end

#master_key_pathnameObject



19
20
21
22
23
24
25
# File 'lib/complex_config/provider.rb', line 19

def master_key_pathname
  if @master_key_pathname
    @master_key_pathname
  else
    config_dir + 'master.key'
  end
end

#pluginsObject (readonly)

Returns the value of attribute plugins.



32
33
34
# File 'lib/complex_config/provider.rb', line 32

def plugins
  @plugins
end

Instance Method Details

#[](name) ⇒ Object



119
120
121
# File 'lib/complex_config/provider.rb', line 119

def [](name)
  config pathname(name), name
end

#add_plugin(plugin) ⇒ Object



34
35
36
37
# File 'lib/complex_config/provider.rb', line 34

def add_plugin(plugin)
  plugins.add plugin
  self
end

#apply_plugins(setting, id) ⇒ Object



50
51
52
53
54
55
56
57
# File 'lib/complex_config/provider.rb', line 50

def apply_plugins(setting, id)
  plugins.find do |plugin|
    catch :skip do
      value = setting.instance_exec(id, &plugin) and return value
    end
    nil
  end
end

#config(pathname, name = nil) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/complex_config/provider.rb', line 89

def config(pathname, name = nil)
  datas = []
  if File.exist?(pathname)
    datas << IO.binread(pathname)
  end
  if decrypted = decrypt_config(pathname)
    datas << decrypted
  end
  datas.empty? and raise ComplexConfig::ConfigurationFileMissing,
    "configuration file #{pathname.to_s.inspect} is missing"
  results = datas.map { |d| evaluate(pathname, d) }
  hashes = results.map { |r| ::YAML.load(r, pathname) }
  settings = ComplexConfig::Settings.build(name, hashes.shift)
  hashes.each { |h| settings.attributes_update(h) }
  if shared = settings.shared?
    shared = shared.to_h
    settings.each do |key, value|
      if value.is_a? ComplexConfig::Settings
        value.attributes_update(shared)
      elsif value.nil?
        settings[key] = ComplexConfig::Settings.build(nil, shared.dup)
      end
    end
  end
  deep_freeze? and settings.deep_freeze
  settings
rescue ::Psych::SyntaxError => e
  raise ComplexConfig::ComplexConfigError.wrap(:ConfigurationSyntaxError, e)
end

#config_dirObject



67
68
69
# File 'lib/complex_config/provider.rb', line 67

def config_dir
  @config_dir || (defined?(Rails) && Rails.root || Pathname.pwd) + 'config'
end

#config_dir=(dir) ⇒ Object



59
60
61
62
63
64
65
# File 'lib/complex_config/provider.rb', line 59

def config_dir=(dir)
  if dir.nil?
    @config_dir = nil
  else
    @config_dir = Pathname.new(dir)
  end
end

#configure_with(config) ⇒ Object



27
28
29
30
# File 'lib/complex_config/provider.rb', line 27

def configure_with(config)
  config.configure(self)
  flush_cache
end

#decrypt_config(pathname) ⇒ Object



75
76
77
78
79
80
81
82
# File 'lib/complex_config/provider.rb', line 75

def decrypt_config(pathname)
  enc_pathname = pathname.to_s + '.enc'
  my_ks        = key_source(pathname)
  if File.exist?(enc_pathname) && my_ks.ask_and_send(:key)
    text = IO.binread(enc_pathname)
    ComplexConfig::Encryption.new(my_ks.key_bytes).decrypt(text)
  end
end

#deep_freeze=(flag) ⇒ Object



39
40
41
42
43
44
# File 'lib/complex_config/provider.rb', line 39

def deep_freeze=(flag)
  if @deep_freeze && !flag
    mize_cache_clear
  end
  @deep_freeze = flag
end

#deep_freeze?Boolean

Returns:

  • (Boolean)


46
47
48
# File 'lib/complex_config/provider.rb', line 46

def deep_freeze?
  !!@deep_freeze
end

#encrypt_config(pathname, config) ⇒ Object



84
85
86
87
# File 'lib/complex_config/provider.rb', line 84

def encrypt_config(pathname, config)
  ks = key_source(pathname)
  ComplexConfig::Encryption.new(ks.key_bytes).encrypt(config)
end

#evaluate(pathname, data) ⇒ Object



170
171
172
173
174
# File 'lib/complex_config/provider.rb', line 170

def evaluate(pathname, data)
  erb = ::ERB.new(data, nil, '-')
  erb.filename = pathname.to_s
  erb.result
end

#exist?(name) ⇒ Boolean

Returns:

  • (Boolean)


154
155
156
157
158
# File 'lib/complex_config/provider.rb', line 154

def exist?(name)
  !!config(pathname(name), name)
rescue ComplexConfig::ConfigurationFileMissing
  false
end

#flush_cacheObject



165
166
167
168
# File 'lib/complex_config/provider.rb', line 165

def flush_cache
  mize_cache_clear
  self
end

#key_source(pathname = nil) ⇒ Object



182
183
184
185
186
187
188
189
190
# File 'lib/complex_config/provider.rb', line 182

def key_source(pathname = nil)
  [
    ComplexConfig::KeySource.new(var: @key),
    ComplexConfig::KeySource.new(pathname: pathname),
    ComplexConfig::KeySource.new(env_var: 'COMPLEX_CONFIG_KEY'),
    ComplexConfig::KeySource.new(env_var: 'RAILS_MASTER_KEY'),
    ComplexConfig::KeySource.new(master_key_pathname: master_key_pathname),
  ].find(&:key)
end

#new_keyObject



200
201
202
# File 'lib/complex_config/provider.rb', line 200

def new_key
  SecureRandom.hex(16)
end

#pathname(name) ⇒ Object



71
72
73
# File 'lib/complex_config/provider.rb', line 71

def pathname(name)
  config_dir + "#{name}.yml"
end

#prepare_output(value) ⇒ Object



148
149
150
151
152
# File 'lib/complex_config/provider.rb', line 148

def prepare_output(value)
  value.each_with_object({}) do |(k, v), h|
    h[k.to_s] = v
  end.to_yaml
end

#proxy(env = nil) ⇒ Object



160
161
162
# File 'lib/complex_config/provider.rb', line 160

def proxy(env = nil)
  ComplexConfig::Proxy.new(env)
end

#valid_key?(key) ⇒ Boolean

Returns:

  • (Boolean)


204
205
206
207
208
209
210
# File 'lib/complex_config/provider.rb', line 204

def valid_key?(key)
  ks = ComplexConfig::KeySource.new(var: key)
  ComplexConfig::Encryption.new(ks.key_bytes)
  ks
rescue
  false
end

#write_config(name, value: nil, encrypt: false, store_key: false) ⇒ Object



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/complex_config/provider.rb', line 124

def write_config(name, value: nil, encrypt: false, store_key: false)
  name, value = interpret_name_value(name, value)
  config_pathname = pathname(name).to_s
  if encrypt
    ks = provide_key_source(config_pathname, encrypt)
    File.secure_write(config_pathname + '.enc') do |out|
      out.write ComplexConfig::Encryption.new(ks.key_bytes).encrypt(prepare_output(value))
    end
    if store_key
      File.secure_write(config_pathname + '.key') do |out|
        out.write ks.key
      end
    end
    ks.key
  else
    File.secure_write(config_pathname) do |out|
      out.puts prepare_output(value)
    end
    true
  end
ensure
  flush_cache
end