a9n 0.4.5 → 0.4.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +0 -1
- data/.rspec +3 -0
- data/lib/a9n.rb +9 -17
- data/lib/a9n/ext/hash.rb +6 -6
- data/lib/a9n/loader.rb +12 -11
- data/lib/a9n/scope.rb +24 -0
- data/lib/a9n/version.rb +1 -1
- data/spec/integration/a9n_spec.rb +7 -5
- data/spec/spec_helper.rb +14 -7
- data/spec/unit/a9n_spec.rb +2 -4
- data/spec/unit/loader_spec.rb +15 -18
- data/spec/unit/scope_spec.rb +27 -0
- data/spec/unit/struct_spec.rb +1 -3
- data/test_app/config/a9n/mandrill.yml +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 044172d147418c1f64d54e328192b4b9dbb06bd5
|
4
|
+
data.tar.gz: 2b2f7135afc4dc3805a0d14bf405547bfee1c0ec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fb2d5778aa099e48696f1ba15190efcbf643e047aa9f365aee02d0d9ef7d3aedb10b062f192b67829f18043624b86783797dd49c27d128dd2c6a4e86ea5fde5a
|
7
|
+
data.tar.gz: 267caee0c0c17a25d1dfbc9045fda30ce94903a370b672d68af413350c151f8ccbed519d19fdb4bbbc5ee1126f44795d96495e5cc1c63840271ae0755f0e8607
|
data/.gitignore
CHANGED
data/.rspec
ADDED
data/lib/a9n.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "a9n/version"
|
2
2
|
require "a9n/struct"
|
3
|
+
require "a9n/scope"
|
3
4
|
require "a9n/ext/hash"
|
4
5
|
require "a9n/loader"
|
5
6
|
require "yaml"
|
@@ -13,7 +14,6 @@ module A9n
|
|
13
14
|
class MissingConfigurationVariables < StandardError; end
|
14
15
|
class NoSuchConfigurationVariable < StandardError; end
|
15
16
|
|
16
|
-
DEFAULT_SCOPE = :configuration
|
17
17
|
EXTENSION_LIST = "{yml,yml.erb,yml.example,yml.erb.example}"
|
18
18
|
|
19
19
|
class << self
|
@@ -54,7 +54,7 @@ module A9n
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def default_files
|
57
|
-
files = Dir[root.join("config/#{
|
57
|
+
files = Dir[root.join("config/#{A9n::Scope::MAIN_NAME}.#{EXTENSION_LIST}").to_s]
|
58
58
|
files += Dir[root.join("config/a9n/*.#{EXTENSION_LIST}")]
|
59
59
|
files.map{ |f| f.sub(/.example$/,'') }.uniq
|
60
60
|
end
|
@@ -77,35 +77,27 @@ module A9n
|
|
77
77
|
private
|
78
78
|
|
79
79
|
def load_file(file)
|
80
|
-
|
81
|
-
scope_data = A9n::Loader.new(file, env).get
|
82
|
-
setup_scope(
|
80
|
+
scope = A9n::Scope.form_file_path(file)
|
81
|
+
scope_data = A9n::Loader.new(file, scope, env).get
|
82
|
+
setup_scope(scope, scope_data)
|
83
83
|
end
|
84
84
|
|
85
|
-
def setup_scope(
|
86
|
-
if
|
85
|
+
def setup_scope(scope, data)
|
86
|
+
if scope.main?
|
87
87
|
storage.merge(data)
|
88
88
|
def_delegator :storage, :fetch
|
89
89
|
def_delegators :storage, *data.keys
|
90
90
|
else
|
91
|
-
storage[name] = data
|
92
|
-
def_delegator :storage, name
|
91
|
+
storage[scope.name] = data
|
92
|
+
def_delegator :storage, scope.name
|
93
93
|
end
|
94
94
|
return data
|
95
95
|
end
|
96
96
|
|
97
|
-
def scope_name_from_file(file)
|
98
|
-
File.basename(file.to_s).split('.').first.to_sym
|
99
|
-
end
|
100
|
-
|
101
97
|
def get_absolute_paths_for(files)
|
102
98
|
files.map { |file| Pathname.new(file).absolute? ? file : self.root.join('config', file).to_s }
|
103
99
|
end
|
104
100
|
|
105
|
-
def default_scope?(scope)
|
106
|
-
scope.to_s == DEFAULT_SCOPE.to_s
|
107
|
-
end
|
108
|
-
|
109
101
|
def require_local_extension
|
110
102
|
return if app.nil? || root.nil?
|
111
103
|
local_extension_file = File.join(root, "config/a9n.rb")
|
data/lib/a9n/ext/hash.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
module A9n
|
2
|
-
class
|
2
|
+
class Hash
|
3
3
|
class << self
|
4
|
-
def deep_prepare(hash)
|
4
|
+
def deep_prepare(hash, scope)
|
5
5
|
hash.inject({}) do |result, (key, value)|
|
6
|
-
result[(key.to_sym rescue key)] = get_value(key, value)
|
6
|
+
result[(key.to_sym rescue key)] = get_value(key, value, scope)
|
7
7
|
result
|
8
8
|
end
|
9
9
|
end
|
@@ -15,11 +15,11 @@ module A9n
|
|
15
15
|
|
16
16
|
private
|
17
17
|
|
18
|
-
def get_value(key, value)
|
18
|
+
def get_value(key, value, scope)
|
19
19
|
if value.is_a?(::Hash)
|
20
|
-
deep_prepare(value)
|
20
|
+
deep_prepare(value, scope)
|
21
21
|
elsif value.is_a?(Symbol) && value == :env
|
22
|
-
ENV[key.
|
22
|
+
ENV[scope.full_key_name(key).upcase]
|
23
23
|
else
|
24
24
|
value
|
25
25
|
end
|
data/lib/a9n/loader.rb
CHANGED
@@ -2,11 +2,12 @@ require 'ostruct'
|
|
2
2
|
|
3
3
|
module A9n
|
4
4
|
class Loader
|
5
|
-
attr_reader :env, :local_file, :example_file
|
5
|
+
attr_reader :scope, :env, :local_file, :example_file
|
6
6
|
|
7
7
|
COMMON_SCOPE = "defaults"
|
8
8
|
|
9
|
-
def initialize(file_path, env)
|
9
|
+
def initialize(file_path, scope, env)
|
10
|
+
@scope = scope
|
10
11
|
@env = env.to_s
|
11
12
|
@local_file = file_path
|
12
13
|
@example_file = "#{file_path}.example"
|
@@ -17,8 +18,8 @@ module A9n
|
|
17
18
|
end
|
18
19
|
|
19
20
|
def load
|
20
|
-
local_config = self.class.load_yml(local_file, env)
|
21
|
-
example_config = self.class.load_yml(example_file, env)
|
21
|
+
local_config = self.class.load_yml(local_file, scope, env)
|
22
|
+
example_config = self.class.load_yml(example_file, scope, env)
|
22
23
|
|
23
24
|
if local_config.nil? && example_config.nil?
|
24
25
|
raise A9n::MissingConfigurationData.new("Configuration data for *#{env}* env was not found in neither *#{example_file}* nor *#{local_file}*")
|
@@ -32,19 +33,19 @@ module A9n
|
|
32
33
|
end
|
33
34
|
|
34
35
|
class << self
|
35
|
-
def load_yml(file_path, env)
|
36
|
+
def load_yml(file_path, scope, env)
|
36
37
|
return nil unless File.exists?(file_path)
|
37
38
|
yml = YAML.load(ERB.new(File.read(file_path)).result)
|
38
39
|
|
39
|
-
common_scope = prepare_yml_scope(yml, COMMON_SCOPE)
|
40
|
-
env_scope = prepare_yml_scope(yml, env)
|
40
|
+
common_scope = prepare_yml_scope(yml, scope, COMMON_SCOPE)
|
41
|
+
env_scope = prepare_yml_scope(yml, scope, env)
|
41
42
|
|
42
|
-
A9n::
|
43
|
+
A9n::Hash.merge(common_scope, env_scope)
|
43
44
|
end
|
44
45
|
|
45
|
-
def prepare_yml_scope(yml,
|
46
|
-
if yml[
|
47
|
-
A9n::
|
46
|
+
def prepare_yml_scope(yml, scope, env)
|
47
|
+
if yml[env].is_a?(::Hash)
|
48
|
+
A9n::Hash.deep_prepare(yml[env], scope)
|
48
49
|
else
|
49
50
|
nil
|
50
51
|
end
|
data/lib/a9n/scope.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
module A9n
|
2
|
+
class Scope
|
3
|
+
MAIN_NAME = :configuration
|
4
|
+
|
5
|
+
attr_reader :name
|
6
|
+
|
7
|
+
def initialize(name)
|
8
|
+
@name = name.to_sym
|
9
|
+
end
|
10
|
+
|
11
|
+
def main?
|
12
|
+
name == MAIN_NAME
|
13
|
+
end
|
14
|
+
|
15
|
+
def full_key_name(key)
|
16
|
+
main? ? key : "#{name}_#{key}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.form_file_path(path)
|
20
|
+
name = File.basename(path.to_s).split('.').first.to_sym
|
21
|
+
self.new(name)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/a9n/version.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
describe A9n do
|
1
|
+
RSpec.describe A9n do
|
4
2
|
subject { described_class }
|
5
3
|
|
6
4
|
let(:env) { "test" }
|
7
5
|
|
8
6
|
before do
|
9
7
|
clean_singleton(subject)
|
8
|
+
ENV["MANDRILL_API_KEY"] = "ASDF1234"
|
9
|
+
ENV["API_KEY"] = "XYZ999"
|
10
10
|
subject.app = double(env: env)
|
11
11
|
subject.root = File.expand_path("../../../test_app", __FILE__)
|
12
12
|
subject.load
|
@@ -14,6 +14,8 @@ describe A9n do
|
|
14
14
|
|
15
15
|
after do
|
16
16
|
clean_singleton(subject)
|
17
|
+
ENV.delete("MANDRILL_API_KEY")
|
18
|
+
ENV.delete("API_KEY")
|
17
19
|
end
|
18
20
|
|
19
21
|
context "base config file" do
|
@@ -65,12 +67,12 @@ describe A9n do
|
|
65
67
|
|
66
68
|
it do
|
67
69
|
expect(subject.mandrill.username).to eq("joe")
|
68
|
-
expect(subject.mandrill.api_key).to eq("
|
70
|
+
expect(subject.mandrill.api_key).to eq("ASDF1234")
|
69
71
|
end
|
70
72
|
|
71
73
|
it do
|
72
74
|
expect(subject.mandrill.fetch(:username)).to eq("joe")
|
73
|
-
expect(subject.mandrill.fetch(:api_key)).to eq("
|
75
|
+
expect(subject.mandrill.fetch(:api_key)).to eq("ASDF1234")
|
74
76
|
end
|
75
77
|
|
76
78
|
it do
|
data/spec/spec_helper.rb
CHANGED
@@ -1,17 +1,24 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "simplecov"
|
2
|
+
require "codeclimate-test-reporter"
|
3
3
|
|
4
4
|
CodeClimate::TestReporter.start
|
5
5
|
|
6
|
-
require
|
7
|
-
require
|
6
|
+
require "rubygems"
|
7
|
+
require "bundler/setup"
|
8
8
|
|
9
|
-
require
|
9
|
+
require "a9n"
|
10
10
|
|
11
11
|
RSpec.configure do |config|
|
12
|
-
config.
|
13
|
-
|
12
|
+
config.disable_monkey_patching!
|
13
|
+
|
14
|
+
config.expect_with :rspec do |expectations|
|
15
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
16
|
+
end
|
17
|
+
|
18
|
+
config.mock_with :rspec do |mocks|
|
19
|
+
mocks.verify_partial_doubles = true
|
14
20
|
end
|
21
|
+
|
15
22
|
config.order = "random"
|
16
23
|
config.tty = true
|
17
24
|
end
|
data/spec/unit/a9n_spec.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
describe A9n do
|
1
|
+
RSpec.describe A9n do
|
4
2
|
subject { described_class }
|
5
3
|
before { clean_singleton(subject) }
|
6
4
|
after { clean_singleton(subject) }
|
@@ -177,7 +175,7 @@ describe A9n do
|
|
177
175
|
expect(described_class).to receive(:env).exactly(2).times.and_return("dev")
|
178
176
|
subject.root = "/apps/test_app"
|
179
177
|
files.each do |f, cfg|
|
180
|
-
expect(A9n::Loader).to receive(:new).with(f, "dev").and_return(double(get: cfg))
|
178
|
+
expect(A9n::Loader).to receive(:new).with(f, kind_of(A9n::Scope), "dev").and_return(double(get: cfg))
|
181
179
|
end
|
182
180
|
end
|
183
181
|
|
data/spec/unit/loader_spec.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
describe A9n::Loader do
|
1
|
+
RSpec.describe A9n::Loader do
|
2
|
+
let(:scope) { A9n::Scope.new("configuration") }
|
4
3
|
let(:env) { "test" }
|
5
4
|
let(:root) { File.expand_path("../../../test_app", __FILE__) }
|
6
5
|
let(:file_path) { File.join(root, "config/configuration.yml") }
|
7
|
-
subject { described_class.new(file_path, env) }
|
6
|
+
subject { described_class.new(file_path, scope, env) }
|
8
7
|
|
9
8
|
describe "#intialize" do
|
9
|
+
it { expect(subject.scope).to eq(scope) }
|
10
10
|
it { expect(subject.env).to eq(env) }
|
11
11
|
it { expect(subject.local_file).to eq(file_path) }
|
12
12
|
it { expect(subject.example_file).to eq("#{file_path}.example") }
|
@@ -26,9 +26,8 @@ describe A9n::Loader do
|
|
26
26
|
|
27
27
|
context "when no configuration file exists" do
|
28
28
|
before do
|
29
|
-
expect(described_class).to receive(:load_yml).with(subject.example_file, env).and_return(nil)
|
30
|
-
expect(described_class).to receive(:load_yml).with(subject.local_file, env).and_return(nil)
|
31
|
-
expect(subject).to receive(:verify!).never
|
29
|
+
expect(described_class).to receive(:load_yml).with(subject.example_file, scope, env).and_return(nil)
|
30
|
+
expect(described_class).to receive(:load_yml).with(subject.local_file, scope, env).and_return(nil)
|
32
31
|
end
|
33
32
|
|
34
33
|
it "raises expection" do
|
@@ -40,9 +39,8 @@ describe A9n::Loader do
|
|
40
39
|
|
41
40
|
context "when only example configuration file exists" do
|
42
41
|
before do
|
43
|
-
expect(described_class).to receive(:load_yml).with(subject.example_file, env).and_return(example_config)
|
44
|
-
expect(described_class).to receive(:load_yml).with(subject.local_file, env).and_return(nil)
|
45
|
-
expect(described_class).to receive(:verify!).never
|
42
|
+
expect(described_class).to receive(:load_yml).with(subject.example_file, scope, env).and_return(example_config)
|
43
|
+
expect(described_class).to receive(:load_yml).with(subject.local_file, scope, env).and_return(nil)
|
46
44
|
subject.load
|
47
45
|
end
|
48
46
|
|
@@ -56,9 +54,8 @@ describe A9n::Loader do
|
|
56
54
|
|
57
55
|
context "when only local configuration file exists" do
|
58
56
|
before do
|
59
|
-
expect(described_class).to receive(:load_yml).with(subject.example_file, env).and_return(nil)
|
60
|
-
expect(described_class).to receive(:load_yml).with(subject.local_file, env).and_return(local_config)
|
61
|
-
expect(described_class).to receive(:verify!).never
|
57
|
+
expect(described_class).to receive(:load_yml).with(subject.example_file, scope, env).and_return(nil)
|
58
|
+
expect(described_class).to receive(:load_yml).with(subject.local_file, scope, env).and_return(local_config)
|
62
59
|
subject.load
|
63
60
|
end
|
64
61
|
|
@@ -73,8 +70,8 @@ describe A9n::Loader do
|
|
73
70
|
context "when both local and base configuration file exists without defaults" do
|
74
71
|
context "with same data" do
|
75
72
|
before do
|
76
|
-
expect(described_class).to receive(:load_yml).with(subject.example_file, env).and_return(example_config)
|
77
|
-
expect(described_class).to receive(:load_yml).with(subject.local_file, env).and_return(example_config)
|
73
|
+
expect(described_class).to receive(:load_yml).with(subject.example_file, scope, env).and_return(example_config)
|
74
|
+
expect(described_class).to receive(:load_yml).with(subject.local_file, scope, env).and_return(example_config)
|
78
75
|
subject.load
|
79
76
|
end
|
80
77
|
|
@@ -88,8 +85,8 @@ describe A9n::Loader do
|
|
88
85
|
|
89
86
|
context "with different data" do
|
90
87
|
before do
|
91
|
-
expect(described_class).to receive(:load_yml).with(subject.example_file, env).and_return(example_config)
|
92
|
-
expect(described_class).to receive(:load_yml).with(subject.local_file, env).and_return(local_config)
|
88
|
+
expect(described_class).to receive(:load_yml).with(subject.example_file, scope, env).and_return(example_config)
|
89
|
+
expect(described_class).to receive(:load_yml).with(subject.local_file, scope, env).and_return(local_config)
|
93
90
|
end
|
94
91
|
|
95
92
|
let(:missing_variables_names) { example_config.keys - local_config.keys }
|
@@ -105,7 +102,7 @@ describe A9n::Loader do
|
|
105
102
|
|
106
103
|
describe ".load_yml" do
|
107
104
|
let(:env) { "test" }
|
108
|
-
subject { described_class.load_yml(file_path, env) }
|
105
|
+
subject { described_class.load_yml(file_path, scope, env) }
|
109
106
|
|
110
107
|
context "when file not exists" do
|
111
108
|
let(:file_path) { "file_not_existing_in_the_universe.yml" }
|
@@ -0,0 +1,27 @@
|
|
1
|
+
RSpec.describe A9n::Scope do
|
2
|
+
subject { described_class.new(name) }
|
3
|
+
|
4
|
+
describe "#name" do
|
5
|
+
let(:name) { "configuration" }
|
6
|
+
it { expect(subject.name).to eq(:configuration) }
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "#main?" do
|
10
|
+
context "when name is configuration" do
|
11
|
+
let(:name) { "configuration" }
|
12
|
+
it { expect(subject).to be_main }
|
13
|
+
end
|
14
|
+
|
15
|
+
context "when name is other than configuration" do
|
16
|
+
let(:name) { "mandrill" }
|
17
|
+
it { expect(subject).not_to be_main }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe ".form_file_path" do
|
22
|
+
let(:path) { "config/a9n/mandrill.yml.example" }
|
23
|
+
subject { described_class.form_file_path(path) }
|
24
|
+
|
25
|
+
it { expect(subject.name).to eq(:mandrill) }
|
26
|
+
end
|
27
|
+
end
|
data/spec/unit/struct_spec.rb
CHANGED
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.
|
4
|
+
version: 0.4.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Krzysztof Knapik
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-09-16 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: a9n - ruby/rails apps configuration manager
|
14
14
|
email:
|
@@ -18,6 +18,7 @@ extensions: []
|
|
18
18
|
extra_rdoc_files: []
|
19
19
|
files:
|
20
20
|
- ".gitignore"
|
21
|
+
- ".rspec"
|
21
22
|
- ".rspec.example"
|
22
23
|
- ".ruby-version"
|
23
24
|
- ".travis.yml"
|
@@ -32,12 +33,14 @@ files:
|
|
32
33
|
- lib/a9n/capistrano/ver2x.rb
|
33
34
|
- lib/a9n/ext/hash.rb
|
34
35
|
- lib/a9n/loader.rb
|
36
|
+
- lib/a9n/scope.rb
|
35
37
|
- lib/a9n/struct.rb
|
36
38
|
- lib/a9n/version.rb
|
37
39
|
- spec/integration/a9n_spec.rb
|
38
40
|
- spec/spec_helper.rb
|
39
41
|
- spec/unit/a9n_spec.rb
|
40
42
|
- spec/unit/loader_spec.rb
|
43
|
+
- spec/unit/scope_spec.rb
|
41
44
|
- spec/unit/struct_spec.rb
|
42
45
|
- test_app/benchmark.rb
|
43
46
|
- test_app/config/a9n/cloud.yml.erb
|
@@ -76,4 +79,5 @@ test_files:
|
|
76
79
|
- spec/spec_helper.rb
|
77
80
|
- spec/unit/a9n_spec.rb
|
78
81
|
- spec/unit/loader_spec.rb
|
82
|
+
- spec/unit/scope_spec.rb
|
79
83
|
- spec/unit/struct_spec.rb
|