lite_config 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Build Status](https://travis-ci.org/gtd/lite_config.png?branch=master)](https://travis-ci.org/gtd/lite_config)
|
4
4
|
[![Code Climate](https://codeclimate.com/github/gtd/lite_config.png)](https://codeclimate.com/github/gtd/lite_config)
|
5
|
+
[![Gem Version](https://badge.fury.io/rb/lite_config.png)](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:
|