configue 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/MIT-LICENSE +20 -0
- data/README.md +15 -13
- data/configue.gemspec +1 -1
- data/lib/configue.rb +1 -1
- data/lib/configue/container.rb +55 -13
- data/lib/configue/container_adapter.rb +33 -0
- data/lib/configue/criteria.rb +2 -2
- data/lib/configue/merger.rb +22 -0
- data/lib/configue/node.rb +48 -0
- data/lib/configue/setting.rb +34 -31
- data/lib/configue/source_loader.rb +44 -0
- data/spec/{configue/basic_spec.rb → basic_spec.rb} +19 -3
- data/spec/config_spec.rb +20 -0
- data/spec/configue/merger_spec.rb +114 -0
- data/spec/{configue/namespace_spec.rb → namespace_spec.rb} +3 -3
- data/spec/{base_namespace_conf.rb → samples/base_namespace_conf.rb} +0 -0
- data/spec/samples/config/admin.yml +6 -0
- data/spec/samples/config/test.yml +6 -0
- data/spec/samples/config_conf.rb +6 -0
- data/spec/{multiple_yaml → samples/multiple_yaml}/foo/baa.yml +0 -0
- data/spec/{multiple_yaml → samples/multiple_yaml}/foo/bar/ding.yml +0 -0
- data/spec/{multiple_yaml → samples/multiple_yaml}/foo/bar/tick.yml +0 -0
- data/spec/{multiple_yaml → samples/multiple_yaml}/foo/pee.yml +0 -0
- data/spec/{multiple_yaml_conf.rb → samples/multiple_yaml_conf.rb} +0 -0
- data/spec/{namespace → samples/namespace}/base/pee/kaa/conf.yml +0 -0
- data/spec/{namespace → samples/namespace}/dev/pee/kaa/conf.yml +0 -0
- data/spec/{namespace → samples/namespace}/test/pee/kaa/conf.yml +0 -0
- data/spec/{namespace_conf.rb → samples/namespace_conf.rb} +0 -0
- data/spec/samples/signs/config.yml +4 -0
- data/spec/samples/signs_conf.rb +5 -0
- data/spec/samples/single_source_conf.rb +7 -0
- data/spec/{single_yaml → samples/single_yaml}/conf.yml +0 -0
- data/spec/{single_yaml_conf.rb → samples/single_yaml_conf.rb} +0 -0
- data/spec/signs_spec.rb +51 -0
- data/spec/support/inner_hash.rb +3 -3
- metadata +53 -31
- data/lib/configue/inner_hash.rb +0 -53
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fe53fc0c3969215bf80141f59536a4027c80009c
|
4
|
+
data.tar.gz: 6048c54717f66a3c840cc1f4d6af57cffb488c27
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fffd57a26f941018cb692adb873071164c7a7df8f00811da59e1701f273279edd42072ee210be137338bf7e56fc7bf0631bca726918dc17ab29356fab8ef335d
|
7
|
+
data.tar.gz: 9588c1c6d5c29df1dea602ad9a66667705d5010bc2e15f27526c08ac495ff908e4cd4204ab37697d24dad832d2ac75799acec104e15b86d49ae5973c7de52968
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2014 hosim <github.hosim@gmail.com>
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Configue
|
2
2
|
Configue is a configuration / settings solution that uses YAML files.
|
3
|
-
It is almost a fork of SettingsLogic.
|
3
|
+
It is almost a fork of [SettingsLogic](https://github.com/binarylogic/settingslogic).
|
4
4
|
Configue can read multiple YAML files and you can use big configuration data
|
5
5
|
simply.
|
6
6
|
|
@@ -20,30 +20,28 @@ end
|
|
20
20
|
### Write your settings in YAML file
|
21
21
|
```yaml
|
22
22
|
# config/accounts/admin_users.yml
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
- sneezy
|
23
|
+
accounts:
|
24
|
+
admin_users:
|
25
|
+
- grumpy
|
26
|
+
- sneezy
|
28
27
|
```
|
29
28
|
|
30
29
|
You can make multiple settings files.
|
31
30
|
|
32
31
|
```yaml
|
33
32
|
# config/accounts/test_users.yml
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
- dopey
|
33
|
+
accounts:
|
34
|
+
test_users:
|
35
|
+
- sleepy
|
36
|
+
- dopey
|
39
37
|
```
|
40
38
|
|
41
39
|
### Access your settings
|
42
40
|
```
|
43
|
-
>> MyConf.
|
41
|
+
>> MyConf.accounts.admin_users
|
44
42
|
=> ["grumpy", "sneezy"]
|
45
43
|
|
46
|
-
>> MyConf.
|
44
|
+
>> MyConf.accounts.test_users
|
47
45
|
=> ["sleepy", "dopey"]
|
48
46
|
```
|
49
47
|
|
@@ -81,7 +79,9 @@ test:
|
|
81
79
|
- foo
|
82
80
|
- woo
|
83
81
|
```
|
82
|
+
|
84
83
|
and define a class for the settings
|
84
|
+
|
85
85
|
```ruby
|
86
86
|
class MyConf < Configue::Container
|
87
87
|
config.source_dir "#{File.dirname(__FILE__)}/config/settings"
|
@@ -89,7 +89,9 @@ class MyConf < Configue::Container
|
|
89
89
|
config.namespace :test
|
90
90
|
end
|
91
91
|
```
|
92
|
+
|
92
93
|
you can access it in the following manner:
|
94
|
+
|
93
95
|
```
|
94
96
|
>> MyConf.foo.baa
|
95
97
|
=> ["boo", "foo", "woo"]
|
data/configue.gemspec
CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |s|
|
|
12
12
|
s.files = `git ls-files`.split("\n")
|
13
13
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
14
14
|
s.require_paths = ["lib"]
|
15
|
-
s.version = "0.1.
|
15
|
+
s.version = "0.1.2"
|
16
16
|
s.license = "MIT"
|
17
17
|
|
18
18
|
s.add_development_dependency 'rspec'
|
data/lib/configue.rb
CHANGED
data/lib/configue/container.rb
CHANGED
@@ -1,33 +1,75 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
|
-
require "
|
3
|
+
require "configue/container_adapter"
|
4
4
|
require "configue/criteria"
|
5
5
|
|
6
6
|
module Configue
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
7
|
+
# +Configue::Container+ is a setting solution using a YAML file.
|
8
|
+
#
|
9
|
+
# When you have such configuration files:
|
10
|
+
#
|
11
|
+
# # config/accounts/admin_users.yml
|
12
|
+
# accounts:
|
13
|
+
# admin_users:
|
14
|
+
# - grumpy
|
15
|
+
# - sneezy
|
16
|
+
#
|
17
|
+
# # config/accounts/test_users.yml
|
18
|
+
# accounts:
|
19
|
+
# test_users:
|
20
|
+
# - sleepy
|
21
|
+
# - dopey
|
22
|
+
#
|
23
|
+
# this could be:
|
24
|
+
#
|
25
|
+
# class Foo < Configue::Container
|
26
|
+
# config.source_dir "#{File.dirname(__FILE__)}/config"
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# Foo.accounts.admin_users
|
30
|
+
# # => ["grumpy", "sneezy"]
|
31
|
+
#
|
32
|
+
# Foo.accounts.test_users
|
33
|
+
# # => ["sleepy", "dopey"]
|
34
|
+
#
|
35
|
+
class Container < Node
|
15
36
|
|
37
|
+
# When you do not know the setting has keys that you want to
|
38
|
+
# specify and want to avoid +NoMethodError+, you could use
|
39
|
+
# +query+ and +retrieve+.
|
40
|
+
#
|
41
|
+
# Foo.query("accounts.admin_users").retrieve
|
42
|
+
# # => ["grumpy", "sneezy"]
|
43
|
+
#
|
44
|
+
# Foo.query("users.admin_users").retrieve
|
45
|
+
# # => nil
|
46
|
+
#
|
47
|
+
# Foo.query[:accounts][:admin_users].retrieve
|
48
|
+
# # => ["grumpy", "sneezy"]
|
49
|
+
#
|
16
50
|
def query(key=nil)
|
17
|
-
q = Criteria.new(
|
51
|
+
q = Criteria.new(self)
|
18
52
|
q = key.split('.').each.inject(q) {|c, k| c[k] } if key
|
19
53
|
q
|
20
54
|
end
|
21
55
|
|
22
56
|
class << self
|
57
|
+
# +config+ allows you to access the object for setting container.
|
23
58
|
def config
|
24
|
-
@
|
59
|
+
@config_access_name = "config"
|
60
|
+
@setting ||= Setting.new(ContainerAdapter.new(self))
|
61
|
+
end
|
62
|
+
|
63
|
+
def config_setting
|
64
|
+
@config_access_name = "config_setting"
|
65
|
+
@setting ||= Setting.new(ContainerAdapter.new(self))
|
25
66
|
end
|
26
|
-
alias_method :config_setting, :config
|
27
67
|
|
28
68
|
private
|
29
69
|
def method_missing(name, *args, &block)
|
30
|
-
@instance
|
70
|
+
# makes @instance in this line.
|
71
|
+
@setting.load!
|
72
|
+
|
31
73
|
if @instance.key?(name)
|
32
74
|
@instance[name]
|
33
75
|
else
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Configue
|
4
|
+
class ContainerAdapter
|
5
|
+
def initialize(container_class)
|
6
|
+
@class = container_class
|
7
|
+
end
|
8
|
+
|
9
|
+
def new_container(hash)
|
10
|
+
self.instance = @class.new(hash)
|
11
|
+
end
|
12
|
+
|
13
|
+
def instance
|
14
|
+
@class.instance_variable_get(:@instance)
|
15
|
+
end
|
16
|
+
|
17
|
+
def instance=(arg)
|
18
|
+
raise TypeError unless arg.respond_to?(:[]) or arg.respond_to?(:keys)
|
19
|
+
|
20
|
+
@class.instance_variable_set(:@instance, arg)
|
21
|
+
sig = class << @class; self; end
|
22
|
+
arg.keys.each do |k|
|
23
|
+
next unless k.to_s =~ /\A\w[\w0-9]*\z/
|
24
|
+
sig.__send__(:define_method, k, -> { arg[k] })
|
25
|
+
end
|
26
|
+
arg
|
27
|
+
end
|
28
|
+
|
29
|
+
def config_method_name
|
30
|
+
@class.instance_variable_get(:@config_access_name)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/configue/criteria.rb
CHANGED
@@ -13,14 +13,14 @@ module Configue
|
|
13
13
|
|
14
14
|
def retrieve
|
15
15
|
@path.each.inject(@hash) do |h, key|
|
16
|
-
return nil unless h.
|
16
|
+
return nil unless h.respond_to?(:has_key?) and h.has_key?(key)
|
17
17
|
h[key]
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
21
|
def exist?
|
22
22
|
@path.each.inject(@hash) do |h, key|
|
23
|
-
return false unless h.
|
23
|
+
return false unless h.respond_to?(:has_key?) and h.has_key?(key)
|
24
24
|
h[key]
|
25
25
|
end
|
26
26
|
true
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Configue
|
4
|
+
module Merger
|
5
|
+
def merge(hash1, hash2)
|
6
|
+
return hash2 unless hash1
|
7
|
+
return hash1 unless hash2
|
8
|
+
|
9
|
+
merger = ->(key, h1, h2) {
|
10
|
+
if h1.is_a?(Hash) and h2.is_a?(Hash)
|
11
|
+
h1.merge(h2, &merger)
|
12
|
+
else
|
13
|
+
h2
|
14
|
+
end
|
15
|
+
}
|
16
|
+
|
17
|
+
hash1.merge(hash2, &merger)
|
18
|
+
end
|
19
|
+
|
20
|
+
module_function :merge
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Configue
|
4
|
+
class Node
|
5
|
+
def initialize(hash)
|
6
|
+
raise TypeError unless hash.respond_to?(:[])
|
7
|
+
|
8
|
+
sig = class << self; self; end
|
9
|
+
@hash = hash.each.inject({}) do |h, (k, v)|
|
10
|
+
sig.__send__(:define_method, k, ->{ self[k] })
|
11
|
+
h[k.to_s] = v; h
|
12
|
+
end
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
def [](key)
|
17
|
+
k = key.to_s
|
18
|
+
v = @hash[k]
|
19
|
+
@hash[k] = self.class.new(v) if v.is_a?(Hash)
|
20
|
+
@hash[k]
|
21
|
+
end
|
22
|
+
|
23
|
+
def fetch(key)
|
24
|
+
k = key.to_s
|
25
|
+
v = @hash[key]
|
26
|
+
@hash[k] = self.class.new(v) if v.is_a?(Hash)
|
27
|
+
@hash.fetch(k)
|
28
|
+
end
|
29
|
+
|
30
|
+
def key?(key)
|
31
|
+
k = key.to_s
|
32
|
+
@hash.key?(k)
|
33
|
+
end
|
34
|
+
alias_method :has_key?, :key?
|
35
|
+
|
36
|
+
def keys
|
37
|
+
@hash.keys
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_hash
|
41
|
+
@hash.dup
|
42
|
+
end
|
43
|
+
|
44
|
+
def to_s
|
45
|
+
@hash.to_s
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/configue/setting.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
|
+
require "configue/merger"
|
4
|
+
require "configue/source_loader"
|
3
5
|
require "configue/yaml_loader"
|
4
6
|
|
5
7
|
module Configue
|
6
8
|
class Setting
|
7
9
|
def initialize(owner_class)
|
8
|
-
@
|
10
|
+
@owner = owner_class
|
9
11
|
@loader = YamlLoader.new
|
10
12
|
end
|
11
13
|
|
@@ -28,9 +30,9 @@ module Configue
|
|
28
30
|
end
|
29
31
|
|
30
32
|
def source_dir(*dirs)
|
31
|
-
@
|
32
|
-
@
|
33
|
-
@
|
33
|
+
@sources ||= []
|
34
|
+
@sources += dirs.map {|d| {dir: d}} unless dirs.empty?
|
35
|
+
@sources
|
34
36
|
end
|
35
37
|
|
36
38
|
def source_dir=(dir)
|
@@ -41,42 +43,43 @@ module Configue
|
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
44
|
-
def
|
45
|
-
|
46
|
+
def source_file(*files)
|
47
|
+
@sources ||= []
|
48
|
+
@sources += files.map {|f| {file: f}} unless files.empty?
|
49
|
+
@sources
|
50
|
+
end
|
46
51
|
|
47
|
-
|
48
|
-
|
49
|
-
base = base_namespace.to_s
|
50
|
-
result = InnerHash.new
|
51
|
-
result.deep_merge!(hash[base]) if base_namespace
|
52
|
-
result.deep_merge!(hash[space]) if hash[space]
|
53
|
-
hash = result
|
54
|
-
end
|
55
|
-
hash
|
52
|
+
def load!
|
53
|
+
@owner.instance ? @owner.instance : @owner.new_container(load_sources)
|
56
54
|
end
|
57
55
|
|
58
56
|
private
|
59
57
|
def load_sources
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
namespaced_hash(root, source)
|
65
|
-
else
|
66
|
-
root.deep_merge!(source)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
root
|
70
|
-
end
|
58
|
+
loader = SourceLoader.new(@loader, @sources, @namespace, @base_namespace)
|
59
|
+
hash = loader.load
|
60
|
+
hash = namespaced_hash(hash) if namespace
|
61
|
+
hash
|
71
62
|
end
|
72
63
|
|
73
|
-
def namespaced_hash(
|
74
|
-
base = base_namespace.to_s
|
64
|
+
def namespaced_hash(hash)
|
75
65
|
space = namespace.to_s
|
66
|
+
base = base_namespace.to_s
|
67
|
+
result = {}
|
68
|
+
result = Merger.merge(result, hash[base]) if base_namespace
|
69
|
+
result = Merger.merge(result, hash[space]) if hash.key?(space)
|
70
|
+
result
|
71
|
+
end
|
76
72
|
|
77
|
-
|
78
|
-
|
79
|
-
|
73
|
+
def method_missing(name, *args, &block)
|
74
|
+
access_name = @owner.config_method_name
|
75
|
+
return super unless access_name
|
76
|
+
|
77
|
+
instance = self.load!
|
78
|
+
if instance[access_name]
|
79
|
+
instance[access_name].__send__(name, *args, &block)
|
80
|
+
else
|
81
|
+
super
|
82
|
+
end
|
80
83
|
end
|
81
84
|
end
|
82
85
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require "configue/merger"
|
4
|
+
|
5
|
+
module Configue
|
6
|
+
class SourceLoader
|
7
|
+
def initialize(loader, sources, namespace=nil, base_namespace=nil)
|
8
|
+
@loader = loader
|
9
|
+
@sources = sources
|
10
|
+
@namespace = namespace.to_s if namespace
|
11
|
+
@basespace = base_namespace.to_s if base_namespace
|
12
|
+
end
|
13
|
+
|
14
|
+
def load
|
15
|
+
@sources.each do |src|
|
16
|
+
src.each {|k, v| __send__("load_#{k}", v) }
|
17
|
+
end
|
18
|
+
@hash
|
19
|
+
end
|
20
|
+
|
21
|
+
protected
|
22
|
+
def load_dir(dir)
|
23
|
+
Dir.glob("#{dir}/**/*.#{@loader.extention}") do |file|
|
24
|
+
load_file(file)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def load_file(file)
|
29
|
+
source = @loader.load(file)
|
30
|
+
if @namespace and source[@namespace]
|
31
|
+
namespaced_hash(source)
|
32
|
+
else
|
33
|
+
@hash = Merger.merge(@hash, source)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def namespaced_hash(hash)
|
38
|
+
if @basespace and hash.key?(@basespace)
|
39
|
+
@hash = Merger.merge(@hash, @basespace => hash[@basespace])
|
40
|
+
end
|
41
|
+
@hash = Merger.merge(@hash, @namespace => hash[@namespace])
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
require File.expand_path("
|
2
|
+
require File.expand_path("../spec_helper", __FILE__)
|
3
3
|
|
4
4
|
describe "Configue::Container" do
|
5
5
|
context "when reading a single yaml file" do
|
6
|
-
require
|
6
|
+
require File.expand_path("../samples/single_yaml_conf", __FILE__)
|
7
7
|
|
8
8
|
context "1st level" do
|
9
9
|
it_should_behave_like "an InnerHash instance",
|
@@ -22,7 +22,7 @@ describe "Configue::Container" do
|
|
22
22
|
end
|
23
23
|
|
24
24
|
context "when reading multiple yaml files" do
|
25
|
-
require
|
25
|
+
require File.expand_path("../samples/multiple_yaml_conf", __FILE__)
|
26
26
|
|
27
27
|
context "1st level" do
|
28
28
|
it_should_behave_like "an InnerHash instance",
|
@@ -46,4 +46,20 @@ describe "Configue::Container" do
|
|
46
46
|
{"ding" => ["dong", "dang"], "tick" => ["tack", "toe"]}
|
47
47
|
end
|
48
48
|
end
|
49
|
+
|
50
|
+
context "when reading a single yaml with source_file" do
|
51
|
+
require File.expand_path("../samples/single_source_conf", __FILE__)
|
52
|
+
|
53
|
+
context "1st level" do
|
54
|
+
it_should_behave_like "an InnerHash instance",
|
55
|
+
SingleSourceConf,
|
56
|
+
{"config" => ["accounts"]}
|
57
|
+
end
|
58
|
+
|
59
|
+
context "2nd level" do
|
60
|
+
it_should_behave_like "an InnerHash instance",
|
61
|
+
SingleSourceConf["config"],
|
62
|
+
{"accounts" => ["admin_users"]}
|
63
|
+
end
|
64
|
+
end
|
49
65
|
end
|
data/spec/config_spec.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require File.expand_path("../spec_helper", __FILE__)
|
3
|
+
|
4
|
+
describe "Configue::Container" do
|
5
|
+
context "when a top key is 'config' in the setting files" do
|
6
|
+
require File.expand_path("../samples/config_conf", __FILE__)
|
7
|
+
|
8
|
+
context "1st level" do
|
9
|
+
it_should_behave_like "an InnerHash instance",
|
10
|
+
ConfigConf,
|
11
|
+
{"config" => ["accounts"]}
|
12
|
+
end
|
13
|
+
|
14
|
+
context "2nd level" do
|
15
|
+
it_should_behave_like "an InnerHash instance",
|
16
|
+
ConfigConf["config"],
|
17
|
+
{"accounts" => ["admin_users", "test_users"]}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
3
|
+
|
4
|
+
describe Configue::Merger do
|
5
|
+
describe ".merge" do
|
6
|
+
context "when merging a hash with another hash" do
|
7
|
+
let(:former) do
|
8
|
+
{
|
9
|
+
a: {
|
10
|
+
aa: {
|
11
|
+
aaa: 1,
|
12
|
+
aab: 2,
|
13
|
+
},
|
14
|
+
ab: {
|
15
|
+
aba: 1,
|
16
|
+
abb: 2,
|
17
|
+
},
|
18
|
+
},
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
let(:latter) do
|
23
|
+
{
|
24
|
+
a: {
|
25
|
+
aa: {
|
26
|
+
aac: 3,
|
27
|
+
},
|
28
|
+
ab: {
|
29
|
+
abc: 3,
|
30
|
+
},
|
31
|
+
},
|
32
|
+
b: {
|
33
|
+
ba: {
|
34
|
+
baa: 1,
|
35
|
+
},
|
36
|
+
},
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
let(:expected) do
|
41
|
+
{
|
42
|
+
a: {
|
43
|
+
aa: {
|
44
|
+
aaa: 1,
|
45
|
+
aab: 2,
|
46
|
+
aac: 3,
|
47
|
+
},
|
48
|
+
ab: {
|
49
|
+
aba: 1,
|
50
|
+
abb: 2,
|
51
|
+
abc: 3,
|
52
|
+
},
|
53
|
+
},
|
54
|
+
b: {
|
55
|
+
ba: {
|
56
|
+
baa: 1,
|
57
|
+
},
|
58
|
+
},
|
59
|
+
}
|
60
|
+
end
|
61
|
+
|
62
|
+
it "returns a merged hash" do
|
63
|
+
actual = Configue::Merger.merge(former, latter)
|
64
|
+
expect(actual).to eq expected
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "when the latter is nil" do
|
69
|
+
let(:former) do
|
70
|
+
{
|
71
|
+
a: {
|
72
|
+
aa: 1,
|
73
|
+
},
|
74
|
+
}
|
75
|
+
end
|
76
|
+
|
77
|
+
let(:expected) do
|
78
|
+
{
|
79
|
+
a: {
|
80
|
+
aa: 1,
|
81
|
+
},
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
it "returns the former hash remaining without change" do
|
86
|
+
actual = Configue::Merger.merge(former, nil)
|
87
|
+
expect(actual).to eq expected
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context "when the former is nil" do
|
92
|
+
let(:latter) do
|
93
|
+
{
|
94
|
+
a: {
|
95
|
+
aa: 9,
|
96
|
+
},
|
97
|
+
}
|
98
|
+
end
|
99
|
+
|
100
|
+
let(:expected) do
|
101
|
+
{
|
102
|
+
a: {
|
103
|
+
aa: 9,
|
104
|
+
},
|
105
|
+
}
|
106
|
+
end
|
107
|
+
|
108
|
+
it "returns the latter remaining without change" do
|
109
|
+
actual = Configue::Merger.merge(nil, latter)
|
110
|
+
expect(actual).to eq expected
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
require File.expand_path("
|
2
|
+
require File.expand_path("../spec_helper", __FILE__)
|
3
3
|
|
4
4
|
describe "Configue::Container" do
|
5
5
|
context "when specifing 'namespace'" do
|
6
|
-
require
|
6
|
+
require File.expand_path("../samples/namespace_conf", __FILE__)
|
7
7
|
|
8
8
|
context "1st level" do
|
9
9
|
it_should_behave_like "an InnerHash instance",
|
@@ -25,7 +25,7 @@ describe "Configue::Container" do
|
|
25
25
|
end
|
26
26
|
|
27
27
|
context "when specifing 'namespace' and 'base_namespace'" do
|
28
|
-
require
|
28
|
+
require File.expand_path("../samples/base_namespace_conf", __FILE__)
|
29
29
|
|
30
30
|
context "1st level" do
|
31
31
|
it_should_behave_like "an InnerHash instance",
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/spec/signs_spec.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require File.expand_path("../spec_helper", __FILE__)
|
3
|
+
|
4
|
+
describe "Configue::Container" do
|
5
|
+
context "when reading a yaml file with keys included signs" do
|
6
|
+
require File.expand_path("../samples/signs_conf", __FILE__)
|
7
|
+
|
8
|
+
context "1st level" do
|
9
|
+
describe ".keys" do
|
10
|
+
it "returns keys described in the setting file" do
|
11
|
+
actual = SignsConf.keys
|
12
|
+
expect(actual).to match_array(["a top key with some spaces", "!@#$%^&*()_+"])
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe ".[]" do
|
17
|
+
it "returns a value associated with the parameter" do
|
18
|
+
actual = SignsConf["a top key with some spaces"].to_hash
|
19
|
+
expected = {"a key with some spaces" => "OK"}
|
20
|
+
expect(actual).to eq expected
|
21
|
+
|
22
|
+
actual = SignsConf["!@#$%^&*()_+"].to_hash
|
23
|
+
expected = {"+_)(*&^%$#@!" => "OK"}
|
24
|
+
expect(actual).to eq expected
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "2nd level" do
|
30
|
+
describe ".keys" do
|
31
|
+
it "returns keys described in the setting file" do
|
32
|
+
actual = SignsConf["a top key with some spaces"].keys
|
33
|
+
expect(actual).to match_array(["a key with some spaces"])
|
34
|
+
|
35
|
+
actual = SignsConf["!@#$%^&*()_+"].keys
|
36
|
+
expect(actual).to match_array(["+_)(*&^%$#@!"])
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe ".[]" do
|
41
|
+
it "returns a value associated with the parameter" do
|
42
|
+
actual = SignsConf["a top key with some spaces"]["a key with some spaces"]
|
43
|
+
expect(actual).to eq "OK"
|
44
|
+
|
45
|
+
actual = SignsConf["!@#$%^&*()_+"]["+_)(*&^%$#@!"]
|
46
|
+
expect(actual).to eq "OK"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/spec/support/inner_hash.rb
CHANGED
@@ -39,7 +39,7 @@ shared_examples_for "an InnerHash instance" do |object, hash|
|
|
39
39
|
context "when specifing the existing key names" do
|
40
40
|
it "returns a Hash value" do
|
41
41
|
hash.each do |key, value|
|
42
|
-
expect(object[key]).to be_a(
|
42
|
+
expect(object[key]).to be_a(Configue::Node) if value
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
@@ -55,7 +55,7 @@ shared_examples_for "an InnerHash instance" do |object, hash|
|
|
55
55
|
context "when specifing the existing key names in symbol" do
|
56
56
|
it "returns a Hash value" do
|
57
57
|
hash.each do |key, value|
|
58
|
-
expect(object[key.to_sym]).to be_a(
|
58
|
+
expect(object[key.to_sym]).to be_a(Configue::Node) if value
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
@@ -73,7 +73,7 @@ shared_examples_for "an InnerHash instance" do |object, hash|
|
|
73
73
|
context "when call methods which names are existing in the setting(s)" do
|
74
74
|
it "returns a Hash value" do
|
75
75
|
hash.each do |key, value|
|
76
|
-
expect(object.__send__(key)).to be_a(
|
76
|
+
expect(object.__send__(key)).to be_a(Configue::Node) if value
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: configue
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- hosim
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-04-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -32,29 +32,42 @@ extensions: []
|
|
32
32
|
extra_rdoc_files: []
|
33
33
|
files:
|
34
34
|
- Gemfile
|
35
|
+
- MIT-LICENSE
|
35
36
|
- README.md
|
36
37
|
- Rakefile
|
37
38
|
- configue.gemspec
|
38
39
|
- lib/configue.rb
|
39
40
|
- lib/configue/container.rb
|
41
|
+
- lib/configue/container_adapter.rb
|
40
42
|
- lib/configue/criteria.rb
|
41
|
-
- lib/configue/
|
43
|
+
- lib/configue/merger.rb
|
44
|
+
- lib/configue/node.rb
|
42
45
|
- lib/configue/setting.rb
|
46
|
+
- lib/configue/source_loader.rb
|
43
47
|
- lib/configue/yaml_loader.rb
|
44
|
-
- spec/
|
45
|
-
- spec/
|
46
|
-
- spec/configue/
|
47
|
-
- spec/
|
48
|
-
- spec/
|
49
|
-
- spec/
|
50
|
-
- spec/
|
51
|
-
- spec/
|
52
|
-
- spec/
|
53
|
-
- spec/
|
54
|
-
- spec/
|
55
|
-
- spec/
|
56
|
-
- spec/
|
57
|
-
- spec/
|
48
|
+
- spec/basic_spec.rb
|
49
|
+
- spec/config_spec.rb
|
50
|
+
- spec/configue/merger_spec.rb
|
51
|
+
- spec/namespace_spec.rb
|
52
|
+
- spec/samples/base_namespace_conf.rb
|
53
|
+
- spec/samples/config/admin.yml
|
54
|
+
- spec/samples/config/test.yml
|
55
|
+
- spec/samples/config_conf.rb
|
56
|
+
- spec/samples/multiple_yaml/foo/baa.yml
|
57
|
+
- spec/samples/multiple_yaml/foo/bar/ding.yml
|
58
|
+
- spec/samples/multiple_yaml/foo/bar/tick.yml
|
59
|
+
- spec/samples/multiple_yaml/foo/pee.yml
|
60
|
+
- spec/samples/multiple_yaml_conf.rb
|
61
|
+
- spec/samples/namespace/base/pee/kaa/conf.yml
|
62
|
+
- spec/samples/namespace/dev/pee/kaa/conf.yml
|
63
|
+
- spec/samples/namespace/test/pee/kaa/conf.yml
|
64
|
+
- spec/samples/namespace_conf.rb
|
65
|
+
- spec/samples/signs/config.yml
|
66
|
+
- spec/samples/signs_conf.rb
|
67
|
+
- spec/samples/single_source_conf.rb
|
68
|
+
- spec/samples/single_yaml/conf.yml
|
69
|
+
- spec/samples/single_yaml_conf.rb
|
70
|
+
- spec/signs_spec.rb
|
58
71
|
- spec/spec_helper.rb
|
59
72
|
- spec/support/inner_hash.rb
|
60
73
|
homepage: https://github.com/hosim/configue
|
@@ -82,19 +95,28 @@ signing_key:
|
|
82
95
|
specification_version: 4
|
83
96
|
summary: A simple configuration solution
|
84
97
|
test_files:
|
85
|
-
- spec/
|
86
|
-
- spec/
|
87
|
-
- spec/configue/
|
88
|
-
- spec/
|
89
|
-
- spec/
|
90
|
-
- spec/
|
91
|
-
- spec/
|
92
|
-
- spec/
|
93
|
-
- spec/
|
94
|
-
- spec/
|
95
|
-
- spec/
|
96
|
-
- spec/
|
97
|
-
- spec/
|
98
|
-
- spec/
|
98
|
+
- spec/basic_spec.rb
|
99
|
+
- spec/config_spec.rb
|
100
|
+
- spec/configue/merger_spec.rb
|
101
|
+
- spec/namespace_spec.rb
|
102
|
+
- spec/samples/base_namespace_conf.rb
|
103
|
+
- spec/samples/config/admin.yml
|
104
|
+
- spec/samples/config/test.yml
|
105
|
+
- spec/samples/config_conf.rb
|
106
|
+
- spec/samples/multiple_yaml/foo/baa.yml
|
107
|
+
- spec/samples/multiple_yaml/foo/bar/ding.yml
|
108
|
+
- spec/samples/multiple_yaml/foo/bar/tick.yml
|
109
|
+
- spec/samples/multiple_yaml/foo/pee.yml
|
110
|
+
- spec/samples/multiple_yaml_conf.rb
|
111
|
+
- spec/samples/namespace/base/pee/kaa/conf.yml
|
112
|
+
- spec/samples/namespace/dev/pee/kaa/conf.yml
|
113
|
+
- spec/samples/namespace/test/pee/kaa/conf.yml
|
114
|
+
- spec/samples/namespace_conf.rb
|
115
|
+
- spec/samples/signs/config.yml
|
116
|
+
- spec/samples/signs_conf.rb
|
117
|
+
- spec/samples/single_source_conf.rb
|
118
|
+
- spec/samples/single_yaml/conf.yml
|
119
|
+
- spec/samples/single_yaml_conf.rb
|
120
|
+
- spec/signs_spec.rb
|
99
121
|
- spec/spec_helper.rb
|
100
122
|
- spec/support/inner_hash.rb
|
data/lib/configue/inner_hash.rb
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
module Configue
|
4
|
-
class InnerHash < Hash
|
5
|
-
def initialize(source_hash=nil)
|
6
|
-
deep_merge!(source_hash) if source_hash
|
7
|
-
end
|
8
|
-
|
9
|
-
def deep_merge!(other)
|
10
|
-
deep_update(other)
|
11
|
-
|
12
|
-
sig = class << self; self; end
|
13
|
-
other.keys.each do |k|
|
14
|
-
sig.__send__(:define_method, k, ->{ self[k] })
|
15
|
-
end
|
16
|
-
self
|
17
|
-
end
|
18
|
-
|
19
|
-
def fetch(key, *args); super(key.to_s, *args); end
|
20
|
-
def delete(key); super(key.to_s); end
|
21
|
-
def key?(key); super(key.to_s); end
|
22
|
-
alias_method :has_key?, :key?
|
23
|
-
|
24
|
-
alias_method :_get_value, :[]
|
25
|
-
alias_method :_set_value, :[]=
|
26
|
-
private :_get_value
|
27
|
-
private :_set_value
|
28
|
-
|
29
|
-
def [](key)
|
30
|
-
value = _get_value(key.to_s)
|
31
|
-
value = self.class.new(value) if value.is_a? Hash
|
32
|
-
yield value if block_given?
|
33
|
-
value
|
34
|
-
end
|
35
|
-
|
36
|
-
def []=(key, value)
|
37
|
-
v = value
|
38
|
-
v = self.class.new(v) if v.is_a? Hash
|
39
|
-
_set_value(key.to_s, v)
|
40
|
-
end
|
41
|
-
|
42
|
-
protected
|
43
|
-
def deep_update(other_hash, &b)
|
44
|
-
other_hash.each do |k, v|
|
45
|
-
if v.is_a?(Hash)
|
46
|
-
v = self.key?(k) ? self[k].deep_update(v) : self.class.new(v)
|
47
|
-
end
|
48
|
-
self[k] = v
|
49
|
-
end
|
50
|
-
self
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|