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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c6fafa85c44eb1e47cfc4a8c8c75d1d5ad46c982
4
- data.tar.gz: 3e014475898cc21ec793573cae9873b35539fddd
3
+ metadata.gz: e369363c79fb9a656521140c1579f784a7e9dc4a
4
+ data.tar.gz: cfc947874a96b1884b65200baf180c7f85b5c30d
5
5
  SHA512:
6
- metadata.gz: 0ad1197d5321b3c868ff02c4d1265538d2fee85a9a24bf12a801dbac3e94f8f6705a5059315d5fec3472c2f2388b25c32d56006ed002cecea2adb30b6c98125a
7
- data.tar.gz: e2e61a41f5b9b53bc86f6640f7d8160acdfae31d04d4a81c847eab5d883ff92095d475b623a80f475a71318e0376c328002880d45b37c7498a66012b15a84729
6
+ metadata.gz: 87fe223271b1188c7df2322279456879bf47a6abfb5c97b9d7ca95faf81d13a9fdae9bce28d2fa6df47ad86f5a361660ccc55153ed4904f7bd099408bc819093
7
+ data.tar.gz: 4c452ad39305bc59df2c81ab207ee98424e8a80967055caebc6fc035b88432f510a49caaa7621053be67ea62faa40859be50cedf8bdeb48a7d5fce11ac31e1c9
@@ -1,6 +1,8 @@
1
1
  language: ruby
2
2
  rvm:
3
- - "1.9.3"
4
- - "2.0.0"
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.1
5
6
  - jruby-19mode
6
- - rbx-19mode
7
+ - rbx-2.0.0
8
+ - rbx-2.1.1
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012 knapo
1
+ Copyright (c) 2013 Krzysztof Knapik @knapo
2
2
 
3
3
  MIT License
4
4
 
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: 'http://knapo.net'
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)
@@ -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 'a9n/version'
2
- require 'a9n/struct'
3
- require 'a9n/core_ext/hash'
4
- require 'yaml'
5
- require 'erb'
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
- def config
17
- @@configuration ||= load
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('RAILS_ENV') || get_env_var('RACK_ENV') || get_env_var('APP_ENV')
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 load
46
- env_config = load_env_config
47
- default_config = load_default_config
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
- whole_config = default_config.merge(env_config)
53
+ whole_config = default_config.merge(env_config)
50
54
 
51
- @@configuration = Struct.new(whole_config)
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('config/configuration.yml.example', env)
56
- local = load_yml('config/configuration.yml', env)
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/configuration.yml.example nor config/configuration.yml was found")
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('config/configuration.yml.example', 'defaults', false)
71
- data ||= load_yml('config/configuration.yml', 'defaults', false)
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
- config.fetch(*args)
101
+ scope(DEFAULT_SCOPE).fetch(*args)
97
102
  end
98
103
 
99
104
  def method_missing(name, *args)
100
- config.send(name, *args)
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
@@ -1,3 +1,3 @@
1
1
  module A9n
2
- VERSION = "0.1.3"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -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 Kiełbasa', api_key: 'base1234default' }
59
+ { page_title: 'Base Kielbasa', api_key: 'base1234default' }
58
60
  }
59
61
  let(:local_default_config){
60
- { page_title: 'Local Kiełbasa', api_key: 'local1234default' }
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('config/configuration.yml.example', env).and_return(nil)
75
- expect(described_class).to receive(:load_yml).with('config/configuration.yml', env).and_return(nil)
76
- expect(described_class).to receive(:load_yml).with('config/configuration.yml.example', 'defaults', false).never
77
- expect(described_class).to receive(:load_yml).with('config/configuration.yml', 'defaults', false).never
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('config/configuration.yml.example', env).and_return(base_sample_config)
90
- expect(described_class).to receive(:load_yml).with('config/configuration.yml', env).and_return(nil)
91
- expect(described_class).to receive(:load_yml).with('config/configuration.yml.example', 'defaults', false).and_return(base_default_config)
92
- expect(described_class).to receive(:load_yml).with('config/configuration.yml', 'defaults', false).never
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 Kiełbasa' }
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('config/configuration.yml.example', env).and_return(nil)
110
- expect(described_class).to receive(:load_yml).with('config/configuration.yml', env).and_return(local_sample_config)
111
- expect(described_class).to receive(:load_yml).with('config/configuration.yml.example', 'defaults', false).and_return(nil)
112
- expect(described_class).to receive(:load_yml).with('config/configuration.yml', 'defaults', false).and_return(local_default_config)
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 Kiełbasa' }
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('config/configuration.yml.example', env).and_return(base_sample_config)
129
- expect(described_class).to receive(:load_yml).with('config/configuration.yml', env).and_return(base_sample_config)
130
- expect(described_class).to receive(:load_yml).with('config/configuration.yml.example', 'defaults', false).and_return(nil)
131
- expect(described_class).to receive(:load_yml).with('config/configuration.yml', 'defaults', false).and_return(nil)
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('config/configuration.yml.example', env).and_return(base_sample_config)
148
- expect(described_class).to receive(:load_yml).with('config/configuration.yml', env).and_return(local_sample_config)
149
- expect(described_class).to receive(:load_yml).with('config/configuration.yml.example', 'defaults', false).never
150
- expect(described_class).to receive(:load_yml).with('config/configuration.yml', 'defaults', false).never
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.should be_nil
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.should be_kind_of(Hash)
188
- subject.keys.should_not be_empty
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.1.3
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: 2013-11-05 00:00:00.000000000 Z
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.0.3
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