chamber 0.0.1 → 0.0.2
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/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +5 -0
- data/README.md +188 -2
- data/Rakefile +6 -1
- data/chamber.gemspec +2 -0
- data/lib/chamber.rb +81 -2
- data/lib/chamber/version.rb +1 -1
- data/spec/lib/chamber_spec.rb +224 -0
- data/spec/spec_helper.rb +8 -0
- metadata +23 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 06481d8263ba75487270bf6bc366357d8ea45e81
|
4
|
+
data.tar.gz: 7095ff800b808dae4ba3470fca3cdcab26072ec1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5d2971516f0228a5fc17ce2b29375b5fb6fd7475918c9ad6df934727b0e15f7176979e16ce93cb9201cf8b69123485186673d0adcdb000680efb665de5298b0e
|
7
|
+
data.tar.gz: 6f38b25d90ade7a0ddc3a07ecb00a069d4f078994f8edab98567434a48767b6459c2079679132df941528252b50208f4b590fdec3d6c3422aa09e0f1a9721f91
|
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
chamber
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.0.0-p247
|
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Chamber
|
1
|
+
# Chamber [](https://travis-ci.org/stevenhallen/chamber)
|
2
2
|
|
3
3
|
Chamber lets you source your Settings from an arbitrary number of YAML files and
|
4
4
|
provides a simple mechanism for overriding settings from the ENV, which is
|
@@ -20,7 +20,193 @@ Or install it yourself as:
|
|
20
20
|
|
21
21
|
## Usage
|
22
22
|
|
23
|
-
|
23
|
+
The following instructions are for a Rails app hosted on heroku with both
|
24
|
+
staging and production heroku environments.
|
25
|
+
|
26
|
+
Create a Settings class that extends Chamber in `app/models/settings.rb`:
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
class Settings
|
30
|
+
extend Chamber
|
31
|
+
end
|
32
|
+
```
|
33
|
+
|
34
|
+
Create a `config/settings.yml` that has this structure:
|
35
|
+
|
36
|
+
```yml
|
37
|
+
development:
|
38
|
+
some_setting: value for dev
|
39
|
+
some_password:
|
40
|
+
environment: ENV_VAR_NAME
|
41
|
+
test:
|
42
|
+
some_setting: value for test
|
43
|
+
some_password:
|
44
|
+
environment: ENV_VAR_NAME
|
45
|
+
staging:
|
46
|
+
some_setting: value for staging
|
47
|
+
some_password:
|
48
|
+
environment: ENV_VAR_NAME
|
49
|
+
production:
|
50
|
+
some_setting: value for production
|
51
|
+
some_password:
|
52
|
+
environment: ENV_VAR_NAME
|
53
|
+
```
|
54
|
+
|
55
|
+
Call `source` in your Settings class:
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
class Settings
|
59
|
+
extend Chamber
|
60
|
+
|
61
|
+
source Rails.root.join('config', 'settings.yml'), namespace: Rails.env, override_from_environment: true
|
62
|
+
end
|
63
|
+
```
|
64
|
+
|
65
|
+
Add environment-specific files for development and test to supply the values for
|
66
|
+
those environments. Make sure to add these to .gitignore.
|
67
|
+
|
68
|
+
Add another call to `source` for these files:
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
class Settings
|
72
|
+
extend Chamber
|
73
|
+
|
74
|
+
source Rails.root.join('config', 'settings.yml'), namespace: Rails.env, override_from_environment: true
|
75
|
+
source Rails.root.join('config', "credentials-#{Rails.env}.yml")
|
76
|
+
end
|
77
|
+
```
|
78
|
+
|
79
|
+
Use `heroku config` to set the `ENV_VAR_NAME` value for the staging and
|
80
|
+
production remotes.
|
81
|
+
|
82
|
+
Now you can access your settings in your code from `Settings.instance` (assuming
|
83
|
+
you extended Chamber in a class named `Settings`).
|
84
|
+
|
85
|
+
In other words, given a configuration file like this:
|
86
|
+
|
87
|
+
```yml
|
88
|
+
s3:
|
89
|
+
access_key_id: value
|
90
|
+
secret_access_key: value
|
91
|
+
bucket: value
|
92
|
+
```
|
93
|
+
|
94
|
+
the corresponding Paperclip configuration would look like this:
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
Paperclip::Attachment.default_options.merge!(
|
98
|
+
storage: 's3',
|
99
|
+
s3_credentials: {
|
100
|
+
access_key_id: Settings.instance.s3.access_key_id,
|
101
|
+
secret_access_key: Settings.instance.s3.secret_access_key
|
102
|
+
},
|
103
|
+
bucket: Settings.instance.s3.bucket,
|
104
|
+
...
|
105
|
+
```
|
106
|
+
|
107
|
+
## General Principles
|
108
|
+
|
109
|
+
### Support best practices with sensitive information
|
110
|
+
|
111
|
+
Generally this is expressed in this overly simplified form: "Don't store
|
112
|
+
sensitive information in git." A better way to say it is that you should store
|
113
|
+
sensitive information separate from non-sensitive information. There's nothing
|
114
|
+
inherently wrong with storing sensitive information in git. You just wouldn't
|
115
|
+
want to store it in a public repository.
|
116
|
+
|
117
|
+
If it weren't for this concern, managing settings would be trivial, easily
|
118
|
+
solved use any number of approaches (e.g., [like using YAML and ERB in an
|
119
|
+
initializer](http://urgetopunt.com/rails/2009/09/12/yaml-config-with-erb.html).
|
120
|
+
|
121
|
+
I recommend adding a pattern like this to `.gitignore`:
|
122
|
+
|
123
|
+
```
|
124
|
+
# Ignore the environment-specific files that contain the real credentials:
|
125
|
+
/config/credentials-*.yml
|
126
|
+
|
127
|
+
# But don't ignore the example file that shows the structure:
|
128
|
+
!/config/credentials-example.yml
|
129
|
+
```
|
130
|
+
|
131
|
+
You would then use Chamber like this:
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
class Settings
|
135
|
+
extend Chamber
|
136
|
+
source Rails.root.join('config', "credentials-#{Rails.env}.yml")
|
137
|
+
end
|
138
|
+
```
|
139
|
+
|
140
|
+
### Support arbitrary organization
|
141
|
+
|
142
|
+
You should be able to organize your settings files however you like. You want
|
143
|
+
one big jumbo settings.yml? You can do that with Chamber. You want a distinct
|
144
|
+
settings file for each specific concern? You can do that too.
|
145
|
+
|
146
|
+
Chamber supports this by allowing:
|
147
|
+
|
148
|
+
* Arbitrary number of files:
|
149
|
+
|
150
|
+
```ruby
|
151
|
+
class Settings
|
152
|
+
extend Chamber
|
153
|
+
|
154
|
+
source Rails.root.join('config', 'settings.yml')
|
155
|
+
source Rails.root.join('config', 'facebook.yml')
|
156
|
+
source Rails.root.join('config', 'twitter.yml')
|
157
|
+
source Rails.root.join('config', 'google-plus.yml')
|
158
|
+
end
|
159
|
+
```
|
160
|
+
|
161
|
+
* Environment-specific filenames (e.g., `settings-#{Rails.env}.yml`)
|
162
|
+
|
163
|
+
* Namespaces:
|
164
|
+
|
165
|
+
```ruby
|
166
|
+
class Settings
|
167
|
+
extend Chamber
|
168
|
+
|
169
|
+
source Rails.root.join('config', 'settings.yml'), namespace: Rails.env
|
170
|
+
end
|
171
|
+
```
|
172
|
+
|
173
|
+
### Support overriding setting values at runtime from ENV
|
174
|
+
|
175
|
+
[heroku](http://heroku.com) addons are configured from ENV. To support this,
|
176
|
+
Chamber's `source` method provides an `override_from_environment` option; e.g.,
|
177
|
+
|
178
|
+
```ruby
|
179
|
+
class Settings
|
180
|
+
extend Chamber
|
181
|
+
|
182
|
+
source Rails.root.join('config', 'settings.yml'), override_from_environment: true
|
183
|
+
end
|
184
|
+
```
|
185
|
+
|
186
|
+
## Ideas
|
187
|
+
|
188
|
+
* Add a rake task for validating environments (do all environments have the same
|
189
|
+
settings?)
|
190
|
+
|
191
|
+
* Add a rake task for setting Heroku environment variables.
|
192
|
+
|
193
|
+
## Alternatives
|
194
|
+
|
195
|
+
### figaro
|
196
|
+
|
197
|
+
[figaro](https://github.com/laserlemon/figaro)
|
198
|
+
|
199
|
+
### idkfa
|
200
|
+
|
201
|
+
[idkfa](https://github.com/bendyworks/idkfa)
|
202
|
+
|
203
|
+
### settingslogic
|
204
|
+
|
205
|
+
[settingslogic](https://github.com/binarylogic/settingslogic)
|
206
|
+
|
207
|
+
### Others?
|
208
|
+
|
209
|
+
I'd love to hear of other gems and/or approaches to settings!
|
24
210
|
|
25
211
|
## Contributing
|
26
212
|
|
data/Rakefile
CHANGED
data/chamber.gemspec
CHANGED
@@ -24,6 +24,8 @@ CHAMBER
|
|
24
24
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
25
25
|
spec.require_paths = ["lib"]
|
26
26
|
|
27
|
+
spec.add_runtime_dependency "hashie", "~> 2.0"
|
28
|
+
|
27
29
|
spec.add_development_dependency "bundler", "~> 1.3"
|
28
30
|
spec.add_development_dependency "rake"
|
29
31
|
spec.add_development_dependency "rspec", "~> 2.14"
|
data/lib/chamber.rb
CHANGED
@@ -1,5 +1,84 @@
|
|
1
|
-
require
|
1
|
+
require 'erb'
|
2
|
+
require 'hashie'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
require 'chamber/version'
|
2
6
|
|
3
7
|
module Chamber
|
4
|
-
|
8
|
+
class ChamberInvalidOptionError < ArgumentError; end
|
9
|
+
|
10
|
+
def source(filename, options={})
|
11
|
+
assert_valid_keys(options)
|
12
|
+
|
13
|
+
add_source(filename, options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def load!
|
17
|
+
sources.each do |source|
|
18
|
+
filename, options = source
|
19
|
+
|
20
|
+
load_source!(filename, options)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def clear!
|
25
|
+
@chamber_instance = nil
|
26
|
+
@chamber_sources = nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def reload!
|
30
|
+
@chamber_instance = nil
|
31
|
+
load!
|
32
|
+
end
|
33
|
+
|
34
|
+
def instance
|
35
|
+
@chamber_instance ||= Hashie::Mash.new
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def assert_valid_keys(options)
|
41
|
+
unknown_keys = options.keys - [:namespace, :override_from_environment]
|
42
|
+
|
43
|
+
raise(ChamberInvalidOptionError, options) unless unknown_keys.empty?
|
44
|
+
end
|
45
|
+
|
46
|
+
def sources
|
47
|
+
@chamber_sources ||= []
|
48
|
+
end
|
49
|
+
|
50
|
+
def add_source(filename, options)
|
51
|
+
sources << [filename, options]
|
52
|
+
end
|
53
|
+
|
54
|
+
def load_source!(filename, options)
|
55
|
+
return unless File.exists?(filename)
|
56
|
+
|
57
|
+
hash = hash_from_source(filename, options[:namespace])
|
58
|
+
if options[:override_from_environment]
|
59
|
+
override_from_environment!(hash)
|
60
|
+
end
|
61
|
+
|
62
|
+
instance.deep_merge!(hash)
|
63
|
+
end
|
64
|
+
|
65
|
+
def hash_from_source(filename, namespace)
|
66
|
+
contents = open(filename).read
|
67
|
+
hash = YAML.load(ERB.new(contents).result).to_hash || {}
|
68
|
+
hash = Hashie::Mash.new(hash)
|
69
|
+
|
70
|
+
namespace ? hash.fetch(namespace) : hash
|
71
|
+
end
|
72
|
+
|
73
|
+
def override_from_environment!(hash)
|
74
|
+
hash.each_pair do |key, value|
|
75
|
+
next unless value.is_a?(Hash)
|
76
|
+
|
77
|
+
if value.environment
|
78
|
+
hash[key] = ENV[value.environment]
|
79
|
+
else
|
80
|
+
override_from_environment!(value)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
5
84
|
end
|
data/lib/chamber/version.rb
CHANGED
@@ -0,0 +1,224 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'tempfile'
|
4
|
+
|
5
|
+
class Settings
|
6
|
+
extend Chamber
|
7
|
+
end
|
8
|
+
|
9
|
+
describe Chamber do
|
10
|
+
before do
|
11
|
+
Settings.clear!
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '.source' do
|
15
|
+
context 'when an invalid option is specified' do
|
16
|
+
let(:options) do
|
17
|
+
{ foo: 'bar' }
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'raises ChamberInvalidOptionError' do
|
21
|
+
expect { Settings.source('filename', options) }.to raise_error(Chamber::ChamberInvalidOptionError)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'when no options are specified' do
|
26
|
+
it 'does not raise an error' do
|
27
|
+
expect { Settings.source('filename') }.not_to raise_error
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'when valid options are specified' do
|
32
|
+
context 'and options only contains :namespace' do
|
33
|
+
let(:options) do
|
34
|
+
{ namespace: 'bar' }
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'does not raise an error' do
|
38
|
+
expect { Settings.source('filename', options) }.not_to raise_error
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'and options only contains :override_from_environment' do
|
43
|
+
let(:options) do
|
44
|
+
{ override_from_environment: 'bar' }
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'does not raise an error' do
|
48
|
+
expect { Settings.source('filename', options) }.not_to raise_error
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'and options contains both :namespace and :override_from_environment' do
|
53
|
+
let(:options) do
|
54
|
+
{
|
55
|
+
namespace: 'bar',
|
56
|
+
override_from_environment: 'bar'
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'does not raise an error' do
|
61
|
+
expect { Settings.source('filename', options) }.not_to raise_error
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '.load!' do
|
68
|
+
context 'when a non-existent file is specified' do
|
69
|
+
let(:file) { Tempfile.new('test') }
|
70
|
+
let!(:filename) { file.path }
|
71
|
+
|
72
|
+
before do
|
73
|
+
file.close
|
74
|
+
file.unlink
|
75
|
+
expect(File.exists?(filename)).to be_false
|
76
|
+
Settings.source filename
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'does not raise an error' do
|
80
|
+
expect { Settings.load! }.not_to raise_error
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'leaves the instance empty' do
|
84
|
+
Settings.load!
|
85
|
+
expect(Settings.instance).to be_empty
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'when an existing file is specified' do
|
90
|
+
let(:file) { Tempfile.new('test') }
|
91
|
+
let(:filename) { file.path }
|
92
|
+
let(:content) do
|
93
|
+
<<-CONTENT
|
94
|
+
secret:
|
95
|
+
environment: CHAMBER_TEST
|
96
|
+
development:
|
97
|
+
foo: bar dev
|
98
|
+
test:
|
99
|
+
foo: bar test
|
100
|
+
CONTENT
|
101
|
+
end
|
102
|
+
|
103
|
+
before do
|
104
|
+
file.write(content)
|
105
|
+
file.close
|
106
|
+
end
|
107
|
+
|
108
|
+
after do
|
109
|
+
file.unlink
|
110
|
+
end
|
111
|
+
|
112
|
+
context 'and no options are specified' do
|
113
|
+
before { Settings.source(filename) }
|
114
|
+
|
115
|
+
let(:expected) do
|
116
|
+
{
|
117
|
+
'secret' => {
|
118
|
+
'environment' => 'CHAMBER_TEST'
|
119
|
+
},
|
120
|
+
'development' => {
|
121
|
+
'foo' => 'bar dev'
|
122
|
+
},
|
123
|
+
'test' => {
|
124
|
+
'foo' => 'bar test'
|
125
|
+
}
|
126
|
+
}
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'loads all settings' do
|
130
|
+
Settings.load!
|
131
|
+
expect(Settings.instance.to_hash).to eq expected
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context 'and the :namespace option is specified' do
|
136
|
+
before { Settings.source(filename, namespace: namespace) }
|
137
|
+
|
138
|
+
context 'and it is valid' do
|
139
|
+
let(:namespace) { 'development' }
|
140
|
+
let(:expected) do
|
141
|
+
{
|
142
|
+
'foo' => 'bar dev'
|
143
|
+
}
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'loads settings for the specified namespace' do
|
147
|
+
Settings.load!
|
148
|
+
expect(Settings.instance.to_hash).to eq expected
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
context 'and it is not valid' do
|
153
|
+
let(:namespace) { 'staging' }
|
154
|
+
|
155
|
+
it 'raises a KeyError' do
|
156
|
+
expect { Settings.load! }.to raise_error(KeyError)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
context 'and the :override_from_environment option is specified' do
|
162
|
+
before { Settings.source(filename, override_from_environment: true) }
|
163
|
+
|
164
|
+
context 'and the environment variable is present' do
|
165
|
+
before { ENV['CHAMBER_TEST'] = 'value' }
|
166
|
+
|
167
|
+
it 'overrides the settings from the environment' do
|
168
|
+
Settings.load!
|
169
|
+
expect(Settings.instance.secret).to eq 'value'
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
context 'and the environment variable is not present' do
|
174
|
+
before { ENV.delete('CHAMBER_TEST') }
|
175
|
+
|
176
|
+
it 'sets the value to nil' do
|
177
|
+
Settings.load!
|
178
|
+
expect(Settings.instance.secret).to be_nil
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
describe '.reload!' do
|
186
|
+
context 'when a filename is changed after it is sourced and loaded' do
|
187
|
+
let(:file) { Tempfile.new('test') }
|
188
|
+
let!(:filename) { file.path }
|
189
|
+
let(:content) do
|
190
|
+
<<-CONTENT
|
191
|
+
initial: value
|
192
|
+
CONTENT
|
193
|
+
end
|
194
|
+
let(:modified) do
|
195
|
+
<<-MODIFIED
|
196
|
+
modified: changed
|
197
|
+
MODIFIED
|
198
|
+
end
|
199
|
+
|
200
|
+
before do
|
201
|
+
file.write(content)
|
202
|
+
file.close
|
203
|
+
Settings.source(filename)
|
204
|
+
Settings.load!
|
205
|
+
end
|
206
|
+
|
207
|
+
after do
|
208
|
+
file.unlink
|
209
|
+
end
|
210
|
+
|
211
|
+
it 'reloads the settings' do
|
212
|
+
File.open(filename, 'w') { |writer| writer.write(modified) }
|
213
|
+
|
214
|
+
expect { Settings.reload! }.to change { Settings.instance.to_hash }.from({ 'initial' => 'value' }).to({ 'modified' => 'changed' })
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
describe '.instance' do
|
220
|
+
it 'is a Hashie::Mash' do
|
221
|
+
expect(Settings.instance).to be_a(Hashie::Mash)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -2,3 +2,11 @@ require 'simplecov'
|
|
2
2
|
SimpleCov.start
|
3
3
|
|
4
4
|
require 'rspec'
|
5
|
+
require 'chamber'
|
6
|
+
|
7
|
+
RSpec.configure do |config|
|
8
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
9
|
+
config.filter_run focused: true
|
10
|
+
config.alias_example_to :fit, focused: true
|
11
|
+
config.run_all_when_everything_filtered = true
|
12
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chamber
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- stevenhallen
|
@@ -9,8 +9,22 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-11-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: hashie
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ~>
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '2.0'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ~>
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '2.0'
|
14
28
|
- !ruby/object:Gem::Dependency
|
15
29
|
name: bundler
|
16
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -79,6 +93,9 @@ extensions: []
|
|
79
93
|
extra_rdoc_files: []
|
80
94
|
files:
|
81
95
|
- .gitignore
|
96
|
+
- .ruby-gemset
|
97
|
+
- .ruby-version
|
98
|
+
- .travis.yml
|
82
99
|
- Gemfile
|
83
100
|
- LICENSE.txt
|
84
101
|
- README.md
|
@@ -86,6 +103,7 @@ files:
|
|
86
103
|
- chamber.gemspec
|
87
104
|
- lib/chamber.rb
|
88
105
|
- lib/chamber/version.rb
|
106
|
+
- spec/lib/chamber_spec.rb
|
89
107
|
- spec/spec_helper.rb
|
90
108
|
homepage: http://github.com/stevenhallen/chamber
|
91
109
|
licenses:
|
@@ -107,9 +125,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
107
125
|
version: '0'
|
108
126
|
requirements: []
|
109
127
|
rubyforge_project:
|
110
|
-
rubygems_version: 2.
|
128
|
+
rubygems_version: 2.0.3
|
111
129
|
signing_key:
|
112
130
|
specification_version: 4
|
113
131
|
summary: Heroku-friendly Settings
|
114
132
|
test_files:
|
133
|
+
- spec/lib/chamber_spec.rb
|
115
134
|
- spec/spec_helper.rb
|
135
|
+
has_rdoc:
|