confuse 0.1.8 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +112 -4
- data/Rakefile +7 -0
- data/confuse.gemspec +1 -0
- data/example/env_example.rb +10 -0
- data/example/example.ini +1 -0
- data/example/example.yaml +1 -0
- data/example/ini_example.rb +10 -0
- data/example/yaml_example.rb +11 -0
- data/lib/confuse.rb +23 -4
- data/lib/confuse/config.rb +22 -33
- data/lib/confuse/definition.rb +52 -0
- data/lib/confuse/errors.rb +12 -0
- data/lib/confuse/item.rb +20 -0
- data/lib/confuse/key_splitter.rb +40 -0
- data/lib/confuse/namespace.rb +6 -59
- data/lib/confuse/source.rb +34 -0
- data/lib/confuse/source/env.rb +28 -0
- data/lib/confuse/source/ini.rb +26 -0
- data/lib/confuse/source/yaml.rb +20 -0
- data/lib/confuse/version.rb +4 -1
- data/test/test_config.rb +27 -44
- data/test/test_confuse.rb +13 -0
- data/test/test_definition.rb +32 -0
- data/test/test_item.rb +21 -0
- data/test/test_key_splitter.rb +53 -0
- data/test/test_namespace.rb +7 -16
- metadata +40 -17
- data/example/001_simple_example.ini +0 -3
- data/example/001_simple_example.rb +0 -18
- data/example/002_namespace_example.rb +0 -29
- data/example/003_config_subclass_instance.ini +0 -2
- data/example/003_config_subclass_instance_example.rb +0 -9
- data/example/004_configured_by.rb +0 -26
- data/lib/confuse/config_item.rb +0 -38
- data/lib/confuse/config_mixin.rb +0 -135
- data/lib/confuse/configurable.rb +0 -15
- data/lib/confuse/dsl.rb +0 -68
- data/test/test_config_base.rb +0 -37
@@ -1,18 +0,0 @@
|
|
1
|
-
require 'configuration/configurable'
|
2
|
-
|
3
|
-
# An example of adding configuration options to a class.
|
4
|
-
class SimpleExample
|
5
|
-
configurable
|
6
|
-
|
7
|
-
config_path 'example/001_simple_example.ini'
|
8
|
-
|
9
|
-
define :foo do
|
10
|
-
description "How many Foo's are there?"
|
11
|
-
type :integer
|
12
|
-
default 1
|
13
|
-
end
|
14
|
-
|
15
|
-
end
|
16
|
-
|
17
|
-
example = SimpleExample.new
|
18
|
-
puts example.foo
|
@@ -1,29 +0,0 @@
|
|
1
|
-
require 'configuration/configurable'
|
2
|
-
|
3
|
-
# An example of adding configuration options to a class, seperated by
|
4
|
-
# namespaces.
|
5
|
-
class NamespaceExample
|
6
|
-
configurable
|
7
|
-
|
8
|
-
config_path 'example/002_namespace_example.ini'
|
9
|
-
|
10
|
-
define :bar do
|
11
|
-
description 'foo_bar'
|
12
|
-
type :integer
|
13
|
-
default 1
|
14
|
-
end
|
15
|
-
|
16
|
-
namespace :foo do
|
17
|
-
define :bar do
|
18
|
-
description 'bar_foo'
|
19
|
-
type :string
|
20
|
-
default 'Hello, world!'
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
example = NamespaceExample.new
|
26
|
-
puts example.config.inspect
|
27
|
-
puts example.bar
|
28
|
-
puts example.config[:foo_bar]
|
29
|
-
puts example.foo[:bar]
|
@@ -1,26 +0,0 @@
|
|
1
|
-
require 'configuration/configurable'
|
2
|
-
|
3
|
-
module ExampleConfig
|
4
|
-
extend Configuration::ConfigMixin
|
5
|
-
extend Configuration::DSL
|
6
|
-
|
7
|
-
define :conf do
|
8
|
-
default 2
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
class Foo
|
13
|
-
configured_by ExampleConfig
|
14
|
-
|
15
|
-
default_namespace :foo
|
16
|
-
|
17
|
-
define :bar do
|
18
|
-
default 1
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
foo = Foo.new
|
24
|
-
puts foo.config[:conf]
|
25
|
-
puts foo.bar
|
26
|
-
|
data/lib/confuse/config_item.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
module Confuse
|
2
|
-
# A {ConfigItem} is a class for storing a single piece of config. It has a
|
3
|
-
# key, a type, a description, and a default value.
|
4
|
-
class ConfigItem
|
5
|
-
attr_reader :key
|
6
|
-
attr_writer :value
|
7
|
-
attr_reader :default_value
|
8
|
-
|
9
|
-
def initialize(name, &block)
|
10
|
-
@key = name
|
11
|
-
instance_eval(&block) unless block.nil?
|
12
|
-
end
|
13
|
-
|
14
|
-
def description(description = nil)
|
15
|
-
@description = description unless description.nil?
|
16
|
-
@description
|
17
|
-
end
|
18
|
-
|
19
|
-
def type(type = nil)
|
20
|
-
@type = type unless type.nil?
|
21
|
-
@type
|
22
|
-
end
|
23
|
-
|
24
|
-
def default(value = nil, &block)
|
25
|
-
@default_value = value unless value.nil?
|
26
|
-
@default_value = block unless block.nil?
|
27
|
-
end
|
28
|
-
|
29
|
-
def value=(val)
|
30
|
-
@value = val
|
31
|
-
end
|
32
|
-
|
33
|
-
def value
|
34
|
-
@value || @default_value
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
data/lib/confuse/config_mixin.rb
DELETED
@@ -1,135 +0,0 @@
|
|
1
|
-
require 'confuse/namespace'
|
2
|
-
require 'inifile'
|
3
|
-
require 'yaml'
|
4
|
-
|
5
|
-
module Confuse
|
6
|
-
# Mixin for configuration.
|
7
|
-
module ConfigMixin
|
8
|
-
def namespaces
|
9
|
-
@namespaces ||= {}
|
10
|
-
end
|
11
|
-
|
12
|
-
def load_namespaces(new_namespaces)
|
13
|
-
new_namespaces.each do |key, value|
|
14
|
-
existing = namespaces[key]
|
15
|
-
existing ? existing.merge!(value) : namespaces[key] = value.clone
|
16
|
-
end
|
17
|
-
@foo = true
|
18
|
-
end
|
19
|
-
|
20
|
-
def read_files(file_paths)
|
21
|
-
Array(file_paths).map do |path|
|
22
|
-
if File.directory?(path)
|
23
|
-
load_config_dir(path)
|
24
|
-
elsif File.exists?(path)
|
25
|
-
load_config_file(path)
|
26
|
-
end
|
27
|
-
end.flatten.compact.each { |c| mixin_config!(c) }
|
28
|
-
end
|
29
|
-
|
30
|
-
def [](key)
|
31
|
-
namespace = find_namespace(key) || :default
|
32
|
-
rest_of_key = rest_of_key(key, namespace)
|
33
|
-
ns = namespaces[namespace]
|
34
|
-
return ns unless rest_of_key
|
35
|
-
ns[rest_of_key, self]
|
36
|
-
end
|
37
|
-
|
38
|
-
def []=(key, value)
|
39
|
-
puts 'WARNING: changing config after it has been set!'
|
40
|
-
mixin_config!({ key => value })
|
41
|
-
end
|
42
|
-
|
43
|
-
def to_hash
|
44
|
-
namespaces.reduce({}) do |memo, (name, namespace)|
|
45
|
-
namespace.keys.each do |key|
|
46
|
-
if name != :default
|
47
|
-
memo[:"#{name}_#{key}"] = namespace[key, self]
|
48
|
-
else
|
49
|
-
memo[:"#{key}"] = namespace[key, self]
|
50
|
-
end
|
51
|
-
end
|
52
|
-
memo
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
# We allow the namespace and the key to be concatenated with an '_', so this
|
57
|
-
# method is to search the possible substrings that could make up the
|
58
|
-
# namespace for a key.
|
59
|
-
#
|
60
|
-
# This does not guarentee that the suffix of the namespace that is found is
|
61
|
-
# a valid key in that namespace.
|
62
|
-
#
|
63
|
-
# @param [Symbol] key to search
|
64
|
-
def find_namespace(key)
|
65
|
-
until key.to_s.empty? || @namespaces[key.to_sym]
|
66
|
-
key = (s = key.to_s)[0, s.rindex('_') || 0]
|
67
|
-
end
|
68
|
-
key.to_s.empty? ? nil : key.to_sym
|
69
|
-
end
|
70
|
-
|
71
|
-
# Once we've found the namespace, we want to find the rest of the string
|
72
|
-
# to use as the rest of the key. If the namespace isn't a substring of the
|
73
|
-
# key (e.g. :default), we return the key unaltered.
|
74
|
-
#
|
75
|
-
# @param [Symbol] key The full key
|
76
|
-
# @param [Symbol] namespace The substring of the key that is the
|
77
|
-
# namespace.
|
78
|
-
def rest_of_key(key, namespace)
|
79
|
-
key_s = key.to_s
|
80
|
-
namespace_s = namespace.to_s
|
81
|
-
return nil if key_s == namespace_s
|
82
|
-
index = key_s.index(namespace_s) && (namespace_s.length + 1)
|
83
|
-
key_s[index || 0, key_s.length].to_sym
|
84
|
-
end
|
85
|
-
|
86
|
-
def load_config_dir(config_dir)
|
87
|
-
Dir[config_dir + '/*.{ini,conf,yaml}'].map do |conf_file|
|
88
|
-
load_config_file(conf_file)
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
def load_config_file(conf_file)
|
93
|
-
conf = load_ini(conf_file) || load_yaml(conf_file)
|
94
|
-
raise "Can't parse #{conf_file}" unless conf
|
95
|
-
conf
|
96
|
-
end
|
97
|
-
|
98
|
-
def mixin_config!(config)
|
99
|
-
config.each do |key, value|
|
100
|
-
namespace_name = find_namespace(key) || :default
|
101
|
-
namespace = @namespaces[namespace_name]
|
102
|
-
if value.respond_to?(:keys)
|
103
|
-
# if its a hash, set each key in the hash as a config item in the
|
104
|
-
# namespace
|
105
|
-
value.each { |k, v| namespace[k] = v }
|
106
|
-
else
|
107
|
-
# otherwise, set it directly in the namespace
|
108
|
-
namespace[rest_of_key(key, namespace_name)] = value
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
def load_ini(file)
|
114
|
-
begin
|
115
|
-
# make sure they keys are ruby symbols
|
116
|
-
symbolise_hash_keys(IniFile.load(file).to_h)
|
117
|
-
rescue IniFile::Error
|
118
|
-
nil
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
def symbolise_hash_keys(hash)
|
123
|
-
hash.reduce({}) do |memo, (key, val)|
|
124
|
-
memo[key.to_sym] =
|
125
|
-
val.respond_to?(:reduce) ? symbolise_hash_keys(val) : val
|
126
|
-
memo
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
def load_yaml(file)
|
131
|
-
YAML.load(File.read(file))
|
132
|
-
end
|
133
|
-
|
134
|
-
end
|
135
|
-
end
|
data/lib/confuse/configurable.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
require 'confuse'
|
2
|
-
|
3
|
-
# Monkey patch class to easily allow a class to be configurable.
|
4
|
-
class Class
|
5
|
-
def configurable
|
6
|
-
extend Confuse::DSL
|
7
|
-
include Confuse::InstanceMethods
|
8
|
-
end
|
9
|
-
|
10
|
-
def configured_by(config)
|
11
|
-
configurable
|
12
|
-
@configured_by = config
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
data/lib/confuse/dsl.rb
DELETED
@@ -1,68 +0,0 @@
|
|
1
|
-
require 'confuse/config'
|
2
|
-
|
3
|
-
module Confuse
|
4
|
-
# DSL for setting up a configurable class
|
5
|
-
module DSL
|
6
|
-
attr_reader :configured_by
|
7
|
-
|
8
|
-
def configured_by(config = Config)
|
9
|
-
@configured_by ||= config
|
10
|
-
end
|
11
|
-
|
12
|
-
def default_namespace(namespace = :default)
|
13
|
-
@default_namespace ||= namespace
|
14
|
-
end
|
15
|
-
|
16
|
-
def config_path(*paths)
|
17
|
-
@config_path ||= []
|
18
|
-
@config_path.concat paths
|
19
|
-
end
|
20
|
-
|
21
|
-
def namespaces
|
22
|
-
@namespaces ||= {
|
23
|
-
default_namespace => Namespace.new(&(Proc.new { }))
|
24
|
-
}
|
25
|
-
end
|
26
|
-
|
27
|
-
def define(name, &block)
|
28
|
-
namespaces[default_namespace].define(name, &block)
|
29
|
-
getter(name, default_namespace)
|
30
|
-
end
|
31
|
-
|
32
|
-
def namespace(name, &block)
|
33
|
-
new_namespace = Namespace.new(&block)
|
34
|
-
if namespaces[name.to_sym]
|
35
|
-
namespaces[name.to_sym].merge! new_namespace
|
36
|
-
else
|
37
|
-
namespaces[name.to_sym] = new_namespace
|
38
|
-
end
|
39
|
-
getter(name)
|
40
|
-
end
|
41
|
-
|
42
|
-
def getter(name, namespace = nil)
|
43
|
-
class_eval do
|
44
|
-
if namespace.nil?
|
45
|
-
define_method(name) do
|
46
|
-
config[name]
|
47
|
-
end
|
48
|
-
else
|
49
|
-
define_method(name) do
|
50
|
-
config[namespace][name, config]
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
end
|
57
|
-
|
58
|
-
# Instance methods for getting the defined configuration from an instance of
|
59
|
-
# a configured class.
|
60
|
-
module InstanceMethods
|
61
|
-
# Lazilly create the config object when it is first requested.
|
62
|
-
def config
|
63
|
-
self.class.configured_by.load_namespaces(self.class.namespaces)
|
64
|
-
self.class.configured_by.read_files(self.class.config_path)
|
65
|
-
self.class.configured_by
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
data/test/test_config_base.rb
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
require 'minitest/autorun'
|
2
|
-
require 'confuse'
|
3
|
-
|
4
|
-
class Foo < Confuse::ConfigBase
|
5
|
-
define :foo do
|
6
|
-
default 'foo'
|
7
|
-
type :string
|
8
|
-
description 'foo'
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
class TestConfigBase < MiniTest::Unit::TestCase
|
13
|
-
# This is easier to test with an instance of a config object, rather than as
|
14
|
-
# part of the test for the module where other tests can modify the model.
|
15
|
-
def test_params_hash
|
16
|
-
assert_equal({ :default_foo => { :type => :string, :doc => 'foo',
|
17
|
-
:default => 'foo' } },
|
18
|
-
Foo.params_hash)
|
19
|
-
end
|
20
|
-
|
21
|
-
def test_can_specify_config_options_on_initialize
|
22
|
-
config = Foo.new(:conf => { :foo => 'bar' })
|
23
|
-
|
24
|
-
assert_equal 'bar', config[:foo]
|
25
|
-
end
|
26
|
-
|
27
|
-
def test_two_instances_can_exist_with_different_values
|
28
|
-
# instatiate two versions of the config
|
29
|
-
config1 = Foo.new
|
30
|
-
config2 = Foo.new(:conf => { :foo => 'bar' })
|
31
|
-
|
32
|
-
# assert config1 and config2 are different
|
33
|
-
assert_equal 'foo', config1[:foo]
|
34
|
-
assert_equal 'bar', config2[:foo]
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|