a9n 0.1.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +5 -3
- data/LICENSE +1 -1
- data/README.md +20 -4
- data/a9n.gemspec +1 -1
- data/lib/a9n.rb +42 -29
- data/lib/a9n/version.rb +1 -1
- data/spec/a9n_spec.rb +73 -47
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e369363c79fb9a656521140c1579f784a7e9dc4a
|
4
|
+
data.tar.gz: cfc947874a96b1884b65200baf180c7f85b5c30d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 87fe223271b1188c7df2322279456879bf47a6abfb5c97b9d7ca95faf81d13a9fdae9bce28d2fa6df47ad86f5a361660ccc55153ed4904f7bd099408bc819093
|
7
|
+
data.tar.gz: 4c452ad39305bc59df2c81ab207ee98424e8a80967055caebc6fc035b88432f510a49caaa7621053be67ea62faa40859be50cedf8bdeb48a7d5fce11ac31e1c9
|
data/.travis.yml
CHANGED
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -37,8 +37,6 @@ after budler requires:
|
|
37
37
|
A9n.root = File.expand_path('../..', __FILE__)
|
38
38
|
A9n.load
|
39
39
|
|
40
|
-
This step is not required, but recommended, as it configuration is loaded and
|
41
|
-
verified on evironment load.
|
42
40
|
|
43
41
|
It works with `Rails` by default. If you want to use `A9n` with non-rails app
|
44
42
|
you may need to tell it A9n:
|
@@ -50,13 +48,30 @@ you may need to tell it A9n:
|
|
50
48
|
You can access any variable defined in configuration files but delegating it to
|
51
49
|
`A9n`. E.g:
|
52
50
|
|
51
|
+
defaults:
|
52
|
+
email_from: 'no-reply@knapo.net'
|
53
53
|
production:
|
54
|
-
app_host: '
|
54
|
+
app_host: 'knapo.net'
|
55
|
+
development:
|
56
|
+
app_host: 'localhost:3000'
|
55
57
|
|
56
58
|
is accessible by:
|
57
59
|
|
58
|
-
A9n.app_host
|
60
|
+
A9n.app_host # => `knapo.net` in production and `localhost:3000` in development
|
61
|
+
A9n.email_from # => `no-reply@knapo.net` in all envs
|
59
62
|
|
63
|
+
## Custom and multiple configuration files
|
64
|
+
|
65
|
+
If you need to load config from custom files (e.g `config/mongo.yml` and `config/other.yml`), add:
|
66
|
+
|
67
|
+
A9n.load('mongo.yml', 'other.yml')
|
68
|
+
|
69
|
+
and the configuration is availble under `mongo` and `other` scopes:
|
70
|
+
|
71
|
+
A9n.mongo.varname
|
72
|
+
|
73
|
+
A9n.other.varname
|
74
|
+
|
60
75
|
## Contributing
|
61
76
|
|
62
77
|
1. Fork it
|
@@ -68,3 +83,4 @@ is accessible by:
|
|
68
83
|
### Contributors
|
69
84
|
|
70
85
|
* [Grzegorz Świrski](https://github.com/sognat)
|
86
|
+
* [Jakub Łopusiński](https://github.com/siemakuba)
|
data/a9n.gemspec
CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |gem|
|
|
7
7
|
gem.description = %q{Simple tool for managing extra configuration in ruby/rails apps}
|
8
8
|
gem.summary = %q{a9n is a simple tool for managing extra configuration in ruby/rails apps}
|
9
9
|
gem.homepage = "https://github.com/knapo/a9n"
|
10
|
-
|
10
|
+
gem.license = 'MIT'
|
11
11
|
gem.files = `git ls-files`.split($\)
|
12
12
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
13
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
data/lib/a9n.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
1
|
+
require "a9n/version"
|
2
|
+
require "a9n/struct"
|
3
|
+
require "a9n/core_ext/hash"
|
4
|
+
require "yaml"
|
5
|
+
require "erb"
|
6
6
|
|
7
7
|
module A9n
|
8
8
|
class ConfigurationNotLoaded < StandardError; end
|
@@ -10,15 +10,13 @@ module A9n
|
|
10
10
|
class MissingConfigurationData < StandardError; end
|
11
11
|
class MissingConfigurationVariables < StandardError; end
|
12
12
|
class NoSuchConfigurationVariable < StandardError; end
|
13
|
-
|
14
|
-
class << self
|
15
13
|
|
16
|
-
|
17
|
-
|
18
|
-
end
|
14
|
+
DEFAULT_FILE = 'configuration.yml'
|
15
|
+
DEFAULT_SCOPE = :configuration
|
19
16
|
|
17
|
+
class << self
|
20
18
|
def env
|
21
|
-
@env ||= local_app_env || get_env_var(
|
19
|
+
@env ||= local_app_env || get_env_var("RAILS_ENV") || get_env_var("RACK_ENV") || get_env_var("APP_ENV")
|
22
20
|
end
|
23
21
|
|
24
22
|
def local_app_env
|
@@ -42,21 +40,28 @@ module A9n
|
|
42
40
|
@root = path.empty? ? nil : Pathname.new(path.to_s)
|
43
41
|
end
|
44
42
|
|
45
|
-
def
|
46
|
-
|
47
|
-
|
43
|
+
def scope(name)
|
44
|
+
instance_variable_get(var_name_for(name)) || (name == DEFAULT_SCOPE && load.first)
|
45
|
+
end
|
46
|
+
|
47
|
+
def load(*files)
|
48
|
+
files = [DEFAULT_FILE] if files.empty?
|
49
|
+
files.map do |file|
|
50
|
+
env_config = load_env_config(file)
|
51
|
+
default_config = load_default_config(file)
|
48
52
|
|
49
|
-
|
53
|
+
whole_config = default_config.merge(env_config)
|
50
54
|
|
51
|
-
|
55
|
+
instance_variable_set(var_name_for(file), A9n::Struct.new(whole_config))
|
56
|
+
end
|
52
57
|
end
|
53
58
|
|
54
|
-
def load_env_config
|
55
|
-
base = load_yml(
|
56
|
-
local = load_yml(
|
59
|
+
def load_env_config(file)
|
60
|
+
base = load_yml("config/#{file}.example", env)
|
61
|
+
local = load_yml("config/#{file}", env)
|
57
62
|
|
58
63
|
if base.nil? && local.nil?
|
59
|
-
raise MissingConfigurationFile.new("Neither config
|
64
|
+
raise MissingConfigurationFile.new("Neither config/#{file}.example nor config/#{file} was found")
|
60
65
|
end
|
61
66
|
|
62
67
|
if !base.nil? && !local.nil?
|
@@ -66,9 +71,9 @@ module A9n
|
|
66
71
|
local || base
|
67
72
|
end
|
68
73
|
|
69
|
-
def load_default_config
|
70
|
-
data = load_yml(
|
71
|
-
data ||= load_yml(
|
74
|
+
def load_default_config(file = "configuration.yml")
|
75
|
+
data = load_yml("config/#{file}.example", "defaults", false)
|
76
|
+
data ||= load_yml("config/#{file}", "defaults", false)
|
72
77
|
data ||= {}
|
73
78
|
return data
|
74
79
|
end
|
@@ -77,7 +82,7 @@ module A9n
|
|
77
82
|
path = File.join(self.root, file)
|
78
83
|
return nil unless File.exists?(path)
|
79
84
|
yml = YAML.load(ERB.new(File.read(path)).result)
|
80
|
-
|
85
|
+
|
81
86
|
if yml[env].is_a?(Hash)
|
82
87
|
return yml[env].deep_symbolize_keys
|
83
88
|
elsif raise_when_not_found
|
@@ -93,11 +98,15 @@ module A9n
|
|
93
98
|
end
|
94
99
|
|
95
100
|
def fetch(*args)
|
96
|
-
|
101
|
+
scope(DEFAULT_SCOPE).fetch(*args)
|
97
102
|
end
|
98
103
|
|
99
104
|
def method_missing(name, *args)
|
100
|
-
|
105
|
+
if scope(name).is_a?(A9n::Struct)
|
106
|
+
scope(name)
|
107
|
+
else
|
108
|
+
scope(DEFAULT_SCOPE).send(name, *args)
|
109
|
+
end
|
101
110
|
end
|
102
111
|
|
103
112
|
def get_rails
|
@@ -105,16 +114,20 @@ module A9n
|
|
105
114
|
end
|
106
115
|
|
107
116
|
def get_env_var(name)
|
108
|
-
ENV[name]
|
117
|
+
ENV[name]
|
109
118
|
end
|
110
|
-
|
119
|
+
|
111
120
|
private
|
112
121
|
|
113
122
|
def verify!(base, local)
|
114
123
|
missing_keys = base.keys - local.keys
|
115
124
|
if missing_keys.any?
|
116
|
-
raise MissingConfigurationVariables.new("Following variables are missing in your configuration file: #{missing_keys.join(
|
125
|
+
raise MissingConfigurationVariables.new("Following variables are missing in your configuration file: #{missing_keys.join(",")}")
|
117
126
|
end
|
118
127
|
end
|
128
|
+
|
129
|
+
def var_name_for(file)
|
130
|
+
:"@#{file.to_s.split('.').first}"
|
131
|
+
end
|
119
132
|
end
|
120
133
|
end
|
data/lib/a9n/version.rb
CHANGED
data/spec/a9n_spec.rb
CHANGED
@@ -10,7 +10,7 @@ describe A9n do
|
|
10
10
|
described_class.local_app.should be_nil
|
11
11
|
}
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
context 'when custom non-rails app is being used' do
|
15
15
|
let(:local_app) { double(env: 'test', root: '/apps/a9n') }
|
16
16
|
before { described_class.local_app = local_app }
|
@@ -42,11 +42,13 @@ describe A9n do
|
|
42
42
|
|
43
43
|
after {
|
44
44
|
described_class.root = nil
|
45
|
-
described_class.local_app = nil
|
45
|
+
described_class.local_app = nil
|
46
46
|
}
|
47
47
|
end
|
48
|
-
|
48
|
+
|
49
49
|
describe '.load' do
|
50
|
+
let(:base_file) { described_class::DEFAULT_FILE }
|
51
|
+
let(:extra_file) { 'mongo.yml' }
|
50
52
|
let(:base_sample_config){
|
51
53
|
{ app_url: 'http://127.0.0.1:3000', api_key: 'base1234' }
|
52
54
|
}
|
@@ -54,16 +56,16 @@ describe A9n do
|
|
54
56
|
{ app_host: '127.0.0.1:3000', api_key: 'local1234' }
|
55
57
|
}
|
56
58
|
let(:base_default_config){
|
57
|
-
{ page_title: 'Base
|
59
|
+
{ page_title: 'Base Kielbasa', api_key: 'base1234default' }
|
58
60
|
}
|
59
61
|
let(:local_default_config){
|
60
|
-
{ page_title: 'Local
|
62
|
+
{ page_title: 'Local Kielbasa', api_key: 'local1234default' }
|
61
63
|
}
|
62
64
|
let(:env){
|
63
65
|
'tropical'
|
64
66
|
}
|
65
|
-
subject {
|
66
|
-
described_class
|
67
|
+
subject {
|
68
|
+
described_class
|
67
69
|
}
|
68
70
|
before do
|
69
71
|
allow(described_class).to receive(:env).and_return(env)
|
@@ -71,10 +73,10 @@ describe A9n do
|
|
71
73
|
|
72
74
|
context 'when no configuration file exists' do
|
73
75
|
before do
|
74
|
-
expect(described_class).to receive(:load_yml).with(
|
75
|
-
expect(described_class).to receive(:load_yml).with(
|
76
|
-
expect(described_class).to receive(:load_yml).with(
|
77
|
-
expect(described_class).to receive(:load_yml).with(
|
76
|
+
expect(described_class).to receive(:load_yml).with("config/#{base_file}.example", env).and_return(nil)
|
77
|
+
expect(described_class).to receive(:load_yml).with("config/#{base_file}", env).and_return(nil)
|
78
|
+
expect(described_class).to receive(:load_yml).with("config/#{base_file}.example", 'defaults', false).never
|
79
|
+
expect(described_class).to receive(:load_yml).with("config/#{base_file}", 'defaults', false).never
|
78
80
|
expect(described_class).to receive(:verify!).never
|
79
81
|
end
|
80
82
|
it 'raises expection' do
|
@@ -83,22 +85,25 @@ describe A9n do
|
|
83
85
|
}.should raise_error(described_class::MissingConfigurationFile)
|
84
86
|
end
|
85
87
|
end
|
86
|
-
|
88
|
+
|
87
89
|
context 'when base configuration file exists with defaults' do
|
88
90
|
before do
|
89
|
-
expect(described_class).to receive(:load_yml).with(
|
90
|
-
expect(described_class).to receive(:load_yml).with(
|
91
|
-
expect(described_class).to receive(:load_yml).with(
|
92
|
-
expect(described_class).to receive(:load_yml).with(
|
93
|
-
|
91
|
+
expect(described_class).to receive(:load_yml).with("config/#{base_file}.example", env).and_return(base_sample_config)
|
92
|
+
expect(described_class).to receive(:load_yml).with("config/#{base_file}", env).and_return(nil)
|
93
|
+
expect(described_class).to receive(:load_yml).with("config/#{base_file}.example", 'defaults', false).and_return(base_default_config)
|
94
|
+
expect(described_class).to receive(:load_yml).with("config/#{base_file}", 'defaults', false).never
|
95
|
+
|
94
96
|
expect(described_class).to receive(:verify!).never
|
95
97
|
described_class.load
|
96
98
|
end
|
97
|
-
|
99
|
+
|
98
100
|
its(:app_url) { should_not be_nil }
|
99
101
|
its(:app_url) { should == subject.fetch(:app_url) }
|
100
|
-
its(:page_title) { should == 'Base
|
102
|
+
its(:page_title) { should == 'Base Kielbasa' }
|
101
103
|
its(:api_key) { should == 'base1234' }
|
104
|
+
specify {
|
105
|
+
expect(subject.instance_variable_get("@configuration")).to be_kind_of(A9n::Struct)
|
106
|
+
}
|
102
107
|
specify {
|
103
108
|
expect { subject.app_host }.to raise_error(described_class::NoSuchConfigurationVariable)
|
104
109
|
}
|
@@ -106,16 +111,16 @@ describe A9n do
|
|
106
111
|
|
107
112
|
context 'when local configuration file exists with defaults' do
|
108
113
|
before do
|
109
|
-
expect(described_class).to receive(:load_yml).with(
|
110
|
-
expect(described_class).to receive(:load_yml).with(
|
111
|
-
expect(described_class).to receive(:load_yml).with(
|
112
|
-
expect(described_class).to receive(:load_yml).with(
|
114
|
+
expect(described_class).to receive(:load_yml).with("config/#{base_file}.example", env).and_return(nil)
|
115
|
+
expect(described_class).to receive(:load_yml).with("config/#{base_file}", env).and_return(local_sample_config)
|
116
|
+
expect(described_class).to receive(:load_yml).with("config/#{base_file}.example", 'defaults', false).and_return(nil)
|
117
|
+
expect(described_class).to receive(:load_yml).with("config/#{base_file}", 'defaults', false).and_return(local_default_config)
|
113
118
|
expect(described_class).to receive(:verify!).never
|
114
119
|
described_class.load
|
115
120
|
end
|
116
|
-
|
121
|
+
|
117
122
|
its(:app_host) { should_not be_nil }
|
118
|
-
its(:page_title) { should == 'Local
|
123
|
+
its(:page_title) { should == 'Local Kielbasa' }
|
119
124
|
its(:api_key) { should == 'local1234' }
|
120
125
|
specify {
|
121
126
|
expect { subject.app_url }.to raise_error(described_class::NoSuchConfigurationVariable)
|
@@ -125,15 +130,15 @@ describe A9n do
|
|
125
130
|
context 'when both local and base configuration file exists without defaults' do
|
126
131
|
context 'with same data' do
|
127
132
|
before do
|
128
|
-
expect(described_class).to receive(:load_yml).with(
|
129
|
-
expect(described_class).to receive(:load_yml).with(
|
130
|
-
expect(described_class).to receive(:load_yml).with(
|
131
|
-
expect(described_class).to receive(:load_yml).with(
|
133
|
+
expect(described_class).to receive(:load_yml).with("config/#{base_file}.example", env).and_return(base_sample_config)
|
134
|
+
expect(described_class).to receive(:load_yml).with("config/#{base_file}", env).and_return(base_sample_config)
|
135
|
+
expect(described_class).to receive(:load_yml).with("config/#{base_file}.example", 'defaults', false).and_return(nil)
|
136
|
+
expect(described_class).to receive(:load_yml).with("config/#{base_file}", 'defaults', false).and_return(nil)
|
132
137
|
described_class.load
|
133
138
|
end
|
134
|
-
|
135
|
-
its(:app_url) { should_not be_nil }
|
136
|
-
its(:api_key) { should == 'base1234' }
|
139
|
+
|
140
|
+
its(:app_url) { should_not be_nil }
|
141
|
+
its(:api_key) { should == 'base1234' }
|
137
142
|
specify {
|
138
143
|
expect { subject.page_title }.to raise_error(described_class::NoSuchConfigurationVariable)
|
139
144
|
}
|
@@ -144,10 +149,10 @@ describe A9n do
|
|
144
149
|
|
145
150
|
context 'with different data' do
|
146
151
|
before do
|
147
|
-
expect(described_class).to receive(:load_yml).with(
|
148
|
-
expect(described_class).to receive(:load_yml).with(
|
149
|
-
expect(described_class).to receive(:load_yml).with(
|
150
|
-
expect(described_class).to receive(:load_yml).with(
|
152
|
+
expect(described_class).to receive(:load_yml).with("config/#{base_file}.example", env).and_return(base_sample_config)
|
153
|
+
expect(described_class).to receive(:load_yml).with("config/#{base_file}", env).and_return(local_sample_config)
|
154
|
+
expect(described_class).to receive(:load_yml).with("config/#{base_file}.example", 'defaults', false).never
|
155
|
+
expect(described_class).to receive(:load_yml).with("config/#{base_file}", 'defaults', false).never
|
151
156
|
end
|
152
157
|
it 'raises expection' do
|
153
158
|
expect {
|
@@ -156,6 +161,27 @@ describe A9n do
|
|
156
161
|
end
|
157
162
|
end
|
158
163
|
end
|
164
|
+
|
165
|
+
context 'when extra file is loaded' do
|
166
|
+
before do
|
167
|
+
expect(described_class).to receive(:load_yml).with("config/#{extra_file}.example", env).and_return(base_sample_config)
|
168
|
+
expect(described_class).to receive(:load_yml).with("config/#{extra_file}", env).and_return(nil)
|
169
|
+
expect(described_class).to receive(:load_yml).with("config/#{extra_file}.example", 'defaults', false).and_return(base_default_config)
|
170
|
+
expect(described_class).to receive(:load_yml).with("config/#{extra_file}", 'defaults', false).never
|
171
|
+
|
172
|
+
expect(described_class).to receive(:verify!).never
|
173
|
+
described_class.load('mongo.yml')
|
174
|
+
end
|
175
|
+
|
176
|
+
it { expect(subject.mongo).to be_kind_of(A9n::Struct) }
|
177
|
+
it { expect(subject.instance_variable_get("@mongo")).to be_kind_of(A9n::Struct) }
|
178
|
+
it { expect(subject.mongo.app_url).to eq("http://127.0.0.1:3000") }
|
179
|
+
it { expect(subject.mongo.page_title).to eq('Base Kielbasa') }
|
180
|
+
it { expect(subject.mongo.api_key).to eq('base1234') }
|
181
|
+
specify {
|
182
|
+
expect { subject.mongo.app_host }.to raise_error(described_class::NoSuchConfigurationVariable)
|
183
|
+
}
|
184
|
+
end
|
159
185
|
end
|
160
186
|
|
161
187
|
describe '.load_yml' do
|
@@ -170,22 +196,22 @@ describe A9n do
|
|
170
196
|
|
171
197
|
context 'when file not exists' do
|
172
198
|
let(:file_path) { 'file_not_existing_in_universe.yml' }
|
173
|
-
|
199
|
+
|
174
200
|
it 'returns nil' do
|
175
|
-
subject.
|
201
|
+
expect(subject).to be_nil
|
176
202
|
end
|
177
203
|
end
|
178
204
|
|
179
205
|
context 'when file exists' do
|
180
206
|
let(:file_path) { 'fixtures/configuration.yml'}
|
181
|
-
before {
|
207
|
+
before {
|
182
208
|
ENV['DWARF'] = 'erbized dwarf'
|
183
209
|
}
|
184
210
|
|
185
211
|
context 'and has data' do
|
186
212
|
it 'returns non-empty hash' do
|
187
|
-
subject.
|
188
|
-
subject.keys.
|
213
|
+
expect(subject).to be_kind_of(Hash)
|
214
|
+
expect(subject.keys).to_not be_empty
|
189
215
|
end
|
190
216
|
|
191
217
|
it 'has symbolized keys' do
|
@@ -198,7 +224,7 @@ describe A9n do
|
|
198
224
|
subject[:erb_dwarf].should == 'erbized dwarf'
|
199
225
|
end
|
200
226
|
end
|
201
|
-
|
227
|
+
|
202
228
|
context 'and has no data' do
|
203
229
|
let(:env) { 'production' }
|
204
230
|
|
@@ -217,15 +243,15 @@ describe A9n do
|
|
217
243
|
}
|
218
244
|
|
219
245
|
context 'local_app_env is set' do
|
220
|
-
before {
|
246
|
+
before {
|
221
247
|
expect(described_class).to receive(:local_app).and_return(double(env: 'dwarf_env')).exactly(3).times
|
222
248
|
expect(described_class).to receive(:get_env_var).never
|
223
249
|
}
|
224
250
|
its(:env) { should == 'dwarf_env' }
|
225
251
|
end
|
226
252
|
|
227
|
-
context "when APP_ENV is set" do
|
228
|
-
before {
|
253
|
+
context "when APP_ENV is set" do
|
254
|
+
before {
|
229
255
|
expect(described_class).to receive(:local_app_env).and_return(nil)
|
230
256
|
expect(described_class).to receive(:get_env_var).with('RAILS_ENV').and_return(nil)
|
231
257
|
expect(described_class).to receive(:get_env_var).with('RACK_ENV').and_return(nil)
|
@@ -250,11 +276,11 @@ describe A9n do
|
|
250
276
|
Object.send(:remove_const, :Rails)
|
251
277
|
}
|
252
278
|
it {
|
253
|
-
described_class.get_rails.should be_kind_of(Module)
|
279
|
+
described_class.get_rails.should be_kind_of(Module)
|
254
280
|
}
|
255
281
|
end
|
256
282
|
context 'when not defined' do
|
257
283
|
it { described_class.get_rails.should be_nil }
|
258
284
|
end
|
259
285
|
end
|
260
|
-
end
|
286
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: a9n
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Krzysztof Knapik
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-03-12 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Simple tool for managing extra configuration in ruby/rails apps
|
14
14
|
email:
|
@@ -33,7 +33,8 @@ files:
|
|
33
33
|
- spec/spec_helper.rb
|
34
34
|
- spec/struct_spec.rb
|
35
35
|
homepage: https://github.com/knapo/a9n
|
36
|
-
licenses:
|
36
|
+
licenses:
|
37
|
+
- MIT
|
37
38
|
metadata: {}
|
38
39
|
post_install_message:
|
39
40
|
rdoc_options: []
|
@@ -51,7 +52,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
51
52
|
version: '0'
|
52
53
|
requirements: []
|
53
54
|
rubyforge_project:
|
54
|
-
rubygems_version: 2.
|
55
|
+
rubygems_version: 2.1.11
|
55
56
|
signing_key:
|
56
57
|
specification_version: 4
|
57
58
|
summary: a9n is a simple tool for managing extra configuration in ruby/rails apps
|