konfig-yaml 0.8.0 → 0.8.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +0 -2
- data/Gemfile.lock +3 -1
- data/README.md +53 -8
- data/lib/konfig_yaml.rb +0 -2
- data/lib/konfig_yaml/main.rb +47 -13
- data/lib/konfig_yaml/version.rb +1 -1
- data/spec/konfig_yaml_spec.rb +205 -34
- metadata +18 -8
- data/lib/konfig_yaml/hash_wrapper.rb +0 -87
- data/lib/konfig_yaml/inner_hash.rb +0 -10
- data/spec/inner_hash_spec.rb +0 -60
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 655ff90650e291f68f89b1c9b85e50443722a594
|
4
|
+
data.tar.gz: d20864bd49f7610a8bedd5afb54dafdbe5c9ebcc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 192f77af8b61f26a6932e612d312fc82caf75d95d5cd54b23cce79a5dfadf54c4542362829100dd197b090e3f607f5489894b882bb262702acdeae711cdccc41
|
7
|
+
data.tar.gz: 329d9eb47988927b9abc280b08eda11619bf55c7b596dbad67b17571fda79fbb15c2a384ddb9d7ac78e5cdfa0aa113fe586a96a13a52339d8e2f818eec20f62e
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
konfig-yaml (0.8.
|
4
|
+
konfig-yaml (0.8.1)
|
5
|
+
neohash (~> 0.1)
|
5
6
|
|
6
7
|
GEM
|
7
8
|
remote: https://rubygems.org/
|
@@ -9,6 +10,7 @@ GEM
|
|
9
10
|
diff-lcs (1.3)
|
10
11
|
docile (1.1.5)
|
11
12
|
json (2.1.0)
|
13
|
+
neohash (0.1.0)
|
12
14
|
rake (10.5.0)
|
13
15
|
rspec (3.7.0)
|
14
16
|
rspec-core (~> 3.7.0)
|
data/README.md
CHANGED
@@ -5,10 +5,13 @@
|
|
5
5
|
[![Code Climate](https://codeclimate.com/github/tilfin/konfig-yaml-rb/badges/gpa.svg)](https://codeclimate.com/github/tilfin/konfig-yaml-rb)
|
6
6
|
[![Test Coverage](https://codeclimate.com/github/tilfin/konfig-yaml-rb/badges/coverage.svg)](https://codeclimate.com/github/tilfin/konfig-yaml-rb/coverage)
|
7
7
|
|
8
|
-
The loader of
|
8
|
+
The loader of YAML configuration for each execution environments like [settingslogic](https://github.com/settingslogic/settingslogic).
|
9
9
|
|
10
|
-
- Expand environment variables (ex. `
|
10
|
+
- Expand environment variables like bash (ex. `storage-${RUBY_ENV}`)
|
11
|
+
- If an environment variable is not set, it is to be emtpy string.
|
12
|
+
- If `${DB_USER:-user}` or `${DB_USER:user}` is defined, `user` is expanded unless DB_USER does not exists.
|
11
13
|
- Deep merge the environment settings and default settings (except array items)
|
14
|
+
- Support YAML Anchor `&something` / Reference `<<: *something`
|
12
15
|
- Ruby version of [konfig-yaml](https://github.com/tilfin/konfig-yaml)
|
13
16
|
|
14
17
|
## Installation
|
@@ -29,7 +32,9 @@ Or install it yourself as:
|
|
29
32
|
|
30
33
|
## Usage
|
31
34
|
|
32
|
-
|
35
|
+
### Load a configuration
|
36
|
+
|
37
|
+
```ruby
|
33
38
|
require 'konfig-yaml'
|
34
39
|
|
35
40
|
config = KonfigYaml.new([name], [opts]);
|
@@ -38,10 +43,50 @@ config = KonfigYaml.new([name], [opts]);
|
|
38
43
|
* `name` specifys the name of `config/<name>.yml` ( default `app` )
|
39
44
|
* `opts`
|
40
45
|
* `:path` config directory path resolved from the process current one ( default `config` )
|
41
|
-
* `:env`
|
46
|
+
* `:env` Execution environment ( default **RUBY_ENV** value, **RAILS_ENV** value, **RACK_ENV** value, or `development` )
|
42
47
|
* `:use_cache` whether using cache ( default `true` )
|
43
48
|
|
44
|
-
|
49
|
+
### Access the values
|
50
|
+
|
51
|
+
#### by accessor method
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
port = config.port
|
55
|
+
log_lv = config.log.level
|
56
|
+
```
|
57
|
+
|
58
|
+
#### by symbol key
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
port = config[:port]
|
62
|
+
log_lv = config.log[:level]
|
63
|
+
```
|
64
|
+
|
65
|
+
#### by string key
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
port = config['port']
|
69
|
+
log_lv = config['log'].level
|
70
|
+
```
|
71
|
+
|
72
|
+
### Dynamically change settings
|
73
|
+
|
74
|
+
Support only symbol or string
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
config[:port] = 80
|
78
|
+
config.log['level'] = 'fatal'
|
79
|
+
config[:backend] = { host: 'cms.example.com', "port" => 7080 }
|
80
|
+
|
81
|
+
p config.port # 80
|
82
|
+
p config.log.level # "fatal"
|
83
|
+
p config.backend.host # "cms.example.com"
|
84
|
+
p config.backend.port # 7080
|
85
|
+
```
|
86
|
+
|
87
|
+
### Clear caches
|
88
|
+
|
89
|
+
For testing purpose
|
45
90
|
|
46
91
|
```
|
47
92
|
KonfigYaml.clear
|
@@ -56,7 +101,7 @@ KonfigYaml.clear
|
|
56
101
|
```
|
57
102
|
default:
|
58
103
|
port: 8080
|
59
|
-
|
104
|
+
log:
|
60
105
|
level: info
|
61
106
|
db:
|
62
107
|
name: ${BRAND:-normal}-app-${RUBY_ENV}
|
@@ -65,7 +110,7 @@ default:
|
|
65
110
|
|
66
111
|
production:
|
67
112
|
port: 1080
|
68
|
-
|
113
|
+
log:
|
69
114
|
level: error
|
70
115
|
db:
|
71
116
|
pass: Password
|
@@ -79,7 +124,7 @@ require 'konfig-yaml'
|
|
79
124
|
config = KonfigYaml.new
|
80
125
|
|
81
126
|
puts config.port
|
82
|
-
puts config.
|
127
|
+
puts config.log.level
|
83
128
|
puts config.db.user
|
84
129
|
puts config[:db]['name']
|
85
130
|
puts config['db'].password
|
data/lib/konfig_yaml.rb
CHANGED
data/lib/konfig_yaml/main.rb
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
require 'pathname'
|
2
|
+
require 'neohash'
|
2
3
|
|
3
4
|
# KonfigYaml main class
|
4
5
|
class KonfigYaml
|
5
|
-
include
|
6
|
+
include NeoHash::Support
|
7
|
+
|
6
8
|
# Create an configuration from yaml file
|
7
9
|
#
|
8
10
|
# @param [String] name ('app') the basename of yaml file
|
9
11
|
# @param [Hash] opts the options to intialize
|
10
|
-
# @option opts [String] :env (ENV['RUBY_ENV'] || ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development')
|
12
|
+
# @option opts [String] :env (ENV['RUBY_ENV'] || ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development') execution environment
|
11
13
|
# @option opts [String] :path ('config') directory path that contains the yaml file
|
12
14
|
# @option opts [Boolean] :use_cache (true) whether cache settings or not
|
13
15
|
def initialize(name = 'app', opts = nil)
|
@@ -22,8 +24,8 @@ class KonfigYaml
|
|
22
24
|
env = environment(opts)
|
23
25
|
use_cache = opts.fetch(:use_cache, true)
|
24
26
|
|
25
|
-
load_config(name, env, path, use_cache)
|
26
|
-
|
27
|
+
h = load_config(name, env, path, use_cache)
|
28
|
+
set_inner_hash(dup_hash_expand_envs(h))
|
27
29
|
end
|
28
30
|
|
29
31
|
# Clear caches
|
@@ -46,14 +48,11 @@ class KonfigYaml
|
|
46
48
|
def load_config(name, env, path, use_cache)
|
47
49
|
cfg_key = "#{name}/#{env}"
|
48
50
|
if use_cache && cfg_cache.key?(cfg_key)
|
49
|
-
|
50
|
-
return
|
51
|
+
return cfg_cache[cfg_key]
|
51
52
|
end
|
52
53
|
|
53
54
|
data = load_yaml(name, path)
|
54
|
-
|
55
|
-
|
56
|
-
cfg_cache[cfg_key] = @h
|
55
|
+
cfg_cache[cfg_key] = convert_data_to_hash(data, env)
|
57
56
|
end
|
58
57
|
|
59
58
|
def load_yaml(name, dir)
|
@@ -62,18 +61,18 @@ class KonfigYaml
|
|
62
61
|
YAML.load(File.read(file_path))
|
63
62
|
end
|
64
63
|
|
65
|
-
def
|
64
|
+
def convert_data_to_hash(data, env)
|
66
65
|
if data.include?(env)
|
67
|
-
|
66
|
+
deep_merge(data[env] || {}, data['default'] || {})
|
68
67
|
elsif data.include?('default')
|
69
|
-
|
68
|
+
data['default']
|
70
69
|
else
|
71
70
|
raise ArgumentError.new("The configuration for #{env} is not defined in #{name}")
|
72
71
|
end
|
73
72
|
end
|
74
73
|
|
75
74
|
def deep_merge(target, default)
|
76
|
-
target.merge
|
75
|
+
target.merge(default) do |key, target_val, default_val|
|
77
76
|
if target_val.is_a?(Hash) && default_val.is_a?(Hash)
|
78
77
|
deep_merge(target_val, default_val)
|
79
78
|
else
|
@@ -81,4 +80,39 @@ class KonfigYaml
|
|
81
80
|
end
|
82
81
|
end
|
83
82
|
end
|
83
|
+
|
84
|
+
def dup_hash_expand_envs(root)
|
85
|
+
root.map do |name, val|
|
86
|
+
if val.is_a?(Hash)
|
87
|
+
[name, dup_hash_expand_envs(val)]
|
88
|
+
elsif val.is_a?(Array)
|
89
|
+
[name, dup_array_expand_envs(val)]
|
90
|
+
elsif val.is_a?(String)
|
91
|
+
[name, expand_envs(val)]
|
92
|
+
else
|
93
|
+
[name, val]
|
94
|
+
end
|
95
|
+
end.to_h
|
96
|
+
end
|
97
|
+
|
98
|
+
def dup_array_expand_envs(root)
|
99
|
+
root.map do |val|
|
100
|
+
if val.is_a?(Hash)
|
101
|
+
dup_hash_expand_envs(val)
|
102
|
+
elsif val.is_a?(Array)
|
103
|
+
dup_array_expand_envs(val)
|
104
|
+
elsif val.is_a?(String)
|
105
|
+
expand_envs(val)
|
106
|
+
else
|
107
|
+
val
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def expand_envs(str)
|
113
|
+
str.gsub(/\$\{(.+?)\}/) do |m|
|
114
|
+
env_key, default = $1.split(/:\-?/)
|
115
|
+
ENV[env_key] || default || ''
|
116
|
+
end
|
117
|
+
end
|
84
118
|
end
|
data/lib/konfig_yaml/version.rb
CHANGED
data/spec/konfig_yaml_spec.rb
CHANGED
@@ -162,59 +162,230 @@ describe KonfigYaml do
|
|
162
162
|
end
|
163
163
|
end
|
164
164
|
|
165
|
-
describe '
|
166
|
-
subject { described_class.new('app', path: 'config') }
|
165
|
+
describe 'merged configuraton' do
|
166
|
+
subject { described_class.new('app', path: 'config', env: env) }
|
167
167
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
168
|
+
context 'environment is development' do
|
169
|
+
let!(:env) { 'development' }
|
170
|
+
|
171
|
+
it 'an instance that has accessors by method' do
|
172
|
+
expect(subject.port).to eq(1080)
|
173
|
+
expect(subject.db.host).to eq('localhost')
|
174
|
+
expect(subject.db.name).to eq('service-development')
|
175
|
+
expect(subject.db.user).to eq('user')
|
176
|
+
expect(subject.db.pass).to eq('password')
|
177
|
+
expect(subject.root_url).to eq('http://localhost')
|
178
|
+
expect(subject.logger.level).to eq('debug')
|
179
|
+
expect(subject.logger.file).to eq('log/app.log')
|
180
|
+
expect{ subject.bucket }.to raise_error(NoMethodError)
|
181
|
+
expect{ subject.bucket_path }.to raise_error(NoMethodError)
|
182
|
+
expect{ subject.cloud_access_key }.to raise_error(NoMethodError)
|
183
|
+
expect(subject[:cloud_access_key]).to be_nil
|
184
|
+
expect(subject.access_limits).to eq ['127.0.0.1']
|
185
|
+
end
|
172
186
|
end
|
173
187
|
|
174
|
-
|
175
|
-
|
176
|
-
|
188
|
+
context 'environment is test' do
|
189
|
+
let!(:env) { 'test' }
|
190
|
+
|
191
|
+
it 'an instance that has accessors by method' do
|
192
|
+
expect(subject.port).to eq(1080)
|
193
|
+
expect(subject.db.host).to eq('localhost')
|
194
|
+
expect(subject.db.name).to eq('service-development')
|
195
|
+
expect(subject.db.user).to eq('user')
|
196
|
+
expect(subject.db.pass).to eq('password')
|
197
|
+
expect(subject.root_url).to eq('http://localhost')
|
198
|
+
expect(subject.logger.level).to eq('error')
|
199
|
+
expect(subject.logger.file).to eq('log/test.log')
|
200
|
+
expect{ subject.bucket }.to raise_error(NoMethodError)
|
201
|
+
expect{ subject.bucket_path }.to raise_error(NoMethodError)
|
202
|
+
expect{ subject.cloud_access_key }.to raise_error(NoMethodError)
|
203
|
+
expect(subject['cloud_access_key']).to be_nil
|
204
|
+
expect(subject.access_limits).to eq ['127.0.0.1']
|
205
|
+
end
|
206
|
+
|
207
|
+
context 'defined environment variables' do
|
208
|
+
before do
|
209
|
+
ENV['RUBY_ENV'] = 'test'
|
210
|
+
end
|
211
|
+
|
212
|
+
after do
|
213
|
+
ENV['RUBY_ENV'] = nil
|
214
|
+
end
|
215
|
+
|
216
|
+
it 'expands environment variables' do
|
217
|
+
expect(subject.db.host).to eq('localhost')
|
218
|
+
expect(subject.db.name).to eq('service-test')
|
219
|
+
expect(subject.db.user).to eq('user')
|
220
|
+
expect(subject.db.pass).to eq('password')
|
221
|
+
end
|
222
|
+
end
|
177
223
|
end
|
178
224
|
|
179
|
-
|
180
|
-
|
181
|
-
|
225
|
+
context 'environment is integration' do
|
226
|
+
let!(:env) { 'integration' }
|
227
|
+
|
228
|
+
it 'an instance that has accessors by method' do
|
229
|
+
expect(subject.port).to eq(1080)
|
230
|
+
expect(subject.db.host).to eq('')
|
231
|
+
expect(subject.db.name).to eq('service-development')
|
232
|
+
expect(subject.db.user).to eq('user')
|
233
|
+
expect(subject.db.pass).to eq('password')
|
234
|
+
expect(subject.root_url).to eq('https://api-itg.example.com')
|
235
|
+
expect(subject.logger.level).to eq('info')
|
236
|
+
expect(subject.logger[:file]).to be_nil
|
237
|
+
expect(subject.bucket).to eq('storage-service-stg')
|
238
|
+
expect(subject.bucket_path).to eq('/itg')
|
239
|
+
expect(subject.cloud_access_key).to eq('aaabbbccc')
|
240
|
+
expect(subject.access_limits).to eq ['192.168.0.0/24', '10.0.0.0/8']
|
241
|
+
end
|
242
|
+
|
243
|
+
context 'defined environment variables' do
|
244
|
+
before do
|
245
|
+
ENV['RUBY_ENV'] = 'integration'
|
246
|
+
ENV['DATABASE_HOST'] = 'db-itg.example.com'
|
247
|
+
ENV['DATABASE_USER'] = 'itg_user'
|
248
|
+
ENV['DATABASE_PASSWORD'] = 'PassworD'
|
249
|
+
end
|
250
|
+
|
251
|
+
after do
|
252
|
+
ENV['RUBY_ENV'] = nil
|
253
|
+
ENV['DATABASE_HOST'] = nil
|
254
|
+
ENV['DATABASE_USER'] = nil
|
255
|
+
ENV['DATABASE_PASSWORD'] = nil
|
256
|
+
end
|
257
|
+
|
258
|
+
it 'expands environment variables' do
|
259
|
+
expect(subject.db.host).to eq('db-itg.example.com')
|
260
|
+
expect(subject.db.name).to eq('service-integration')
|
261
|
+
expect(subject.db.user).to eq('itg_user')
|
262
|
+
expect(subject.db.pass).to eq('PassworD')
|
263
|
+
end
|
264
|
+
end
|
182
265
|
end
|
183
266
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
267
|
+
context 'environment is staging' do
|
268
|
+
let!(:env) { 'staging' }
|
269
|
+
|
270
|
+
it 'an instance that has accessors by method' do
|
271
|
+
expect(subject.port).to eq(1080)
|
272
|
+
expect(subject.db.host).to eq('')
|
273
|
+
expect(subject.db.name).to eq('service-development')
|
274
|
+
expect(subject.db.user).to eq('user')
|
275
|
+
expect(subject.db.pass).to eq('password')
|
276
|
+
expect(subject.root_url).to eq('https://api-stg.example.com')
|
277
|
+
expect(subject.logger.level).to eq('info')
|
278
|
+
expect(subject.logger['file']).to be_nil
|
279
|
+
expect(subject.bucket).to eq('storage-service-stg')
|
280
|
+
expect(subject.bucket_path).to eq('/stg')
|
281
|
+
expect(subject.cloud_access_key).to eq('aaabbbccc')
|
282
|
+
expect(subject.access_limits).to eq ['192.168.0.0/24', '10.0.0.0/8']
|
283
|
+
end
|
284
|
+
|
285
|
+
context 'defined environment variables' do
|
286
|
+
before do
|
287
|
+
ENV['RUBY_ENV'] = 'staging'
|
288
|
+
ENV['DATABASE_HOST'] = 'db-stg.example.com'
|
289
|
+
ENV['DATABASE_USER'] = 'stg_user'
|
290
|
+
ENV['DATABASE_PASSWORD'] = 'PassworD'
|
291
|
+
end
|
292
|
+
|
293
|
+
after do
|
294
|
+
ENV['RUBY_ENV'] = nil
|
295
|
+
ENV['DATABASE_HOST'] = nil
|
296
|
+
ENV['DATABASE_USER'] = nil
|
297
|
+
ENV['DATABASE_PASSWORD'] = nil
|
298
|
+
end
|
299
|
+
|
300
|
+
it 'expands environment variables' do
|
301
|
+
expect(subject.db.host).to eq('db-stg.example.com')
|
302
|
+
expect(subject.db.name).to eq('service-staging')
|
303
|
+
expect(subject.db.user).to eq('stg_user')
|
304
|
+
expect(subject.db.pass).to eq('PassworD')
|
305
|
+
end
|
306
|
+
end
|
191
307
|
end
|
192
308
|
|
193
|
-
context '
|
194
|
-
|
195
|
-
|
309
|
+
context 'environment is preproduction' do
|
310
|
+
let!(:env) { 'preproduction' }
|
311
|
+
|
312
|
+
it 'an instance that has accessors by method' do
|
313
|
+
expect(subject.port).to eq(1080)
|
314
|
+
expect(subject.db.host).to eq('')
|
315
|
+
expect(subject.db.name).to eq('service-development')
|
316
|
+
expect(subject.db.user).to eq('user')
|
317
|
+
expect(subject.db.pass).to eq('password')
|
318
|
+
expect(subject.root_url).to eq('https://api-pre.example.com')
|
319
|
+
expect(subject.logger.level).to eq('warn')
|
320
|
+
expect(subject.logger[:file]).to be_nil
|
321
|
+
expect(subject.bucket).to eq('storage-service-stg')
|
322
|
+
expect(subject.bucket_path).to eq('/pre')
|
323
|
+
expect(subject.cloud_access_key).to eq('aaabbbccc')
|
324
|
+
expect(subject.access_limits).to eq ['192.168.0.0/24', '10.0.0.0/8']
|
325
|
+
end
|
326
|
+
|
327
|
+
context 'defined environment variables' do
|
328
|
+
before do
|
329
|
+
ENV['RUBY_ENV'] = 'preproduction'
|
330
|
+
ENV['DATABASE_HOST'] = 'db-prod.example.com'
|
331
|
+
ENV['DATABASE_USER'] = 'preprod_user'
|
332
|
+
ENV['DATABASE_PASSWORD'] = '4s5gsUoP'
|
333
|
+
end
|
334
|
+
|
335
|
+
after do
|
336
|
+
ENV['RUBY_ENV'] = nil
|
337
|
+
ENV['DATABASE_HOST'] = nil
|
338
|
+
ENV['DATABASE_USER'] = nil
|
339
|
+
ENV['DATABASE_PASSWORD'] = nil
|
340
|
+
end
|
196
341
|
|
197
|
-
|
198
|
-
|
342
|
+
it 'expands environment variables' do
|
343
|
+
expect(subject.db.host).to eq('db-prod.example.com')
|
344
|
+
expect(subject.db.name).to eq('service-preproduction')
|
345
|
+
expect(subject.db.user).to eq('preprod_user')
|
346
|
+
expect(subject.db.pass).to eq('4s5gsUoP')
|
347
|
+
end
|
199
348
|
end
|
200
349
|
end
|
201
350
|
|
202
351
|
context 'environment is production' do
|
203
|
-
|
204
|
-
after { ENV['RUBY_ENV'] = nil }
|
352
|
+
let!(:env) { 'production' }
|
205
353
|
|
206
|
-
it 'an instance that
|
354
|
+
it 'an instance that has accessors by method' do
|
207
355
|
expect(subject.port).to eq(1080)
|
208
|
-
expect(subject
|
209
|
-
expect(subject.db.name).to eq('-
|
356
|
+
expect(subject.db.host).to eq('')
|
357
|
+
expect(subject.db.name).to eq('service-development')
|
358
|
+
expect(subject.db.user).to eq('user')
|
359
|
+
expect(subject.db.pass).to eq('password')
|
360
|
+
expect(subject.root_url).to eq('https://api.example.com')
|
361
|
+
expect(subject.logger.level).to eq('error')
|
362
|
+
expect(subject.logger['file']).to be_nil
|
363
|
+
expect(subject.bucket).to eq('storage-service')
|
364
|
+
expect(subject.bucket_path).to eq('/')
|
365
|
+
expect(subject.cloud_access_key).to eq('xxxyyyzzz')
|
366
|
+
expect(subject.access_limits).to be_nil
|
210
367
|
end
|
211
368
|
|
212
|
-
context 'defined
|
213
|
-
before
|
214
|
-
|
369
|
+
context 'defined environment variables' do
|
370
|
+
before do
|
371
|
+
ENV['RUBY_ENV'] = 'production'
|
372
|
+
ENV['DATABASE_HOST'] = 'db-prod.example.com'
|
373
|
+
ENV['DATABASE_USER'] = 'prod_user'
|
374
|
+
ENV['DATABASE_PASSWORD'] = '3kszdf4aR'
|
375
|
+
end
|
376
|
+
|
377
|
+
after do
|
378
|
+
ENV['RUBY_ENV'] = nil
|
379
|
+
ENV['DATABASE_HOST'] = nil
|
380
|
+
ENV['DATABASE_USER'] = nil
|
381
|
+
ENV['DATABASE_PASSWORD'] = nil
|
382
|
+
end
|
215
383
|
|
216
|
-
it 'expands
|
217
|
-
expect(subject.db.
|
384
|
+
it 'expands environment variables' do
|
385
|
+
expect(subject.db.host).to eq('db-prod.example.com')
|
386
|
+
expect(subject.db.name).to eq('service-production')
|
387
|
+
expect(subject.db.user).to eq('prod_user')
|
388
|
+
expect(subject.db.pass).to eq('3kszdf4aR')
|
218
389
|
end
|
219
390
|
end
|
220
391
|
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: konfig-yaml
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Toshimitsu Takahashi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-02-
|
11
|
+
date: 2018-02-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: neohash
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.1'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: bundler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,7 +66,7 @@ dependencies:
|
|
52
66
|
- - "~>"
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '3.0'
|
55
|
-
description: The loader of
|
69
|
+
description: The loader of YAML configuration for each execution environments.
|
56
70
|
email:
|
57
71
|
- toshi@tilfin.com
|
58
72
|
executables: []
|
@@ -67,13 +81,10 @@ files:
|
|
67
81
|
- Rakefile
|
68
82
|
- lib/konfig-yaml.rb
|
69
83
|
- lib/konfig_yaml.rb
|
70
|
-
- lib/konfig_yaml/hash_wrapper.rb
|
71
|
-
- lib/konfig_yaml/inner_hash.rb
|
72
84
|
- lib/konfig_yaml/main.rb
|
73
85
|
- lib/konfig_yaml/version.rb
|
74
86
|
- spec/fixtures/another.yml
|
75
87
|
- spec/fixtures/app.yaml
|
76
|
-
- spec/inner_hash_spec.rb
|
77
88
|
- spec/konfig_yaml_spec.rb
|
78
89
|
- spec/spec_helper.rb
|
79
90
|
homepage: https://github.com/tilfin/konfig-yaml-rb
|
@@ -99,9 +110,8 @@ rubyforge_project:
|
|
99
110
|
rubygems_version: 2.6.13
|
100
111
|
signing_key:
|
101
112
|
specification_version: 4
|
102
|
-
summary: Loader for
|
113
|
+
summary: Loader for YAML configuration with ENVs.
|
103
114
|
test_files:
|
104
|
-
- spec/inner_hash_spec.rb
|
105
115
|
- spec/konfig_yaml_spec.rb
|
106
116
|
- spec/fixtures/another.yml
|
107
117
|
- spec/fixtures/app.yaml
|
@@ -1,87 +0,0 @@
|
|
1
|
-
class KonfigYaml
|
2
|
-
module HashWrapper
|
3
|
-
def activate
|
4
|
-
replace_hash_and_expand_env
|
5
|
-
define_attr_readers
|
6
|
-
end
|
7
|
-
|
8
|
-
def [](key)
|
9
|
-
@h[key.to_sym]
|
10
|
-
end
|
11
|
-
|
12
|
-
def []=(key, value)
|
13
|
-
if value.is_a?(Hash)
|
14
|
-
@h[key.to_sym] = InnerHash.new(value)
|
15
|
-
else
|
16
|
-
@h[key.to_sym] = value
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def each
|
21
|
-
@h.each
|
22
|
-
end
|
23
|
-
|
24
|
-
def each_key
|
25
|
-
@h.each_key
|
26
|
-
end
|
27
|
-
|
28
|
-
def each_value
|
29
|
-
@h.each_value
|
30
|
-
end
|
31
|
-
|
32
|
-
def include?(key)
|
33
|
-
@h.include?(key)
|
34
|
-
end
|
35
|
-
|
36
|
-
# Convert to original Hash
|
37
|
-
#
|
38
|
-
# @return [Hash] hash
|
39
|
-
# @param [Hash] opts the options to intialize
|
40
|
-
# @option opts [String] :symbolize_names (true) whether symbolize names or not
|
41
|
-
def to_h(opts = {})
|
42
|
-
symbolize = opts.fetch(:symbolize_names, true)
|
43
|
-
|
44
|
-
@h.map {|name, val|
|
45
|
-
[symbolize ? name : name.to_s,
|
46
|
-
val.is_a?(InnerHash) ? val.to_h(opts) : val]
|
47
|
-
}.to_h
|
48
|
-
end
|
49
|
-
|
50
|
-
alias_method :each_pair, :each
|
51
|
-
alias_method :has_key?, :include?
|
52
|
-
alias_method :key?, :include?
|
53
|
-
alias_method :member?, :include?
|
54
|
-
|
55
|
-
private
|
56
|
-
|
57
|
-
def define_attr_readers
|
58
|
-
self.instance_eval do |obj|
|
59
|
-
s = class << self; self end
|
60
|
-
@h.each_key do |name|
|
61
|
-
s.send :define_method , name, lambda { @h[name] }
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def replace_hash_and_expand_env
|
67
|
-
new_h = {}
|
68
|
-
@h.each do |name, val|
|
69
|
-
new_h[name.to_sym] = convert_value(val)
|
70
|
-
end
|
71
|
-
@h = new_h
|
72
|
-
end
|
73
|
-
|
74
|
-
def convert_value(val)
|
75
|
-
if val.is_a?(Hash)
|
76
|
-
InnerHash.new(val)
|
77
|
-
elsif val.is_a?(String)
|
78
|
-
val.gsub(/\$\{(.+?)\}/) {|m|
|
79
|
-
env_key, default = $1.split(/:\-?/)
|
80
|
-
ENV[env_key] || default || ''
|
81
|
-
}
|
82
|
-
else
|
83
|
-
val
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
data/spec/inner_hash_spec.rb
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'yaml'
|
3
|
-
|
4
|
-
describe KonfigYaml::InnerHash do
|
5
|
-
subject { described_class.new(h) }
|
6
|
-
|
7
|
-
let!(:h) do
|
8
|
-
{
|
9
|
-
'port' => 80,
|
10
|
-
'logger' => { 'level' => 'warn' }
|
11
|
-
}
|
12
|
-
end
|
13
|
-
|
14
|
-
describe '#initialize' do
|
15
|
-
it 'an instance that has accessors by method' do
|
16
|
-
expect(subject.port).to eq(80)
|
17
|
-
expect(subject.logger.level).to eq('warn')
|
18
|
-
end
|
19
|
-
|
20
|
-
it 'an instance that has accessors by symbol' do
|
21
|
-
expect(subject[:port]).to eq(80)
|
22
|
-
expect(subject[:logger][:level]).to eq('warn')
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'an instance that has accessors by string' do
|
26
|
-
expect(subject['port']).to eq(80)
|
27
|
-
expect(subject['logger']['level']).to eq('warn')
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'an instance that has accessors by various ways' do
|
31
|
-
expect(subject.logger[:level]).to eq('warn')
|
32
|
-
expect(subject.logger['level']).to eq('warn')
|
33
|
-
expect(subject[:logger].level).to eq('warn')
|
34
|
-
expect(subject[:logger]['level']).to eq('warn')
|
35
|
-
expect(subject['logger'].level).to eq('warn')
|
36
|
-
expect(subject['logger'][:level]).to eq('warn')
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
describe '#to_h' do
|
41
|
-
let!(:h_symbol) do
|
42
|
-
{
|
43
|
-
port: 80,
|
44
|
-
logger: { level: 'warn' }
|
45
|
-
}
|
46
|
-
end
|
47
|
-
|
48
|
-
it 'creates an hash with name as symbol' do
|
49
|
-
expect(subject.to_h).to eq(h_symbol)
|
50
|
-
end
|
51
|
-
|
52
|
-
it 'creates an hash with name as symbol' do
|
53
|
-
expect(subject.to_h(symbolize_names: true)).to eq(h_symbol)
|
54
|
-
end
|
55
|
-
|
56
|
-
it 'creates an hash with name as string' do
|
57
|
-
expect(subject.to_h(symbolize_names: false)).to eq(h)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|