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.
@@ -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: