confuse 0.1.8 → 1.0.0
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.
- 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
|
-
|