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



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

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

#key(pathname = nil) ⇒ Object



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

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



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

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



84
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
# File 'lib/complex_config/provider.rb', line 84

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



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

def config_dir
  @config_dir || (defined?(Rails) && Rails.respond_to?(:root) && 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
# File 'lib/complex_config/provider.rb', line 75

def decrypt_config(pathname)
  decrypt_config_case(pathname).first
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



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

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

#evaluate(pathname, data) ⇒ Object



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

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

#exist?(name) ⇒ Boolean

Returns:

  • (Boolean)


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

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

#flush_cacheObject



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

def flush_cache
  mize_cache_clear
  self
end

#key_source(pathname = nil) ⇒ Object



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

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



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

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



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

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



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

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

#valid_key?(key) ⇒ Boolean

Returns:

  • (Boolean)


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

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



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

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