yaml_settings 1.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rdoc_options +11 -0
- data/README.rdoc +154 -0
- data/Rakefile +22 -0
- data/lib/yaml_settings.rb +59 -0
- data/spec/fixtures/default.yml +79 -0
- data/spec/fixtures/default_missing.yml +3 -0
- data/spec/fixtures/default_only.yml +3 -0
- data/spec/fixtures/example_database.yml +18 -0
- data/spec/fixtures/private.yml +6 -0
- data/spec/fixtures/symbol_keys.yml +6 -0
- data/spec/spec_readme_examples.rb +13 -0
- data/spec/spec_yaml_settings.rb +167 -0
- data/yaml_settings.gemspec +29 -0
- metadata +78 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 248f78a2595723d1f64b57406b7bed078831232b
|
4
|
+
data.tar.gz: 302fa7f374b773c56fa3dbc93655711f3e6b3dab
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a3d3f8bcb4964b607d765369f31ba74781e39d851396a69bbb91d3a4718510156f713cc6824b0d709e173f062ba3eaec21b134d1561fd1156792d5c8b910a36e
|
7
|
+
data.tar.gz: ef37138b7b107afaed5f377382bd0a314cddba81d7e8770987afdd5278bc34f7e0c273ad99c5fd65af9c84b910ba221652c234e770f2456cd9ab635ce90d5e26
|
data/.rdoc_options
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
--- !ruby/object:RDoc::Options
|
2
|
+
charset: UTF-8
|
3
|
+
encoding: UTF-8
|
4
|
+
static_path: []
|
5
|
+
rdoc_include:
|
6
|
+
- "."
|
7
|
+
exclude:
|
8
|
+
line_numbers: false
|
9
|
+
main_page: README.rdoc
|
10
|
+
markup: rdoc
|
11
|
+
title: YAMLSettings Ruby Gem - Load and merge app settings from YAML files
|
data/README.rdoc
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
= YAML Settings
|
2
|
+
|
3
|
+
Load and merge application settings from YAML files.
|
4
|
+
|
5
|
+
At load time, settings are merged in two stages. First, all YAML data are
|
6
|
+
recursively merged in reverse file order. Settings in succeeding files override
|
7
|
+
all duplicate settings in preceding files. Second, the user selected
|
8
|
+
settings—specified by key (e.g., environment key)—are recursively merged with
|
9
|
+
the default settings.
|
10
|
+
|
11
|
+
This class can load multiple settings files, which provides a few benefits:
|
12
|
+
|
13
|
+
1. Confidential settings can be stored separately and securely from
|
14
|
+
non-confidential settings; for example, in a public repository.
|
15
|
+
|
16
|
+
2. Settings for each application component or service (e.g., database, payment
|
17
|
+
gateway, logger, CDN) can be stored in their respective files.
|
18
|
+
|
19
|
+
3. Shared or system-wide settings can be merged with application settings.
|
20
|
+
|
21
|
+
|
22
|
+
== Settings File Examples
|
23
|
+
|
24
|
+
The following are settings files, defined using YAML[http://yaml.org], which
|
25
|
+
typically use the +.yml+ or +.yaml+ file extension. For information on how to
|
26
|
+
craft YAML, see the spec[http://yaml.org/spec/].
|
27
|
+
|
28
|
+
=== Absolute minimal settings
|
29
|
+
|
30
|
+
default:
|
31
|
+
|
32
|
+
Above is the *mandatory* +default+ stanza, which must be present in at least one
|
33
|
+
of the YAML settings files, even if it is empty. This isn't very useful, so lets
|
34
|
+
add a couple of default settings.
|
35
|
+
|
36
|
+
default:
|
37
|
+
setting_1: on
|
38
|
+
setting_2: off
|
39
|
+
|
40
|
+
|
41
|
+
=== Database settings
|
42
|
+
|
43
|
+
Here we have settings that specify the database name, user, host, and password
|
44
|
+
file. There are three additional top-level stanzas: +development+, +production+,
|
45
|
+
and +test+. These stanzas can be defined for any reason and have any name, but
|
46
|
+
typically represent the runtime environment or mode of the application. Zero or
|
47
|
+
more non-default top-level stanzas can be defined.
|
48
|
+
|
49
|
+
# database.yaml
|
50
|
+
default:
|
51
|
+
db:
|
52
|
+
host: db.example.com
|
53
|
+
user: dbusr
|
54
|
+
pass: config/db-access
|
55
|
+
|
56
|
+
development:
|
57
|
+
db:
|
58
|
+
name: myapp_dev
|
59
|
+
|
60
|
+
production:
|
61
|
+
db:
|
62
|
+
name: myapp
|
63
|
+
pass: /var/www/sites/myapp/db-access
|
64
|
+
|
65
|
+
test:
|
66
|
+
db:
|
67
|
+
name: myapp_test
|
68
|
+
|
69
|
+
With these settings, the +default+ will always provide the database +host+ and
|
70
|
+
+user+ because it is not overridden in any other stanza. However, the database
|
71
|
+
+name+ is not specified in +default+ because it is set in each environment. In
|
72
|
+
+production+, the database password file is unique—and secure of course—thus
|
73
|
+
overrides +default+.
|
74
|
+
|
75
|
+
|
76
|
+
== Usage Examples
|
77
|
+
|
78
|
+
<em>First things first!</em>
|
79
|
+
|
80
|
+
require 'yaml_settings'
|
81
|
+
|
82
|
+
=== Load database settings
|
83
|
+
|
84
|
+
Load +production+ using the database settings above. The +production+ settings
|
85
|
+
are merged into +default+.
|
86
|
+
|
87
|
+
settings = YAMLSettings.new('database.yaml', :production)
|
88
|
+
settings.db.host # => "db.example.com"
|
89
|
+
settings.db.user # => "dbusr"
|
90
|
+
settings.db.name # => "myapp"
|
91
|
+
settings.db.pass # => "/var/www/sites/myapp/db-access"
|
92
|
+
|
93
|
+
The settings are accessed using methods. The +db+ setting is actually a Hash and
|
94
|
+
can also be accessed as such.
|
95
|
+
|
96
|
+
settings.db['host'] # => "db.example.com"
|
97
|
+
|
98
|
+
The difference is that method access raises an error if a setting is nonexistent.
|
99
|
+
|
100
|
+
settings.db.mia # KeyError: key not found: "mia"
|
101
|
+
settings.db['mia'] # => nil
|
102
|
+
|
103
|
+
Method access is only available for string and symbol keys of Hash settings.
|
104
|
+
|
105
|
+
=== Load multiple settings files
|
106
|
+
|
107
|
+
It may be helpful to store settings for each application component separately.
|
108
|
+
Or perhaps, settings are in a shared location. Here's how to initialize for such
|
109
|
+
a situation:
|
110
|
+
|
111
|
+
settings = YAMLSettings.new '/etc/app-defaults.yml', # system wide
|
112
|
+
'/etc/payment-gateway.yml', # system wide
|
113
|
+
'/var/www/share/config/cdn.yml', # common for sites
|
114
|
+
'config/app.yml', # app specific
|
115
|
+
'config/database.yml', # app specific
|
116
|
+
ENV['APP_MODE']
|
117
|
+
|
118
|
+
The +settings+ variable above is a compilation of four merges. First,
|
119
|
+
_config/database.yml_ will merge with and override _config/app.yml_; the result
|
120
|
+
will merge with and override _cdn.yml_; and so on. Therefore, specify files with
|
121
|
+
more generic settings first.
|
122
|
+
|
123
|
+
|
124
|
+
== Links
|
125
|
+
|
126
|
+
Homepage :: https://ecentryx.com/gems/yaml_settings
|
127
|
+
Ruby Gem :: https://rubygems.org/gems/yaml_settings
|
128
|
+
Source Code :: https://bitbucket.org/pachl/yaml_settings/src
|
129
|
+
Bug Tracker :: https://bitbucket.org/pachl/yaml_settings/issues
|
130
|
+
|
131
|
+
|
132
|
+
== History
|
133
|
+
|
134
|
+
1. 2017-06-30, v1.0.6
|
135
|
+
* First public release
|
136
|
+
|
137
|
+
|
138
|
+
== License
|
139
|
+
|
140
|
+
({ISC License}[https://opensource.org/licenses/ISC])
|
141
|
+
|
142
|
+
Copyright (c) 2013-2017, Clint Pachl <pachl@ecentryx.com>
|
143
|
+
|
144
|
+
Permission to use, copy, modify, and/or distribute this software for any purpose
|
145
|
+
with or without fee is hereby granted, provided that the above copyright notice
|
146
|
+
and this permission notice appear in all copies.
|
147
|
+
|
148
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
149
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
150
|
+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
151
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
152
|
+
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
153
|
+
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
154
|
+
THIS SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
GEM_NAME = File.basename(Dir['*.gemspec'][0], '.*')
|
2
|
+
|
3
|
+
desc 'Build gem'
|
4
|
+
task :gem do
|
5
|
+
system "gem build #{GEM_NAME}.gemspec"
|
6
|
+
end
|
7
|
+
|
8
|
+
desc 'Publish docs'
|
9
|
+
task :pub do
|
10
|
+
dir = ENV.fetch('public_gem_dir') + GEM_NAME
|
11
|
+
host = ENV.fetch('public_gem_host')
|
12
|
+
|
13
|
+
if system 'rdoc lib README.rdoc'
|
14
|
+
`cd ./doc && pax -w . | ssh #{host} 'cd #{dir} && rm -rf * && pax -r'`
|
15
|
+
`rm -r ./doc;`
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
desc 'Run tests'
|
20
|
+
task :test do
|
21
|
+
system 'bacon -a'
|
22
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
class YAMLSettings < DelegateClass(Hash)
|
5
|
+
|
6
|
+
VERSION = '1.0.6'
|
7
|
+
|
8
|
+
module AttrReader # :nodoc:
|
9
|
+
def method_missing(setting)
|
10
|
+
has_key?(setting) ? fetch(setting) : fetch(setting.to_s) # raises KeyError
|
11
|
+
end
|
12
|
+
private :method_missing
|
13
|
+
end
|
14
|
+
|
15
|
+
#
|
16
|
+
# Settings are merged in two stages. First, all +filenames+ are recursively
|
17
|
+
# merged in reverse order. Settings in succeeding +filenames+ overwrite all
|
18
|
+
# duplicate settings in preceding +filenames+. Second, settings specified by
|
19
|
+
# +key+ are then recursively merged with the _default_ settings.
|
20
|
+
#
|
21
|
+
# +filenames+:: one or more YAML data files
|
22
|
+
# +key+:: selects the top-level stanza from +filenames+ to be merged
|
23
|
+
# with the _default_ stanza
|
24
|
+
#
|
25
|
+
def initialize(*filenames, key)
|
26
|
+
all_settings = filenames.collect {|f| YAML.load_file(f) }
|
27
|
+
settings = all_settings.reduce {|i, j| deep_merge(i, j) }
|
28
|
+
@settings = deep_merge(settings.fetch('default'),
|
29
|
+
settings.fetch(key.to_s))
|
30
|
+
@settings.extend(AttrReader)
|
31
|
+
propagate_attr_reader(@settings)
|
32
|
+
super(@settings)
|
33
|
+
end
|
34
|
+
|
35
|
+
def inspect() @settings.inspect end
|
36
|
+
alias :to_s :inspect
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def method_missing(setting, *args, &blk)
|
41
|
+
super rescue @settings.send(setting)
|
42
|
+
end
|
43
|
+
|
44
|
+
def deep_merge(h1, h2)
|
45
|
+
h1.merge!(h2) do |key, v1, v2|
|
46
|
+
v1.is_a?(Hash) && v2.is_a?(Hash) ? deep_merge(v1, v2) : v2
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def propagate_attr_reader(settings)
|
51
|
+
settings.each_value do |setting_value|
|
52
|
+
if setting_value.is_a? Hash
|
53
|
+
setting_value.extend(AttrReader)
|
54
|
+
propagate_attr_reader(setting_value)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# NOTE: Settings with a value of 'default overriden' should never be accessible.
|
2
|
+
default:
|
3
|
+
a: 'default overriden'
|
4
|
+
c:
|
5
|
+
a:
|
6
|
+
a: 'default overriden'
|
7
|
+
b: 'default c.a.b'
|
8
|
+
b: 'default c.b'
|
9
|
+
c: 'default overriden'
|
10
|
+
d:
|
11
|
+
a: 'default d.a'
|
12
|
+
e:
|
13
|
+
a:
|
14
|
+
a: 'default overriden'
|
15
|
+
b: 'default overriden'
|
16
|
+
b:
|
17
|
+
a: 'default e.b.a'
|
18
|
+
b: 'default overriden'
|
19
|
+
f:
|
20
|
+
- 'default 0'
|
21
|
+
- 'default 1'
|
22
|
+
g:
|
23
|
+
- 'default overriden'
|
24
|
+
- 'default overriden'
|
25
|
+
- 'default overriden'
|
26
|
+
:h: 'default h'
|
27
|
+
i:
|
28
|
+
a: 'default i.a'
|
29
|
+
j:
|
30
|
+
a:
|
31
|
+
a: 'default j.a.a'
|
32
|
+
k:
|
33
|
+
a: 'default overriden'
|
34
|
+
b: 'default overriden'
|
35
|
+
c: 'default overriden'
|
36
|
+
d: 'default k.d'
|
37
|
+
l:
|
38
|
+
a: 'default overriden'
|
39
|
+
b: 'default overriden'
|
40
|
+
m: 'default m'
|
41
|
+
|
42
|
+
test:
|
43
|
+
a: 'test a'
|
44
|
+
b:
|
45
|
+
a: 'test b.a'
|
46
|
+
b: 'test b.b'
|
47
|
+
c:
|
48
|
+
a:
|
49
|
+
a: 'test c.a.a'
|
50
|
+
c: 'test c.c'
|
51
|
+
d:
|
52
|
+
b: 'test d.b'
|
53
|
+
e:
|
54
|
+
a:
|
55
|
+
a: 'test e.a.a'
|
56
|
+
b: 'test e.a.b'
|
57
|
+
b:
|
58
|
+
b: 'test e.b.b'
|
59
|
+
g:
|
60
|
+
- 'test 0'
|
61
|
+
- 'test 1'
|
62
|
+
k:
|
63
|
+
a: 'test k.a'
|
64
|
+
b: 'test k.b'
|
65
|
+
c: 'test k.c'
|
66
|
+
e: 'test k.e'
|
67
|
+
l: 'test l'
|
68
|
+
m:
|
69
|
+
a: 'test m.a'
|
70
|
+
|
71
|
+
development:
|
72
|
+
a: 'development a'
|
73
|
+
|
74
|
+
production:
|
75
|
+
a: 'production a'
|
76
|
+
k:
|
77
|
+
a: 'production k.a'
|
78
|
+
b: 'production overriden'
|
79
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
describe 'README Examples' do
|
2
|
+
|
3
|
+
should 'load database settings' do
|
4
|
+
yaml = File.join(File.dirname(__FILE__), "fixtures", "example_database.yml")
|
5
|
+
|
6
|
+
settings = YAMLSettings.new(yaml, :production)
|
7
|
+
settings.db.host.should == "db.example.com"
|
8
|
+
settings.db.user.should == "dbusr"
|
9
|
+
settings.db.name.should == "myapp"
|
10
|
+
settings.db.pass.should == "/var/www/sites/myapp/db-access"
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
require 'yaml_settings'
|
2
|
+
|
3
|
+
describe YAMLSettings do
|
4
|
+
|
5
|
+
def fixture name
|
6
|
+
File.join(File.dirname(__FILE__), "fixtures", "#{name}.yml")
|
7
|
+
end
|
8
|
+
|
9
|
+
ys = YAMLSettings.new(fixture(:default), :test)
|
10
|
+
|
11
|
+
should 'load and merge multiple YAML files' do
|
12
|
+
p = YAMLSettings.new(
|
13
|
+
fixture(:default),
|
14
|
+
fixture(:private),
|
15
|
+
:production
|
16
|
+
)
|
17
|
+
p.a. should == 'production a [private]'
|
18
|
+
p.k.a.should == 'production k.a'
|
19
|
+
p.k.b.should == 'production k.b [private]'
|
20
|
+
p.k.c.should == 'production k.c [private]'
|
21
|
+
p.k.d.should == 'default k.d'
|
22
|
+
end
|
23
|
+
|
24
|
+
should 'allow either a string or symbol for environment parameter' do
|
25
|
+
str = YAMLSettings.new(fixture(:default), 'development')
|
26
|
+
sym = YAMLSettings.new(fixture(:default), :development)
|
27
|
+
str.a.should == 'development a'
|
28
|
+
sym.a.should == 'development a'
|
29
|
+
end
|
30
|
+
|
31
|
+
should 'allow only string environment keys in YAML files' do
|
32
|
+
should.raise(KeyError) {
|
33
|
+
YAMLSettings.new(fixture(:symbol_keys), :development)
|
34
|
+
}.message.should.equal 'key not found: "default"'
|
35
|
+
end
|
36
|
+
|
37
|
+
should 'allow just a "default" stanza in YAML file' do
|
38
|
+
default = YAMLSettings.new(fixture(:default_only), :default)
|
39
|
+
default.setting_1.should.equal 'setting 1'
|
40
|
+
end
|
41
|
+
|
42
|
+
should 'raise if "default" stanza does not exist' do
|
43
|
+
should.raise(KeyError) {
|
44
|
+
YAMLSettings.new(fixture(:default_missing), :development)
|
45
|
+
}.message.should.equal 'key not found: "default"'
|
46
|
+
end
|
47
|
+
|
48
|
+
should 'raise if specified environment does not exist' do
|
49
|
+
should.raise(KeyError) { # single file
|
50
|
+
YAMLSettings.new(fixture(:default), "nonexistent")
|
51
|
+
}.message.should.equal 'key not found: "nonexistent"'
|
52
|
+
|
53
|
+
should.raise(KeyError) { # multiple files
|
54
|
+
YAMLSettings.new(fixture(:default_only),
|
55
|
+
fixture(:default),
|
56
|
+
fixture(:private),
|
57
|
+
"nonexistent")
|
58
|
+
}.message.should.equal 'key not found: "nonexistent"'
|
59
|
+
end
|
60
|
+
|
61
|
+
should 'delegate to a Hash object' do
|
62
|
+
[:hash, :key, :keys, :each_value, :merge, :rehash].each do |hash_method|
|
63
|
+
ys.public_methods.should.include? hash_method
|
64
|
+
end
|
65
|
+
ys.__getobj__.class.should.equal Hash
|
66
|
+
end
|
67
|
+
|
68
|
+
should 'act like a Hash' do
|
69
|
+
ys.keys.should == # "b" not in default
|
70
|
+
["a", "c", "d", "e", "f", "g", :h, "i", "j", "k", "l", "m", "b"]
|
71
|
+
ys.values.count.should == 13
|
72
|
+
ys['a'].should == 'test a'
|
73
|
+
end
|
74
|
+
|
75
|
+
should 'allow method call for symbol keys' do
|
76
|
+
ys.h.should == ys[:h]
|
77
|
+
end
|
78
|
+
|
79
|
+
should 'raise when accessing nonexistent settings via method call' do
|
80
|
+
[ -> { ys. mia_setting }, # TOP level
|
81
|
+
-> { ys.b. mia_setting }, # 2nd level
|
82
|
+
-> { ys.c.a.mia_setting }, # 3rd level
|
83
|
+
-> { ys.i. mia_setting }, # 2nd level from default
|
84
|
+
-> { ys.j.a.mia_setting } # 3nd level from default
|
85
|
+
].each do |setting|
|
86
|
+
should.raise(KeyError) { setting.call }.
|
87
|
+
message.should.equal 'key not found: "mia_setting"'
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
should 'not raise when accessing nonexistent settings via hash bracket' do
|
92
|
+
[ -> { ys['mia_setting'] },
|
93
|
+
-> { ys.d['mia_setting'] }
|
94
|
+
].each do |setting|
|
95
|
+
should.not.raise { setting.call }
|
96
|
+
setting.call.should.equal nil
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
should 'return non-default setting from each environment' do
|
101
|
+
%w(development production test).each do |env|
|
102
|
+
YAMLSettings.new(fixture(:default), env).a.should == env+' a'
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
should 'return settings using hash bracket or method call at any level' do
|
107
|
+
i = 'test e.a.b'
|
108
|
+
ys['e']['a']['b'].should == i # 000
|
109
|
+
ys['e']['a'] .b .should == i # 001
|
110
|
+
ys['e'] .a[ 'b'].should == i # 010
|
111
|
+
ys['e'] .a .b .should == i # 011
|
112
|
+
ys .e[ 'a']['b'].should == i # 100
|
113
|
+
ys .e[ 'a'] .b .should == i # 101
|
114
|
+
ys .e .a[ 'b'].should == i # 110
|
115
|
+
ys .e .a .b .should == i # 111
|
116
|
+
end
|
117
|
+
|
118
|
+
should 'return default string settings at multiple levels' do
|
119
|
+
ys.c.a.b.should == 'default c.a.b'
|
120
|
+
ys.c.b. should == 'default c.b'
|
121
|
+
ys.d.a. should == 'default d.a'
|
122
|
+
ys.e.b.a.should == 'default e.b.a'
|
123
|
+
end
|
124
|
+
|
125
|
+
should 'return non-defualt string settings at multiple levels' do
|
126
|
+
ys.a. should == 'test a'
|
127
|
+
ys.b.a. should == 'test b.a'
|
128
|
+
ys.b.b. should == 'test b.b'
|
129
|
+
ys.c.a.a.should == 'test c.a.a'
|
130
|
+
ys.c.c. should == 'test c.c'
|
131
|
+
ys.d.b. should == 'test d.b'
|
132
|
+
ys.e.a.a.should == 'test e.a.a'
|
133
|
+
ys.e.a.b.should == 'test e.a.b'
|
134
|
+
ys.e.b.b.should == 'test e.b.b'
|
135
|
+
end
|
136
|
+
|
137
|
+
should 'only override hash values for duplicate keys' do
|
138
|
+
ys.k.a.should == 'test k.a'
|
139
|
+
ys.k.b.should == 'test k.b'
|
140
|
+
ys.k.c.should == 'test k.c'
|
141
|
+
ys.k.d.should == 'default k.d'
|
142
|
+
ys.k.e.should == 'test k.e'
|
143
|
+
end
|
144
|
+
|
145
|
+
should 'override default hash with string value' do
|
146
|
+
ys.l.should == 'test l'
|
147
|
+
should.raise(NoMethodError) { ys.l.a } # no access to default hash
|
148
|
+
end
|
149
|
+
|
150
|
+
should 'override default string value with hash' do
|
151
|
+
ys.m.class.should.equal Hash
|
152
|
+
ys.m.keys.count.should == 1
|
153
|
+
end
|
154
|
+
|
155
|
+
should 'return default array setting' do
|
156
|
+
ys.f[0].should == 'default 0'
|
157
|
+
ys.f[1].should == 'default 1'
|
158
|
+
end
|
159
|
+
|
160
|
+
should 'return non-default array setting' do
|
161
|
+
ys.g[0].should == 'test 0'
|
162
|
+
ys.g[1].should == 'test 1'
|
163
|
+
ys.g[2].should.be.nil # unlike hash, duplicate indexes not preserved
|
164
|
+
ys.g.size.should == 2
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'yaml_settings'
|
3
|
+
s.version = File.read('lib/yaml_settings.rb')[/VERSION = '(.*)'/, 1]
|
4
|
+
s.author = 'Clint Pachl'
|
5
|
+
s.email = 'pachl@ecentryx.com'
|
6
|
+
s.homepage = 'https://ecentryx.com/gems/yaml_settings'
|
7
|
+
s.license = 'ISC'
|
8
|
+
s.summary = 'Load and merge application settings from YAML files'
|
9
|
+
s.description = <<-EOS
|
10
|
+
YAMLSettings loads and recursively merges settings from one or more YAML data
|
11
|
+
files. A settings group—specified by key (e.g., environment variable)—is merged
|
12
|
+
with any default settings to create a coherent hash of settings.
|
13
|
+
EOS
|
14
|
+
s.files = Dir[
|
15
|
+
'Rakefile',
|
16
|
+
'README*',
|
17
|
+
'*.gemspec',
|
18
|
+
'lib/*.rb',
|
19
|
+
'spec/**/*',
|
20
|
+
'.rdoc_options'
|
21
|
+
]
|
22
|
+
s.extra_rdoc_files = ['README.rdoc']
|
23
|
+
s.rdoc_options = [
|
24
|
+
'--title', "YAMLSettings Ruby Gem: #{s.summary}",
|
25
|
+
'--main', 'README.rdoc'
|
26
|
+
]
|
27
|
+
s.required_ruby_version = '>= 2.2'
|
28
|
+
s.add_development_dependency 'bacon', '~> 1.2'
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: yaml_settings
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.6
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Clint Pachl
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-06-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bacon
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.2'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.2'
|
27
|
+
description: |
|
28
|
+
YAMLSettings loads and recursively merges settings from one or more YAML data
|
29
|
+
files. A settings group—specified by key (e.g., environment variable)—is merged
|
30
|
+
with any default settings to create a coherent hash of settings.
|
31
|
+
email: pachl@ecentryx.com
|
32
|
+
executables: []
|
33
|
+
extensions: []
|
34
|
+
extra_rdoc_files:
|
35
|
+
- README.rdoc
|
36
|
+
files:
|
37
|
+
- ".rdoc_options"
|
38
|
+
- README.rdoc
|
39
|
+
- Rakefile
|
40
|
+
- lib/yaml_settings.rb
|
41
|
+
- spec/fixtures/default.yml
|
42
|
+
- spec/fixtures/default_missing.yml
|
43
|
+
- spec/fixtures/default_only.yml
|
44
|
+
- spec/fixtures/example_database.yml
|
45
|
+
- spec/fixtures/private.yml
|
46
|
+
- spec/fixtures/symbol_keys.yml
|
47
|
+
- spec/spec_readme_examples.rb
|
48
|
+
- spec/spec_yaml_settings.rb
|
49
|
+
- yaml_settings.gemspec
|
50
|
+
homepage: https://ecentryx.com/gems/yaml_settings
|
51
|
+
licenses:
|
52
|
+
- ISC
|
53
|
+
metadata: {}
|
54
|
+
post_install_message:
|
55
|
+
rdoc_options:
|
56
|
+
- "--title"
|
57
|
+
- 'YAMLSettings Ruby Gem: Load and merge application settings from YAML files'
|
58
|
+
- "--main"
|
59
|
+
- README.rdoc
|
60
|
+
require_paths:
|
61
|
+
- lib
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '2.2'
|
67
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
requirements: []
|
73
|
+
rubyforge_project:
|
74
|
+
rubygems_version: 2.6.12
|
75
|
+
signing_key:
|
76
|
+
specification_version: 4
|
77
|
+
summary: Load and merge application settings from YAML files
|
78
|
+
test_files: []
|