a9n 0.1.3 → 0.2.0
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/.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
|