a9n 0.4.5 → 0.4.6
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/.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
|