configurate 0.2.0 → 0.3.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.
- checksums.yaml +4 -4
- data/Changelog.md +7 -0
- data/README.md +4 -4
- data/lib/configurate.rb +21 -16
- data/lib/configurate/lookup_chain.rb +10 -10
- data/lib/configurate/provider.rb +29 -27
- data/lib/configurate/provider/dynamic.rb +30 -22
- data/lib/configurate/provider/env.rb +16 -14
- data/lib/configurate/provider/yaml.rb +34 -29
- data/lib/configurate/proxy.rb +7 -6
- data/lib/configurate/setting_path.rb +8 -4
- data/spec/configurate/lookup_chain_spec.rb +3 -3
- data/spec/configurate/provider/dynamic_spec.rb +6 -6
- data/spec/configurate/provider/env_spec.rb +10 -10
- data/spec/configurate/provider/yaml_spec.rb +33 -15
- data/spec/configurate/provider_spec.rb +14 -2
- data/spec/configurate/proxy_spec.rb +10 -11
- data/spec/configurate/setting_path_spec.rb +8 -9
- data/spec/configurate_spec.rb +2 -2
- data/spec/spec_helper.rb +3 -4
- metadata +7 -7
- checksums.yaml.gz.asc +0 -11
- data.tar.gz.asc +0 -11
- metadata.gz.asc +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cee20b7c12f6d7b03d65511ea8c501955dc437cc
|
4
|
+
data.tar.gz: 6b23db2069cf5b8128c9b2d1c6b1f3e1ddac26b7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 53094d245312357e844542e7342fc9c1e07c864320109c35a883bcd250bfcd81a81fffef41792cf092bb81f4ec96f61d5ba6faa577e79f0678dca2543a68c9ec
|
7
|
+
data.tar.gz: ddf023b472ebcd5388e6e454939970d7744add4784cf4d1d434fd1b6dfe9f5f8d9c0d4f7e20bd295dc97fd587a9eb5cd0a2afc13aaf18d897bdff4fec227fd11
|
data/Changelog.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
# 0.3.0
|
2
|
+
|
3
|
+
* Add new exception: Configurate::MissingSetting to be raised and bubble up to the user
|
4
|
+
if a setting wasn't found and the user requested to be informed.
|
5
|
+
* Configurate::Provider::YAML got the new option raise_on_missing to raise
|
6
|
+
Configurate::MissingSetting if the requested key is not in the YAML document.
|
7
|
+
|
1
8
|
# 0.2.0
|
2
9
|
|
3
10
|
* Dynamic provider listens to reset_dynamic! message and forgets all settings on it.
|
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# Configurate - A flexible configuration system
|
2
2
|
[](https://rubygems.org/gems/configurate)
|
3
3
|
[](https://travis-ci.org/jhass/configurate)
|
4
|
-
[](https://codeclimate.com/github/
|
6
|
-
[](https://gemnasium.com/jhass/configurate)
|
5
|
+
[](https://codeclimate.com/github/jhass/configurate)
|
6
|
+
[](https://coveralls.io/r/jhass/configurate?branch=master)
|
7
7
|
|
8
8
|
Configurate allows you to specify a chain of configuration providers which are
|
9
9
|
queried in order until one returns a value. This allows scenarios like overriding
|
@@ -11,7 +11,7 @@ your default settings with a user configuration file and let those be overridden
|
|
11
11
|
by environment variables. The query interface allows to group and nest your configuration options
|
12
12
|
to a practically unlimited level.
|
13
13
|
|
14
|
-
Configurate
|
14
|
+
Configurate supports Ruby 2.0 or later.
|
15
15
|
|
16
16
|
## Installation
|
17
17
|
|
data/lib/configurate.rb
CHANGED
@@ -1,10 +1,9 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
require 'configurate/setting_path'
|
4
|
-
require 'configurate/lookup_chain'
|
5
|
-
require 'configurate/provider'
|
6
|
-
require 'configurate/proxy'
|
1
|
+
require "forwardable"
|
7
2
|
|
3
|
+
require "configurate/setting_path"
|
4
|
+
require "configurate/lookup_chain"
|
5
|
+
require "configurate/provider"
|
6
|
+
require "configurate/proxy"
|
8
7
|
|
9
8
|
# A flexible and extendable configuration system.
|
10
9
|
# The calling logic is isolated from the lookup logic
|
@@ -20,15 +19,15 @@ require 'configurate/proxy'
|
|
20
19
|
module Configurate
|
21
20
|
# This is your main entry point. Instead of lengthy explanations
|
22
21
|
# let an example demonstrate its usage:
|
23
|
-
#
|
22
|
+
#
|
24
23
|
# require 'configuration_methods'
|
25
|
-
#
|
24
|
+
#
|
26
25
|
# AppSettings = Configurate::Settings.create do
|
27
26
|
# add_provider Configurate::Provider::Env
|
28
27
|
# add_provider Configurate::Provider::YAML, '/etc/app_settings.yml',
|
29
28
|
# namespace: Rails.env, required: false
|
30
29
|
# add_provider Configurate::Provider::YAML, 'config/default_settings.yml'
|
31
|
-
#
|
30
|
+
#
|
32
31
|
# extend YourConfigurationMethods
|
33
32
|
# end
|
34
33
|
#
|
@@ -36,18 +35,17 @@ module Configurate
|
|
36
35
|
#
|
37
36
|
# Please also read the note at {Proxy}!
|
38
37
|
class Settings
|
39
|
-
|
40
38
|
attr_reader :lookup_chain
|
41
|
-
|
39
|
+
|
42
40
|
undef_method :method # Remove possible conflicts with common setting names
|
43
41
|
|
44
42
|
extend Forwardable
|
45
43
|
|
46
44
|
def initialize
|
47
45
|
@lookup_chain = LookupChain.new
|
48
|
-
|
46
|
+
warn "Warning you called Configurate::Settings.new with a block, you really meant to call #create" if block_given?
|
49
47
|
end
|
50
|
-
|
48
|
+
|
51
49
|
# @!method lookup(setting)
|
52
50
|
# (see {LookupChain#lookup})
|
53
51
|
|
@@ -63,15 +61,22 @@ module Configurate
|
|
63
61
|
def method_missing(method, *args, &block)
|
64
62
|
Proxy.new(@lookup_chain).public_send(method, *args, &block)
|
65
63
|
end
|
66
|
-
|
64
|
+
|
67
65
|
# Create a new configuration object
|
68
66
|
# @yield the given block will be evaluated in the context of the new object
|
69
67
|
def self.create(&block)
|
70
|
-
config =
|
68
|
+
config = new
|
71
69
|
config.instance_eval(&block) if block_given?
|
72
70
|
config
|
73
71
|
end
|
74
72
|
end
|
75
|
-
|
73
|
+
|
74
|
+
# This is supposed to be raised by providers if the requested setting
|
75
|
+
# does not exist, (remember, nil is a valid value and thus rarely a sufficient check)
|
76
|
+
# and this should be communicated to the end user.
|
77
|
+
class MissingSetting < RuntimeError; end
|
78
|
+
|
79
|
+
# This is supposed to be raised by providers if the requested setting
|
80
|
+
# cannot be found and the next provider in the chain should be tried.
|
76
81
|
class SettingNotFoundError < RuntimeError; end
|
77
82
|
end
|
@@ -21,7 +21,6 @@ module Configurate
|
|
21
21
|
@provider << provider.new(*args)
|
22
22
|
end
|
23
23
|
|
24
|
-
|
25
24
|
# Tries all providers in the order they were added to provide a response
|
26
25
|
# for setting.
|
27
26
|
#
|
@@ -45,19 +44,20 @@ module Configurate
|
|
45
44
|
private
|
46
45
|
|
47
46
|
def special_value_or_string(value)
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
47
|
+
case value
|
48
|
+
when TrueClass, FalseClass, NilClass, Array, Hash
|
49
|
+
value
|
50
|
+
else
|
51
|
+
if value.respond_to?(:to_s)
|
52
|
+
case value.to_s.strip
|
52
53
|
when "true" then true
|
53
54
|
when "false" then false
|
54
55
|
when "", "nil" then nil
|
55
|
-
else value
|
56
|
+
else value.to_s
|
57
|
+
end
|
58
|
+
else
|
59
|
+
value
|
56
60
|
end
|
57
|
-
elsif value.respond_to?(:to_s)
|
58
|
-
return value.to_s
|
59
|
-
else
|
60
|
-
return value
|
61
61
|
end
|
62
62
|
end
|
63
63
|
end
|
data/lib/configurate/provider.rb
CHANGED
@@ -1,32 +1,34 @@
|
|
1
|
-
module Configurate
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
1
|
+
module Configurate
|
2
|
+
module Provider
|
3
|
+
# This provides a basic {#lookup} method for other providers to build
|
4
|
+
# upon. Childs are expected to define +lookup_path(path, *args)+.
|
5
|
+
# The method should return nil if the setting
|
6
|
+
# wasn't found and {#lookup} will raise an {SettingNotFoundError} in that
|
7
|
+
# case.
|
8
|
+
class Base
|
9
|
+
def lookup(*args)
|
10
|
+
result = lookup_path(*args)
|
11
|
+
return result unless result.nil?
|
12
|
+
raise Configurate::SettingNotFoundError, "The setting #{args.first} was not found"
|
13
|
+
end
|
12
14
|
end
|
13
|
-
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
16
|
+
# Utility function to lookup a settings path in a hash
|
17
|
+
# @param setting_path [SettingPath]
|
18
|
+
# @param hash [Hash]
|
19
|
+
# @yield fallback value if not found
|
20
|
+
# @return [Object]
|
21
|
+
def self.lookup_in_hash setting_path, hash, &fallback
|
22
|
+
fallback ||= proc { nil }
|
23
|
+
while hash.is_a?(Hash) && hash.has_key?(setting_path.first) && !setting_path.empty?
|
24
|
+
hash = hash[setting_path.shift]
|
25
|
+
end
|
26
|
+
return fallback.call unless setting_path.empty?
|
27
|
+
hash
|
24
28
|
end
|
25
|
-
return fallback.call unless setting_path.empty?
|
26
|
-
hash
|
27
29
|
end
|
28
|
-
end
|
30
|
+
end
|
29
31
|
|
30
|
-
require
|
31
|
-
require
|
32
|
-
require
|
32
|
+
require "configurate/provider/yaml"
|
33
|
+
require "configurate/provider/env"
|
34
|
+
require "configurate/provider/dynamic"
|
@@ -1,30 +1,38 @@
|
|
1
|
-
module Configurate
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
1
|
+
module Configurate
|
2
|
+
module Provider
|
3
|
+
# This provider knows nothing upon initialization, however if you access
|
4
|
+
# a setting ending with +=+ and give one argument to that call it remembers
|
5
|
+
# that setting, stripping the +=+ and will return it on the next call
|
6
|
+
# without +=+. Sending +reset_dynamic!+ to it will make it forget all
|
7
|
+
# settings. Also assigning nil will have the effect of it forgetting
|
8
|
+
# a setting.
|
9
|
+
class Dynamic < Base
|
10
|
+
def lookup_path(setting_path, *args)
|
11
|
+
if setting_path.to_s == "reset_dynamic!"
|
12
|
+
@settings = nil
|
13
|
+
return
|
14
|
+
end
|
15
|
+
|
16
|
+
if setting_path.setter? && args.length > 0
|
17
|
+
*root, key = setting_path.to_a
|
18
|
+
hash = root.inject(settings) {|hash, key| hash[key] }
|
19
|
+
hash[key] = extract_value(args)
|
20
|
+
end
|
21
|
+
|
22
|
+
Provider.lookup_in_hash setting_path, settings
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
12
26
|
|
13
|
-
|
14
|
-
|
15
|
-
@settings = {}
|
16
|
-
return
|
27
|
+
def settings
|
28
|
+
@settings ||= Hash.new {|hash, key| hash[key] = Hash.new(&hash.default_proc) }
|
17
29
|
end
|
18
30
|
|
19
|
-
|
31
|
+
def extract_value args
|
20
32
|
value = args.first
|
21
33
|
value = value.get if value.respond_to?(:_proxy?) && value._proxy?
|
22
|
-
|
23
|
-
hash = root.inject(@settings) {|hash, key| hash[key] ||= {} }
|
24
|
-
hash[key] = value
|
34
|
+
value
|
25
35
|
end
|
26
|
-
|
27
|
-
Provider.lookup_in_hash setting_path, @settings
|
28
36
|
end
|
29
37
|
end
|
30
|
-
end
|
38
|
+
end
|
@@ -1,17 +1,19 @@
|
|
1
|
-
module Configurate
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
1
|
+
module Configurate
|
2
|
+
module Provider
|
3
|
+
# This provider looks for settings in the environment.
|
4
|
+
# For the setting +foo.bar_baz+ this provider will look for an
|
5
|
+
# environment variable +FOO_BAR_BAZ+, joining all components of the
|
6
|
+
# setting with underscores and upcasing the result.
|
7
|
+
# If an value contains any commas (,) it's split at them and returned as array.
|
8
|
+
class Env < Base
|
9
|
+
def lookup_path(setting_path, *_args)
|
10
|
+
value = ENV[setting_path.join("_").upcase]
|
11
|
+
unless value.nil?
|
12
|
+
value = value.dup
|
13
|
+
value = value.split(",") if value.include?(",")
|
14
|
+
end
|
15
|
+
value
|
13
16
|
end
|
14
|
-
value
|
15
17
|
end
|
16
18
|
end
|
17
|
-
end
|
19
|
+
end
|
@@ -1,37 +1,42 @@
|
|
1
|
-
require
|
1
|
+
require "yaml"
|
2
2
|
|
3
|
-
module Configurate
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
@
|
16
|
-
|
3
|
+
module Configurate
|
4
|
+
module Provider
|
5
|
+
# This provider tries to open a YAML file and does nested lookups
|
6
|
+
# in it.
|
7
|
+
class YAML < Base
|
8
|
+
# @param file [String] the path to the file
|
9
|
+
# @param namespace [String] optionally set this as the root
|
10
|
+
# @param required [Boolean] whether or not to raise an error if
|
11
|
+
# the file or the namespace, if given, is not found. Defaults to +true+.
|
12
|
+
# @param raise_on_missing [Boolean] whether to raise {Configurate::MissingSetting}
|
13
|
+
# if a setting can't be provided. Defaults to +false+.
|
14
|
+
# @raise [ArgumentError] if the namespace isn't found in the file
|
15
|
+
# @raise [Errno:ENOENT] if the file isn't found
|
16
|
+
def initialize file, namespace: nil, required: true, raise_on_missing: false
|
17
|
+
@raise_on_missing = raise_on_missing
|
18
|
+
@settings = {}
|
17
19
|
|
18
|
-
|
20
|
+
@settings = ::YAML.load_file(file)
|
19
21
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
unless namespace.nil?
|
23
|
+
@settings = Provider.lookup_in_hash(SettingPath.new(namespace), @settings) do
|
24
|
+
raise ArgumentError, "Namespace #{namespace} not found in #{file}" if required
|
25
|
+
$stderr.puts "WARNING: Namespace #{namespace} not found in #{file}"
|
26
|
+
nil
|
27
|
+
end
|
26
28
|
end
|
29
|
+
rescue Errno::ENOENT => e
|
30
|
+
warn "WARNING: Configuration file #{file} not found, ensure it's present"
|
31
|
+
raise e if required
|
27
32
|
end
|
28
|
-
rescue Errno::ENOENT => e
|
29
|
-
$stderr.puts "WARNING: Configuration file #{file} not found, ensure it's present"
|
30
|
-
raise e if required
|
31
|
-
end
|
32
33
|
|
33
|
-
|
34
|
-
|
34
|
+
def lookup_path setting_path, *_
|
35
|
+
Provider.lookup_in_hash(setting_path, @settings) {
|
36
|
+
raise MissingSetting.new "#{setting_path} is not a valid setting." if @raise_on_missing
|
37
|
+
nil
|
38
|
+
}
|
39
|
+
end
|
35
40
|
end
|
36
41
|
end
|
37
|
-
end
|
42
|
+
end
|
data/lib/configurate/proxy.rb
CHANGED
@@ -23,17 +23,17 @@ module Configurate
|
|
23
23
|
!target
|
24
24
|
end
|
25
25
|
|
26
|
-
|
26
|
+
%i(!= == eql? coerce).each do |method|
|
27
27
|
define_method method do |other|
|
28
28
|
target.public_send method, target_or_object(other)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
32
|
{
|
33
|
-
|
34
|
-
:
|
35
|
-
|
36
|
-
|
33
|
+
to_int: :to_i,
|
34
|
+
to_hash: :to_h,
|
35
|
+
to_str: :to_s,
|
36
|
+
to_ary: :to_a
|
37
37
|
}.each do |method, converter|
|
38
38
|
define_method method do
|
39
39
|
value = target
|
@@ -75,7 +75,8 @@ module Configurate
|
|
75
75
|
alias_method :get, :target
|
76
76
|
|
77
77
|
private
|
78
|
-
|
78
|
+
|
79
|
+
COMMON_KEY_NAMES = %i(key method)
|
79
80
|
|
80
81
|
def target_respond_to? setting, include_private=false
|
81
82
|
return false if COMMON_KEY_NAMES.include? setting
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "forwardable"
|
2
2
|
|
3
3
|
module Configurate
|
4
4
|
# Class encapsulating the concept of a path to a setting
|
@@ -45,13 +45,13 @@ module Configurate
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
-
|
48
|
+
%i(join first last shift pop).each do |method|
|
49
49
|
define_method method do |*args|
|
50
50
|
clean_special_characters @path.public_send(method, *args)
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
-
|
54
|
+
%i(<< unshift push).each do |method|
|
55
55
|
define_method method do |*args|
|
56
56
|
@path.public_send method, *args.map(&:to_s)
|
57
57
|
end
|
@@ -66,7 +66,11 @@ module Configurate
|
|
66
66
|
end
|
67
67
|
|
68
68
|
def inspect
|
69
|
-
"<SettingPath:#{object_id.to_s(16)}
|
69
|
+
"<SettingPath:#{object_id.to_s(16)} "\
|
70
|
+
"path=#{self}:#{@path.object_id.to_s(16)} "\
|
71
|
+
"question=#{question?} "\
|
72
|
+
"action=#{action?} "\
|
73
|
+
"setter=#{setter?}>"
|
70
74
|
end
|
71
75
|
|
72
76
|
private
|
@@ -1,8 +1,8 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
class InvalidConfigurationProvider; end
|
4
4
|
class ValidConfigurationProvider
|
5
|
-
def lookup(
|
5
|
+
def lookup(_setting, *_args); end
|
6
6
|
end
|
7
7
|
|
8
8
|
describe Configurate::LookupChain do
|
@@ -97,7 +97,7 @@ describe Configurate::LookupChain do
|
|
97
97
|
end
|
98
98
|
|
99
99
|
it "returns nil if no value is found" do
|
100
|
-
@provider.each {
|
100
|
+
@provider.each {|p| allow(p).to receive(:lookup).and_raise(Configurate::SettingNotFoundError) }
|
101
101
|
expect(subject.lookup "not.me").to be_nil
|
102
102
|
end
|
103
103
|
end
|
@@ -1,16 +1,16 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe Configurate::Provider::Dynamic do
|
4
4
|
subject { described_class.new }
|
5
5
|
describe "#lookup_path" do
|
6
6
|
it "returns nil if the setting was never set" do
|
7
|
-
expect(subject.lookup_path Configurate::SettingPath.new(["not_me"])
|
7
|
+
expect(subject.lookup_path Configurate::SettingPath.new(["not_me"])).to be_nil
|
8
8
|
end
|
9
9
|
|
10
10
|
it "remembers the setting if it ends with =" do
|
11
11
|
subject.lookup_path Configurate::SettingPath.new(["find_me", "later="]), "there"
|
12
12
|
|
13
|
-
expect(subject.lookup_path Configurate::SettingPath.new(
|
13
|
+
expect(subject.lookup_path Configurate::SettingPath.new(%w(find_me later))).to eq "there"
|
14
14
|
end
|
15
15
|
|
16
16
|
it "calls .get on the argument if a proxy object is given" do
|
@@ -20,14 +20,14 @@ describe Configurate::Provider::Dynamic do
|
|
20
20
|
end
|
21
21
|
|
22
22
|
it "resolves nested calls after group assignment" do
|
23
|
-
subject.lookup_path Configurate::SettingPath.new(
|
24
|
-
expect(subject.lookup_path Configurate::SettingPath.new(
|
23
|
+
subject.lookup_path Configurate::SettingPath.new(%w(find_me later=)), "a" => "b"
|
24
|
+
expect(subject.lookup_path Configurate::SettingPath.new(%w(find_me later a))).to eq "b"
|
25
25
|
end
|
26
26
|
|
27
27
|
it "clears out all overrides on reset_dynamic!" do
|
28
28
|
subject.lookup_path Configurate::SettingPath.new(["find_me", "later="]), "there"
|
29
29
|
subject.lookup_path Configurate::SettingPath.new(["reset_dynamic!"])
|
30
|
-
expect(subject.lookup_path Configurate::SettingPath.new(
|
30
|
+
expect(subject.lookup_path Configurate::SettingPath.new(%w(find_me later))).to_not eq "there"
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
@@ -1,21 +1,21 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe Configurate::Provider::Env do
|
4
4
|
subject { described_class.new }
|
5
|
-
let(:existing_path) {
|
6
|
-
let(:not_existing_path) {
|
7
|
-
let(:array_path) { [
|
5
|
+
let(:existing_path) { %w(existing setting) }
|
6
|
+
let(:not_existing_path) { %w(not existing path) }
|
7
|
+
let(:array_path) { ["array"] }
|
8
8
|
before(:all) do
|
9
|
-
ENV[
|
10
|
-
ENV[
|
9
|
+
ENV["EXISTING_SETTING"] = "there"
|
10
|
+
ENV["ARRAY"] = "foo,bar,baz"
|
11
11
|
end
|
12
12
|
|
13
13
|
after(:all) do
|
14
|
-
ENV[
|
15
|
-
ENV[
|
14
|
+
ENV["EXISTING_SETTING"] = nil
|
15
|
+
ENV["ARRAY"] = nil
|
16
16
|
end
|
17
17
|
|
18
|
-
describe
|
18
|
+
describe "#lookup_path" do
|
19
19
|
it "joins and upcases the path" do
|
20
20
|
expect(ENV).to receive(:[]).with("EXISTING_SETTING")
|
21
21
|
subject.lookup_path existing_path
|
@@ -26,7 +26,7 @@ describe Configurate::Provider::Env do
|
|
26
26
|
end
|
27
27
|
|
28
28
|
it "makes an array out of comma separated values" do
|
29
|
-
expect(subject.lookup_path array_path).to eq
|
29
|
+
expect(subject.lookup_path array_path).to eq %w(foo bar baz)
|
30
30
|
end
|
31
31
|
|
32
32
|
it "returns a unfrozen string" do
|
@@ -1,11 +1,14 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe Configurate::Provider::YAML do
|
4
|
-
let(:settings) {
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
let(:settings) {
|
5
|
+
{
|
6
|
+
"toplevel" => "bar",
|
7
|
+
"some" => {
|
8
|
+
"nested" => {"some" => "lala", "setting" => "foo"}
|
9
|
+
}
|
10
|
+
}
|
11
|
+
}
|
9
12
|
|
10
13
|
describe "#initialize" do
|
11
14
|
it "loads the file" do
|
@@ -23,26 +26,25 @@ describe Configurate::Provider::YAML do
|
|
23
26
|
}.to raise_error Errno::ENOENT
|
24
27
|
end
|
25
28
|
|
26
|
-
|
27
29
|
context "with a namespace" do
|
28
30
|
it "looks in the file for that namespace" do
|
29
31
|
namespace = "some.nested"
|
30
32
|
allow(::YAML).to receive(:load_file).and_return(settings)
|
31
|
-
provider = described_class.new
|
32
|
-
expect(provider.instance_variable_get :@settings).to eq settings[
|
33
|
+
provider = described_class.new "bla", namespace: namespace
|
34
|
+
expect(provider.instance_variable_get :@settings).to eq settings["some"]["nested"]
|
33
35
|
end
|
34
36
|
|
35
37
|
it "raises if the namespace isn't found" do
|
36
38
|
allow(::YAML).to receive(:load_file).and_return({})
|
37
39
|
expect {
|
38
|
-
described_class.new
|
40
|
+
described_class.new "bla", namespace: "bar"
|
39
41
|
}.to raise_error
|
40
42
|
end
|
41
43
|
|
42
44
|
it "works with an empty namespace in the file" do
|
43
|
-
allow(::YAML).to receive(:load_file).and_return(
|
45
|
+
allow(::YAML).to receive(:load_file).and_return("foo" => {"bar" => nil})
|
44
46
|
expect {
|
45
|
-
described_class.new
|
47
|
+
described_class.new "bla", namespace: "foo.bar"
|
46
48
|
}.to_not raise_error
|
47
49
|
end
|
48
50
|
end
|
@@ -58,7 +60,7 @@ describe Configurate::Provider::YAML do
|
|
58
60
|
it "doesn't raise if a namespace isn't found" do
|
59
61
|
allow(::YAML).to receive(:load_file).and_return({})
|
60
62
|
expect {
|
61
|
-
described_class.new
|
63
|
+
described_class.new "bla", namespace: "foo", required: false
|
62
64
|
}.not_to raise_error
|
63
65
|
end
|
64
66
|
end
|
@@ -67,15 +69,31 @@ describe Configurate::Provider::YAML do
|
|
67
69
|
describe "#lookup_path" do
|
68
70
|
before do
|
69
71
|
allow(::YAML).to receive(:load_file).and_return(settings)
|
70
|
-
@provider = described_class.new
|
72
|
+
@provider = described_class.new "dummy"
|
71
73
|
end
|
72
74
|
|
73
75
|
it "looks up the whole nesting" do
|
74
|
-
expect(@provider.lookup_path
|
76
|
+
expect(@provider.lookup_path %w(some nested some)).to eq settings["some"]["nested"]["some"]
|
75
77
|
end
|
76
78
|
|
77
79
|
it "returns nil if no setting is found" do
|
78
80
|
expect(@provider.lookup_path ["not_me"]).to be_nil
|
79
81
|
end
|
82
|
+
|
83
|
+
context "with raise_on_missing set to true" do
|
84
|
+
before do
|
85
|
+
@provider = described_class.new "dummy", raise_on_missing: true
|
86
|
+
end
|
87
|
+
|
88
|
+
it "looks up the whole nesting" do
|
89
|
+
expect(@provider.lookup_path %w(some nested some)).to eq settings["some"]["nested"]["some"]
|
90
|
+
end
|
91
|
+
|
92
|
+
it "returns nil if no setting is found" do
|
93
|
+
expect {
|
94
|
+
@provider.lookup_path ["not_me"]
|
95
|
+
}.to raise_error Configurate::MissingSetting
|
96
|
+
end
|
97
|
+
end
|
80
98
|
end
|
81
99
|
end
|
@@ -1,10 +1,10 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe Configurate::Provider::Base do
|
4
4
|
describe "#lookup" do
|
5
5
|
subject { described_class.new }
|
6
6
|
it "calls #lookup_path" do
|
7
|
-
path = Configurate::SettingPath.new(
|
7
|
+
path = Configurate::SettingPath.new(%w(foo bar))
|
8
8
|
expect(subject).to receive(:lookup_path).with(path).and_return("something")
|
9
9
|
expect(subject.lookup(path)).to eq "something"
|
10
10
|
end
|
@@ -15,5 +15,17 @@ describe Configurate::Provider::Base do
|
|
15
15
|
subject.lookup("bla")
|
16
16
|
}.to raise_error Configurate::SettingNotFoundError
|
17
17
|
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "::lookup_in_hash" do
|
22
|
+
let(:hash) { {foo: {bar: nil}} }
|
23
|
+
it "returns nil if key is nil" do
|
24
|
+
expect(Configurate::Provider.lookup_in_hash(%i(foo bar), hash) { :fallback }).to be_nil
|
25
|
+
end
|
26
|
+
|
27
|
+
it "returns fallback for a non-existent key" do
|
28
|
+
expect(Configurate::Provider.lookup_in_hash(%i(foo bar baz), hash) { :fallback }).to eq :fallback
|
29
|
+
end
|
18
30
|
end
|
19
31
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe Configurate::Proxy do
|
4
4
|
let(:lookup_chain) { double(lookup: "something") }
|
@@ -9,9 +9,9 @@ describe Configurate::Proxy do
|
|
9
9
|
pending "If anyone knows a sane way to overwrite Module#===, please tell me :P"
|
10
10
|
result = case proxy
|
11
11
|
when String
|
12
|
-
|
12
|
+
"string"
|
13
13
|
else
|
14
|
-
|
14
|
+
"wrong"
|
15
15
|
end
|
16
16
|
expect(result).to eq "string"
|
17
17
|
end
|
@@ -54,9 +54,8 @@ describe Configurate::Proxy do
|
|
54
54
|
end
|
55
55
|
|
56
56
|
describe "#target" do
|
57
|
-
|
58
|
-
|
59
|
-
:start_with?, :end_with?].each do |method|
|
57
|
+
%i(to_s to_xml respond_to? present? != eql? each try size length
|
58
|
+
count == =~ gsub blank? chop start_with? end_with?).each do |method|
|
60
59
|
it "is called for accessing #{method} on the proxy" do
|
61
60
|
target = double(respond_to?: true, _proxy?: false)
|
62
61
|
allow(lookup_chain).to receive(:lookup).and_return(target)
|
@@ -80,22 +79,22 @@ describe Configurate::Proxy do
|
|
80
79
|
|
81
80
|
it "converts to a string" do
|
82
81
|
allow(lookup_chain).to receive(:lookup).and_return("bar")
|
83
|
-
expect("foo
|
82
|
+
expect("foo#{proxy.something}").to eq "foobar"
|
84
83
|
end
|
85
84
|
|
86
85
|
it "converts to a number" do
|
87
86
|
allow(lookup_chain).to receive(:lookup).and_return(1)
|
88
|
-
expect(2+proxy.something).to eq 3
|
87
|
+
expect(2 + proxy.something).to eq 3
|
89
88
|
end
|
90
89
|
|
91
90
|
it "converts to an array" do
|
92
91
|
allow(lookup_chain).to receive(:lookup).and_return([1, 2])
|
93
|
-
expect(
|
92
|
+
expect(%i(a b).zip(proxy.something)).to eq [[:a, 1], [:b, 2]]
|
94
93
|
end
|
95
94
|
|
96
95
|
it "converts to a hash" do
|
97
|
-
allow(lookup_chain).to receive(:lookup).and_return(
|
98
|
-
expect({c: :d}.merge(proxy.something)).to eq
|
96
|
+
allow(lookup_chain).to receive(:lookup).and_return(a: :b)
|
97
|
+
expect({c: :d}.merge(proxy.something)).to eq a: :b, c: :d
|
99
98
|
end
|
100
99
|
end
|
101
100
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe Configurate::SettingPath do
|
4
4
|
let(:normal_path) { described_class.new([:foo]) }
|
@@ -53,7 +53,7 @@ describe Configurate::SettingPath do
|
|
53
53
|
|
54
54
|
describe "#initialize_copy" do
|
55
55
|
it "modifying a copy leaves the original unchanged" do
|
56
|
-
original = described_class.new
|
56
|
+
original = described_class.new %w(foo bar)
|
57
57
|
copy = original.clone
|
58
58
|
copy << "baz"
|
59
59
|
expect(copy).to include "baz"
|
@@ -61,7 +61,6 @@ describe Configurate::SettingPath do
|
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
|
-
|
65
64
|
describe "#question_action_or_setter?" do
|
66
65
|
context "with a question signature as setting" do
|
67
66
|
subject { question_path.question_action_or_setter? }
|
@@ -86,22 +85,22 @@ describe Configurate::SettingPath do
|
|
86
85
|
|
87
86
|
describe "#each" do
|
88
87
|
it "should strip special characters" do
|
89
|
-
expect(long_path.all? {
|
88
|
+
expect(long_path.all? {|c| c.include? "?" }).to be_falsey
|
90
89
|
end
|
91
90
|
end
|
92
91
|
|
93
|
-
|
92
|
+
%i(join first last shift pop).each do |method|
|
94
93
|
describe "##{method}" do
|
95
94
|
subject { question_path.public_send method }
|
96
95
|
it { should_not include "?" }
|
97
96
|
end
|
98
97
|
end
|
99
98
|
|
100
|
-
|
99
|
+
%i(<< unshift push).each do |method|
|
101
100
|
describe "##{method}" do
|
102
|
-
it
|
101
|
+
it "converts the argument to a string" do
|
103
102
|
arg = double
|
104
|
-
expect(arg).to receive(:to_s).and_return(
|
103
|
+
expect(arg).to receive(:to_s).and_return("bar")
|
105
104
|
described_class.new.public_send method, arg
|
106
105
|
end
|
107
106
|
end
|
@@ -120,7 +119,7 @@ describe Configurate::SettingPath do
|
|
120
119
|
|
121
120
|
describe "#inspect" do
|
122
121
|
it "includes the dotted path" do
|
123
|
-
path = described_class.new(
|
122
|
+
path = described_class.new(%i(foo bar))
|
124
123
|
expect(path.inspect).to include "foo.bar"
|
125
124
|
end
|
126
125
|
end
|
data/spec/configurate_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe Configurate::Settings do
|
4
4
|
describe "#method_missing" do
|
@@ -12,7 +12,7 @@ describe Configurate::Settings do
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
|
15
|
+
%i(lookup add_provider []).each do |method|
|
16
16
|
describe "#{method}" do
|
17
17
|
subject { described_class.create }
|
18
18
|
|
data/spec/spec_helper.rb
CHANGED
@@ -5,13 +5,12 @@
|
|
5
5
|
#
|
6
6
|
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
7
|
|
8
|
-
|
9
8
|
begin
|
10
|
-
require
|
9
|
+
require "coveralls"
|
11
10
|
Coveralls.wear!
|
12
11
|
rescue LoadError; end
|
13
12
|
|
14
|
-
require
|
13
|
+
require "configurate"
|
15
14
|
|
16
15
|
def silence_stderr
|
17
16
|
$stderr = StringIO.new
|
@@ -27,7 +26,7 @@ RSpec.configure do |config|
|
|
27
26
|
# order dependency and want to debug it, you can fix the order by providing
|
28
27
|
# the seed, which is printed after each run.
|
29
28
|
# --seed 1234
|
30
|
-
config.order =
|
29
|
+
config.order = "random"
|
31
30
|
|
32
31
|
config.expect_with :rspec do |expect_config|
|
33
32
|
expect_config.syntax = :expect
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: configurate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonne Haß
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-05-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -85,18 +85,18 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
85
85
|
version: '0'
|
86
86
|
requirements: []
|
87
87
|
rubyforge_project:
|
88
|
-
rubygems_version: 2.4.
|
88
|
+
rubygems_version: 2.4.5
|
89
89
|
signing_key:
|
90
90
|
specification_version: 4
|
91
91
|
summary: Flexbile configuration system
|
92
92
|
test_files:
|
93
|
-
- spec/configurate/provider_spec.rb
|
94
|
-
- spec/configurate/lookup_chain_spec.rb
|
95
|
-
- spec/configurate/provider/yaml_spec.rb
|
96
|
-
- spec/configurate/provider/env_spec.rb
|
97
93
|
- spec/configurate/provider/dynamic_spec.rb
|
94
|
+
- spec/configurate/provider/env_spec.rb
|
95
|
+
- spec/configurate/provider/yaml_spec.rb
|
98
96
|
- spec/configurate/setting_path_spec.rb
|
99
97
|
- spec/configurate/proxy_spec.rb
|
98
|
+
- spec/configurate/provider_spec.rb
|
99
|
+
- spec/configurate/lookup_chain_spec.rb
|
100
100
|
- spec/spec_helper.rb
|
101
101
|
- spec/configurate_spec.rb
|
102
102
|
has_rdoc:
|
checksums.yaml.gz.asc
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
-----BEGIN PGP SIGNATURE-----
|
2
|
-
Version: GnuPG v2
|
3
|
-
|
4
|
-
iQEcBAABAgAGBQJULyg7AAoJEPNH4OtHrHDWLzkIAIwwqTjkZlNOPS2D7tUOcNJY
|
5
|
-
ZF/zxymbrSL9yjzXwvYExgKy2i1xV5LrWpWP/mCiX9RX2eLxv8LcQGlWKupCwMc9
|
6
|
-
2ca/yy1wziXLhLY6zJhWF5j6WNOfRlJTGaAUPSHtbCeT9WOjbpnDWfWTDZKNuonb
|
7
|
-
i1HPUCZPx+YAXb6Gzgl39FcCH1UgEZy3D3ijc3FCSHigfnwSEDcjCwQtQuMedwNu
|
8
|
-
l1/V5UdTPDiWPBxeGMucyZLBKdN8r70wfgNKvDZ1XHolO+9HUOsmcS6St1P5OpUp
|
9
|
-
dJ25Tm3ACv+uydyQLr/e2bPJs+Lm901rKUMb+gIozoQCYMTRnpAoNMVNqK+KRBI=
|
10
|
-
=+ZIR
|
11
|
-
-----END PGP SIGNATURE-----
|
data.tar.gz.asc
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
-----BEGIN PGP SIGNATURE-----
|
2
|
-
Version: GnuPG v2
|
3
|
-
|
4
|
-
iQEcBAABAgAGBQJULyg7AAoJEPNH4OtHrHDWgO0H/jLKCQPi2kguHzfJU/k4hII8
|
5
|
-
VITtYbNZb4ZBbHecgiam4mI+m5EvDCfQu3KEzSN3w06czUoVFW0uCABJkAqb43He
|
6
|
-
EvITE2z36GKFb8GqfA5EXnRPjmsGTvH8EnUG8DetTRNjFkERvNSi6t3RxgfNQ8yw
|
7
|
-
UFwtascrsmM5vjzCvgRlJ0cm1HA3LZFqoEyw/MovOLDviLTz1ECKqxNmaEULdhp9
|
8
|
-
Fb10e5Y9XalRbbF6wSOKWp06owiEcTVY/lqNOZBJ+ZIG1RQUD73yhAGW2b7bM6rg
|
9
|
-
tiBEAal1Tt6c5v5SvucCcMrKxd3R8CXCtwETQVFl4rxB4eYhSgx0PkFiQ3OPicY=
|
10
|
-
=hJkd
|
11
|
-
-----END PGP SIGNATURE-----
|
metadata.gz.asc
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
-----BEGIN PGP SIGNATURE-----
|
2
|
-
Version: GnuPG v2
|
3
|
-
|
4
|
-
iQEcBAABAgAGBQJULyg7AAoJEPNH4OtHrHDWD0IH/0e90hWnDOQqWhUnKY3JM+gf
|
5
|
-
wOdHXiyB4p7cPIoO6QFsZq0Mm4t+bYLADI3adDq9kQAtIjo6s3jUJzK84QNjnsNS
|
6
|
-
8Sc1OWNFYLrMVi/7rkJfyjiV6rMHYyB9O76vxH3w7/CZAl7fscadF4BW1PTqcti8
|
7
|
-
z4IoXtBs5KVxk1U3vtpPLaYitYIx/mc2voL0Z5wEuMeBhTYHjx4XraLrNzuSh6yN
|
8
|
-
cRnItaD70Z2uIvRF6bSyazDLWEO2cUfH/kTjsjHja4xwa4yYm3/ZkFZ2YZAXJNvU
|
9
|
-
P5mtnv5cCcJKZy1uNKV5DRj9zATL+yrzgSaSKV1O9BPW7zL3eHeu156TOxIRW48=
|
10
|
-
=sUo3
|
11
|
-
-----END PGP SIGNATURE-----
|