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.
@@ -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
@@ -1,6 +1,7 @@
1
1
  language: ruby
2
+ before_install: gem update bundler
2
3
  cache: bundler
3
4
  rvm:
4
- - 1.9.3
5
- - 2.0.0
6
5
  - 2.1.0
6
+ - 2.2.0
7
+ - 2.3.0
@@ -1,3 +1,8 @@
1
+ ### Version 0.0.4
2
+
3
+ * Allow ERB-processed config files (Federico Keen, Andy Dust)
4
+ * Remove ActiveSupport dependency (Sergio Tulentsev)
5
+
1
6
  ### Version 0.0.3
2
7
 
3
8
  * Fix error on missing config (thanks RKushnir)
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.
@@ -1,9 +1,10 @@
1
1
  require "lite_config/version"
2
2
 
3
- require 'active_support/core_ext/hash/deep_merge'
4
- require 'active_support/core_ext/hash/indifferent_access'
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] = HashWithIndifferentAccess.new(load(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 = YAML.load_file(filename)
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
@@ -1,3 +1,3 @@
1
1
  module LiteConfig
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -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
@@ -0,0 +1,2 @@
1
+ development:
2
+ option: <%= 1 + 1 %>
@@ -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)
@@ -1,6 +1,5 @@
1
1
  require 'bundler/setup'
2
2
  require 'minitest/autorun'
3
- require 'debugger'
4
3
 
5
4
  require 'lite_config'
6
5
 
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.3
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: 2014-01-26 00:00:00.000000000 Z
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: 1.8.23
110
+ rubygems_version: 2.4.5.1
148
111
  signing_key:
149
- specification_version: 3
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: