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.



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

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

Instance Attribute Details

#envObject



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

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

#key(pathname = nil) ⇒ Object



210
211
212
# File 'lib/complex_config/provider.rb', line 210

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

#master_key_pathnameObject



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

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.



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

def plugins
  @plugins
end

Instance Method Details

#[](name) ⇒ Object



127
128
129
# File 'lib/complex_config/provider.rb', line 127

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

#add_plugin(plugin) ⇒ Object



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

def add_plugin(plugin)
  plugins.add plugin
  self
end

#apply_plugins(setting, id) ⇒ Object



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

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



85
86
87
88
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
118
119
120
121
122
123
124
125
# File 'lib/complex_config/provider.rb', line 85

def config(pathname, name = nil)
  datas = []
  path_exist = File.exist?(pathname)
  if path_exist
    datas << IO.binread(pathname)
  end
  decrypted, reason, enc_pathname = decrypt_config_case(pathname)
  case reason
  when :ok
    datas << decrypted
  when :key_missing
    datas.empty? and raise ComplexConfig::EncryptionKeyMissing,
      "encryption key for #{enc_pathname.to_s.inspect} is missing"
  when :file_missing
    datas.empty? and raise ComplexConfig::ConfigurationFileMissing,
      "configuration file #{pathname.to_s.inspect} is missing"
  end
  results = datas.map { |d| evaluate(pathname, d) }
  hashes =
    if ::Psych::VERSION < "4"
      results.map { |r| ::YAML.load(r, pathname) }
    else
      results.map { |r| ::YAML.unsafe_load(r, filename: pathname) }
    end
  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_if_nil(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



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

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

#config_dir=(dir) ⇒ Object



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

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

#configure_with(config) ⇒ Object



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

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

#decrypt_config(pathname) ⇒ Object



76
77
78
# File 'lib/complex_config/provider.rb', line 76

def decrypt_config(pathname)
  decrypt_config_case(pathname).first
end

#deep_freeze=(flag) ⇒ Object



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

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

#deep_freeze?Boolean

Returns:

  • (Boolean)


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

def deep_freeze?
  !!@deep_freeze
end

#encrypt_config(pathname, config) ⇒ Object



80
81
82
83
# File 'lib/complex_config/provider.rb', line 80

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

#evaluate(pathname, data) ⇒ Object



179
180
181
182
183
# File 'lib/complex_config/provider.rb', line 179

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

#exist?(name) ⇒ Boolean

Returns:

  • (Boolean)


162
163
164
165
166
# File 'lib/complex_config/provider.rb', line 162

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

#flush_cacheObject



173
174
175
176
# File 'lib/complex_config/provider.rb', line 173

def flush_cache
  mize_cache_clear
  self
end

#key_source(pathname = nil) ⇒ Object



200
201
202
203
204
205
206
207
208
# File 'lib/complex_config/provider.rb', line 200

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



218
219
220
# File 'lib/complex_config/provider.rb', line 218

def new_key
  SecureRandom.hex(16)
end

#pathname(name) ⇒ Object



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

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

#prepare_output(value) ⇒ Object



156
157
158
159
160
# File 'lib/complex_config/provider.rb', line 156

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



168
169
170
# File 'lib/complex_config/provider.rb', line 168

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

#valid_key?(key) ⇒ Boolean

Returns:

  • (Boolean)


222
223
224
225
226
227
228
# File 'lib/complex_config/provider.rb', line 222

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



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/complex_config/provider.rb', line 132

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