lite_config 0.0.3 → 0.0.4
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 +7 -0
- data/.travis.yml +3 -2
- data/CHANGELOG.md +5 -0
- data/README.md +14 -1
- data/lib/lite_config.rb +12 -5
- data/lib/lite_config/hash.rb +19 -0
- data/lib/lite_config/hash_with_indifferent_access.rb +144 -0
- data/lib/lite_config/version.rb +1 -1
- data/lite_config.gemspec +0 -3
- data/spec/fixtures/basic_erb.yml.erb +2 -0
- data/spec/lite_config_spec.rb +10 -0
- data/spec/spec_helper.rb +0 -1
- metadata +19 -56
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5db4fcd568a95da45fd32bff70f82feafb5107c0
|
4
|
+
data.tar.gz: 72ee684d093272263d47850ff977cd126356cb3d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 97bd67457c73f00f51a481999530dfd237cef18f94bcdda01dfc190a4455346458316907319f06ac6657c86bef1caf67a0e8c7d02ba42798f1356a409fb2a7e4
|
7
|
+
data.tar.gz: 98c8e90c77d1366e037426d84ac79bb2c431139a04e2f8715b6b77c268d7d69fb5b45e7aa55e359fc03c3478f40ccbf5d88d86c5c60664f51f7e398663c62424
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
[](https://travis-ci.org/gtd/lite_config)
|
4
4
|
[](https://codeclimate.com/github/gtd/lite_config)
|
5
|
+
[](http://badge.fury.io/rb/lite_config)
|
5
6
|
|
6
7
|
LiteConfig automates the loading of Rails-style YAML config files. With a single line the config file is lazily loaded
|
7
8
|
and cached, automatically choosing the current environment's hash. It also supports local developer override via
|
@@ -50,6 +51,19 @@ you can do:
|
|
50
51
|
|
51
52
|
Of course any valid YAML will work, but it works particularly nicely with simple hashes and arrays.
|
52
53
|
|
54
|
+
#### ERB Config Files
|
55
|
+
|
56
|
+
You might want part of your config file to be dynamic, the most obvious use of
|
57
|
+
which would be to inject secrets from an environment variables. You do so by
|
58
|
+
adding an `.erb` extension to the file. For instance if you have the file
|
59
|
+
`config/options.yml.erb` you could pull in a secret key from the environment
|
60
|
+
like this:
|
61
|
+
|
62
|
+
development:
|
63
|
+
secret_key: abc123
|
64
|
+
production:
|
65
|
+
secret_key: <%= ENV['SECRET_KEY'] %>
|
66
|
+
|
53
67
|
#### Flat Config Files
|
54
68
|
|
55
69
|
Do you ever cringe when your config file uses advanced YAML features do duplicate the exact same hash for every
|
@@ -104,7 +118,6 @@ changed after the first config file is loaded as that could lead to the wrong da
|
|
104
118
|
## Future Ideas
|
105
119
|
|
106
120
|
* Convert LiteConfig to an insantiable class instead of a singleton
|
107
|
-
* Remove ActiveSupport dependency
|
108
121
|
* Ability to raise errors for undefined config keys
|
109
122
|
* Support TOML or other config formats
|
110
123
|
* Allow OpenStruct-like access to the config. I'm not 100% sure on the ROI of this feature.
|
data/lib/lite_config.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
require "lite_config/version"
|
2
2
|
|
3
|
-
require '
|
4
|
-
require '
|
3
|
+
require 'lite_config/hash'
|
4
|
+
require 'lite_config/hash_with_indifferent_access'
|
5
5
|
|
6
6
|
require 'yaml'
|
7
|
+
require 'erb'
|
7
8
|
|
8
9
|
module LiteConfig
|
9
10
|
class ImmutableError < StandardError; end
|
@@ -14,7 +15,7 @@ module LiteConfig
|
|
14
15
|
def fetch(name)
|
15
16
|
name = name.to_sym
|
16
17
|
@configs ||= {}
|
17
|
-
@configs.key?(name) ? @configs[name] : (@configs[name] =
|
18
|
+
@configs.key?(name) ? @configs[name] : (@configs[name] = IndifferentHash.new(load(name)))
|
18
19
|
end
|
19
20
|
|
20
21
|
def config_path=(path)
|
@@ -52,7 +53,11 @@ module LiteConfig
|
|
52
53
|
end
|
53
54
|
|
54
55
|
def load_single(filename)
|
55
|
-
hash =
|
56
|
+
hash = if File.extname(filename) == '.erb'
|
57
|
+
YAML.load ERB.new(IO.read(filename)).result
|
58
|
+
else
|
59
|
+
YAML.load_file filename
|
60
|
+
end
|
56
61
|
|
57
62
|
has_environmenty_key?(hash) ? hash[app_env] : hash
|
58
63
|
end
|
@@ -62,7 +67,9 @@ module LiteConfig
|
|
62
67
|
end
|
63
68
|
|
64
69
|
def config_filename(name)
|
65
|
-
File.join(config_path, name.to_s + '.yml')
|
70
|
+
filename = File.join(config_path, name.to_s + '.yml')
|
71
|
+
filename << '.erb' if File.exist?(filename + '.erb')
|
72
|
+
filename
|
66
73
|
end
|
67
74
|
|
68
75
|
def local_config_filename(name)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class Hash
|
2
|
+
# Copied from active_support
|
3
|
+
# http://apidock.com/rails/Hash/deep_merge%21
|
4
|
+
def deep_merge!(other_hash, &block)
|
5
|
+
other_hash.each_pair do |k,v|
|
6
|
+
tv = self[k]
|
7
|
+
if tv.is_a?(Hash) && v.is_a?(Hash)
|
8
|
+
self[k] = tv.deep_merge(v, &block)
|
9
|
+
else
|
10
|
+
self[k] = block && tv ? block.call(k, tv, v) : v
|
11
|
+
end
|
12
|
+
end
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
def deep_merge(other_hash, &block)
|
17
|
+
dup.deep_merge!(other_hash, &block)
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
# Copied from https://raw.github.com/mikel/mail/master/lib/mail/indifferent_hash.rb
|
2
|
+
# which itself is a copy from active_support
|
3
|
+
|
4
|
+
module LiteConfig
|
5
|
+
class IndifferentHash < Hash
|
6
|
+
|
7
|
+
def initialize(constructor = {})
|
8
|
+
if constructor.is_a?(Hash)
|
9
|
+
super()
|
10
|
+
update(constructor)
|
11
|
+
else
|
12
|
+
super(constructor)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def default(key = nil)
|
17
|
+
if key.is_a?(Symbol) && include?(key = key.to_s)
|
18
|
+
self[key]
|
19
|
+
else
|
20
|
+
super
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.new_from_hash_copying_default(hash)
|
25
|
+
IndifferentHash.new(hash).tap do |new_hash|
|
26
|
+
new_hash.default = hash.default
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
|
31
|
+
alias_method :regular_update, :update unless method_defined?(:regular_update)
|
32
|
+
|
33
|
+
# Assigns a new value to the hash:
|
34
|
+
#
|
35
|
+
# hash = HashWithIndifferentAccess.new
|
36
|
+
# hash[:key] = "value"
|
37
|
+
#
|
38
|
+
def []=(key, value)
|
39
|
+
regular_writer(convert_key(key), convert_value(value))
|
40
|
+
end
|
41
|
+
|
42
|
+
alias_method :store, :[]=
|
43
|
+
|
44
|
+
# Updates the instantized hash with values from the second:
|
45
|
+
#
|
46
|
+
# hash_1 = HashWithIndifferentAccess.new
|
47
|
+
# hash_1[:key] = "value"
|
48
|
+
#
|
49
|
+
# hash_2 = HashWithIndifferentAccess.new
|
50
|
+
# hash_2[:key] = "New Value!"
|
51
|
+
#
|
52
|
+
# hash_1.update(hash_2) # => {"key"=>"New Value!"}
|
53
|
+
#
|
54
|
+
def update(other_hash)
|
55
|
+
other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
|
56
|
+
self
|
57
|
+
end
|
58
|
+
|
59
|
+
alias_method :merge!, :update
|
60
|
+
|
61
|
+
# Checks the hash for a key matching the argument passed in:
|
62
|
+
#
|
63
|
+
# hash = HashWithIndifferentAccess.new
|
64
|
+
# hash["key"] = "value"
|
65
|
+
# hash.key? :key # => true
|
66
|
+
# hash.key? "key" # => true
|
67
|
+
#
|
68
|
+
def key?(key)
|
69
|
+
super(convert_key(key))
|
70
|
+
end
|
71
|
+
|
72
|
+
alias_method :include?, :key?
|
73
|
+
alias_method :has_key?, :key?
|
74
|
+
alias_method :member?, :key?
|
75
|
+
|
76
|
+
# Fetches the value for the specified key, same as doing hash[key]
|
77
|
+
def fetch(key, *extras)
|
78
|
+
super(convert_key(key), *extras)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Returns an array of the values at the specified indices:
|
82
|
+
#
|
83
|
+
# hash = HashWithIndifferentAccess.new
|
84
|
+
# hash[:a] = "x"
|
85
|
+
# hash[:b] = "y"
|
86
|
+
# hash.values_at("a", "b") # => ["x", "y"]
|
87
|
+
#
|
88
|
+
def values_at(*indices)
|
89
|
+
indices.collect {|key| self[convert_key(key)]}
|
90
|
+
end
|
91
|
+
|
92
|
+
# Returns an exact copy of the hash.
|
93
|
+
def dup
|
94
|
+
IndifferentHash.new(self)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Merges the instantized and the specified hashes together, giving precedence to the values from the second hash
|
98
|
+
# Does not overwrite the existing hash.
|
99
|
+
def merge(hash)
|
100
|
+
self.dup.update(hash)
|
101
|
+
end
|
102
|
+
|
103
|
+
# Performs the opposite of merge, with the keys and values from the first hash taking precedence over the second.
|
104
|
+
# This overloaded definition prevents returning a regular hash, if reverse_merge is called on a HashWithDifferentAccess.
|
105
|
+
def reverse_merge(other_hash)
|
106
|
+
super self.class.new_from_hash_copying_default(other_hash)
|
107
|
+
end
|
108
|
+
|
109
|
+
def reverse_merge!(other_hash)
|
110
|
+
replace(reverse_merge( other_hash ))
|
111
|
+
end
|
112
|
+
|
113
|
+
# Removes a specified key from the hash.
|
114
|
+
def delete(key)
|
115
|
+
super(convert_key(key))
|
116
|
+
end
|
117
|
+
|
118
|
+
def stringify_keys!; self end
|
119
|
+
def stringify_keys; dup end
|
120
|
+
def symbolize_keys; to_hash.symbolize_keys end
|
121
|
+
def to_options!; self end
|
122
|
+
|
123
|
+
def to_hash
|
124
|
+
Hash.new(default).merge!(self)
|
125
|
+
end
|
126
|
+
|
127
|
+
protected
|
128
|
+
|
129
|
+
def convert_key(key)
|
130
|
+
key.kind_of?(Symbol) ? key.to_s : key
|
131
|
+
end
|
132
|
+
|
133
|
+
def convert_value(value)
|
134
|
+
if value.class == Hash
|
135
|
+
self.class.new_from_hash_copying_default(value)
|
136
|
+
elsif value.is_a?(Array)
|
137
|
+
value.dup.replace(value.map { |e| convert_value(e) })
|
138
|
+
else
|
139
|
+
value
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
end
|
data/lib/lite_config/version.rb
CHANGED
data/lite_config.gemspec
CHANGED
@@ -18,10 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_dependency 'activesupport'
|
22
|
-
|
23
21
|
spec.add_development_dependency "bundler", "~> 1.3"
|
24
22
|
spec.add_development_dependency "rake"
|
25
23
|
spec.add_development_dependency "minitest", ">= 5.0.0"
|
26
|
-
spec.add_development_dependency "debugger"
|
27
24
|
end
|
data/spec/lite_config_spec.rb
CHANGED
@@ -35,6 +35,16 @@ describe LiteConfig do
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
+
describe "basic_erb config" do
|
39
|
+
before do
|
40
|
+
@config = LiteConfig(:basic_erb)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should find evaluated keys" do
|
44
|
+
@config[:option].must_equal 2
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
38
48
|
describe "nested config" do
|
39
49
|
before do
|
40
50
|
@config = LiteConfig(:nested)
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,96 +1,57 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lite_config
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.4
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Gabe da Silveira
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2016-08-07 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
|
-
- !ruby/object:Gem::Dependency
|
15
|
-
name: activesupport
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
|
-
requirements:
|
19
|
-
- - ! '>='
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version: '0'
|
22
|
-
type: :runtime
|
23
|
-
prerelease: false
|
24
|
-
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
|
-
requirements:
|
27
|
-
- - ! '>='
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: '0'
|
30
13
|
- !ruby/object:Gem::Dependency
|
31
14
|
name: bundler
|
32
15
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
16
|
requirements:
|
35
|
-
- - ~>
|
17
|
+
- - "~>"
|
36
18
|
- !ruby/object:Gem::Version
|
37
19
|
version: '1.3'
|
38
20
|
type: :development
|
39
21
|
prerelease: false
|
40
22
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
23
|
requirements:
|
43
|
-
- - ~>
|
24
|
+
- - "~>"
|
44
25
|
- !ruby/object:Gem::Version
|
45
26
|
version: '1.3'
|
46
27
|
- !ruby/object:Gem::Dependency
|
47
28
|
name: rake
|
48
29
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
30
|
requirements:
|
51
|
-
- -
|
31
|
+
- - ">="
|
52
32
|
- !ruby/object:Gem::Version
|
53
33
|
version: '0'
|
54
34
|
type: :development
|
55
35
|
prerelease: false
|
56
36
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
37
|
requirements:
|
59
|
-
- -
|
38
|
+
- - ">="
|
60
39
|
- !ruby/object:Gem::Version
|
61
40
|
version: '0'
|
62
41
|
- !ruby/object:Gem::Dependency
|
63
42
|
name: minitest
|
64
43
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
44
|
requirements:
|
67
|
-
- -
|
45
|
+
- - ">="
|
68
46
|
- !ruby/object:Gem::Version
|
69
47
|
version: 5.0.0
|
70
48
|
type: :development
|
71
49
|
prerelease: false
|
72
50
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
51
|
requirements:
|
75
|
-
- -
|
52
|
+
- - ">="
|
76
53
|
- !ruby/object:Gem::Version
|
77
54
|
version: 5.0.0
|
78
|
-
- !ruby/object:Gem::Dependency
|
79
|
-
name: debugger
|
80
|
-
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
|
-
requirements:
|
83
|
-
- - ! '>='
|
84
|
-
- !ruby/object:Gem::Version
|
85
|
-
version: '0'
|
86
|
-
type: :development
|
87
|
-
prerelease: false
|
88
|
-
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
|
-
requirements:
|
91
|
-
- - ! '>='
|
92
|
-
- !ruby/object:Gem::Version
|
93
|
-
version: '0'
|
94
55
|
description: Lightweight configuration for your ruby app. Reads Rails-style YAML
|
95
56
|
files from your config directory. Features include optional environment namespacing,
|
96
57
|
local convention-based override files, and indifferent (symbol vs string) access.
|
@@ -100,17 +61,20 @@ executables: []
|
|
100
61
|
extensions: []
|
101
62
|
extra_rdoc_files: []
|
102
63
|
files:
|
103
|
-
- .gitignore
|
104
|
-
- .travis.yml
|
64
|
+
- ".gitignore"
|
65
|
+
- ".travis.yml"
|
105
66
|
- CHANGELOG.md
|
106
67
|
- Gemfile
|
107
68
|
- LICENSE.txt
|
108
69
|
- README.md
|
109
70
|
- Rakefile
|
110
71
|
- lib/lite_config.rb
|
72
|
+
- lib/lite_config/hash.rb
|
73
|
+
- lib/lite_config/hash_with_indifferent_access.rb
|
111
74
|
- lib/lite_config/version.rb
|
112
75
|
- lite_config.gemspec
|
113
76
|
- spec/fixtures/basic.yml
|
77
|
+
- spec/fixtures/basic_erb.yml.erb
|
114
78
|
- spec/fixtures/empty_environment_override.yml
|
115
79
|
- spec/fixtures/empty_environment_override_local.yml
|
116
80
|
- spec/fixtures/empty_override.yml
|
@@ -126,30 +90,30 @@ files:
|
|
126
90
|
homepage: ''
|
127
91
|
licenses:
|
128
92
|
- MIT
|
93
|
+
metadata: {}
|
129
94
|
post_install_message:
|
130
95
|
rdoc_options: []
|
131
96
|
require_paths:
|
132
97
|
- lib
|
133
98
|
required_ruby_version: !ruby/object:Gem::Requirement
|
134
|
-
none: false
|
135
99
|
requirements:
|
136
|
-
- -
|
100
|
+
- - ">="
|
137
101
|
- !ruby/object:Gem::Version
|
138
102
|
version: '0'
|
139
103
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
140
|
-
none: false
|
141
104
|
requirements:
|
142
|
-
- -
|
105
|
+
- - ">="
|
143
106
|
- !ruby/object:Gem::Version
|
144
107
|
version: '0'
|
145
108
|
requirements: []
|
146
109
|
rubyforge_project:
|
147
|
-
rubygems_version:
|
110
|
+
rubygems_version: 2.4.5.1
|
148
111
|
signing_key:
|
149
|
-
specification_version:
|
112
|
+
specification_version: 4
|
150
113
|
summary: Lightweight configuration for your ruby app
|
151
114
|
test_files:
|
152
115
|
- spec/fixtures/basic.yml
|
116
|
+
- spec/fixtures/basic_erb.yml.erb
|
153
117
|
- spec/fixtures/empty_environment_override.yml
|
154
118
|
- spec/fixtures/empty_environment_override_local.yml
|
155
119
|
- spec/fixtures/empty_override.yml
|
@@ -162,4 +126,3 @@ test_files:
|
|
162
126
|
- spec/fixtures/override_local.yml
|
163
127
|
- spec/lite_config_spec.rb
|
164
128
|
- spec/spec_helper.rb
|
165
|
-
has_rdoc:
|