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 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