foundry 0.2.2 → 0.3.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: c0e5844ff236192bbd134f6044eeecd46b97a96f
4
- data.tar.gz: f54d2a1d4f15b500e121f663b5cdf84fa3eb0d80
3
+ metadata.gz: b28681a81e233360028348be15505ab62d698a9c
4
+ data.tar.gz: 060e3a8c45400254f9fb8e926b75683f82a4fed9
5
5
  SHA512:
6
- metadata.gz: 337e51d286fb9e574bb4f446a0dfdd9d3b689051b4315a0a6d4d269fbccb8075497bda0d751e37bce8f1010cb9c0bd1df3f659484394f1c83ab11dec046598b9
7
- data.tar.gz: d808c17433690c4b4375b4a7c2559171844f350005c42e49d3cc150a0eae3c56b95e65c743abfdff735fb132613b5159400ccaf3bc83b58146b5374c99abbade
6
+ metadata.gz: 52e33f3b602ff5a8dd9fdc6728a8898e42d3572bc4c147f4755cab966d4ceece89ce46639619302677882028620084aaf60c93cebf92e8490515fdfb8fb13a7d
7
+ data.tar.gz: 3bf3b2b64289087f2abd06816434e51590fd59add1fb82b0aee96522d1a5571d58a0496fc993d420e97b78191219324bd183a78b55e62a0de7bf4a50f508e8fe
@@ -6,10 +6,13 @@ matrix:
6
6
  - rvm: rbx-2
7
7
 
8
8
  rvm:
9
+ - 1.8.7
10
+ - 1.9.2
9
11
  - 1.9.3
10
12
  - 2.0.0
11
13
  - 2.1.0
12
14
  - 2.1.1
13
15
  - 2.1.2
16
+ - 2.1.3
14
17
  - jruby-19mode
15
18
  - rbx-2
data/README.md CHANGED
@@ -36,40 +36,94 @@ Or install it yourself as:
36
36
  Loading from a local-file:
37
37
 
38
38
  ```ruby
39
- config = Foundry::Configurator.configure(:file_name => 'path-to-local-file')
39
+ config = Foundry::Configurator.configure(
40
+ :root_path => 'local-root-path',
41
+ :relative_path => 'relative-path-to-file',
42
+ :source_type => Foundry::Sources::File
43
+ )
40
44
  ```
41
45
 
42
46
  Loading from a HTTP/HTTPS endpoint:
43
47
 
44
48
  ```ruby
45
- config = Foundry::Configurator.configure(:uri => 'http-or-https-endpoint')
49
+ config = Foundry::Configurator.configure(
50
+ :root_path => 'http-or-https-root-url',
51
+ :relative_path => 'relative-path-to-file',
52
+ :source_type => Foundry::Sources::URI
53
+ )
46
54
  ```
47
55
 
48
56
  Loading from a HTTP/HTTPS endpoint using "Basic Authentication":
49
57
 
50
58
  ```ruby
51
59
  config = Foundry::Configurator.configure(
52
- :uri => 'http-or-https-endpoint',
60
+ :root_path => 'http-or-https-root-url',
61
+ :relative_path => 'relative-path-to-file',
62
+ :source_type => Foundry::Sources::URI,
53
63
  :username => 'basic-auth-username',
54
64
  :password => 'basic-auth-password'
55
65
  )
56
66
  ```
57
67
 
58
- Using the "config" object (defined above):
68
+ Fetching top-level and nested values:
59
69
 
60
70
  ```ruby
61
- # The examples below assume that the following YAML was loaded by a call to
62
- # "Foundry::Configurator.configure" and into a variable named "config"
71
+ # The examples below assume that a file containing the following has already
72
+ # been loaded and processed by a call to `Foundry::Configurator.configure` (into
73
+ # a variable named `config`).
63
74
  #
64
75
  # ---
65
- # some_key:
66
- # some_nested_key: value
76
+ # value1: value
77
+ # value2:
78
+ # nested_value1: value
79
+
80
+ # Fetching a top-level value using dot-notation
81
+ value1 = config.value1
82
+
83
+ # Fetching a nested value using dot-notation
84
+ nested_value1 = config.value2.nested_value1
85
+
86
+ # Fetching a top-level value by key
87
+ value1 = config['value1']
88
+
89
+ # Fetching a nested value by key
90
+ nested_value1 = config['value2']['nested_value1']
91
+ ```
92
+
93
+ Inheritance support:
94
+
95
+ ```ruby
96
+ # The examples below assume that there are two files available, relative to the
97
+ # `root_path`, named "file1.yml" and "file2.yml" (and that "file2.yml" inherits
98
+ # from "file1.yml").
99
+ #
100
+ # The file contents are as follows:
101
+ #
102
+ # === file1.yml ===
103
+ #
104
+ # ---
105
+ # value1: value
106
+ #
107
+ # === file2.yml ===
108
+ #
109
+ # ---
110
+ # value2: value
111
+ # inherit: file1.yml
112
+ #
113
+ # It is also assumed that the files have already been loaded and processed by a
114
+ # call to `Foundry::Configurator.configure` (into a variable named `config`).
115
+ #
116
+ # The result now contains values for both `value1` and `value2` and can be used
117
+ # as follows (it is worth noting that the `inherit` key is removed during the
118
+ # configuration process):
67
119
 
68
- # Fetch a value using dot-notation
69
- value = config.some_key.some_nested_key
120
+ # Fetching `value1` and `value2` using dot-notation
121
+ value1 = config.value1
122
+ value2 = config.value2
70
123
 
71
- # Fetch a value by key
72
- value = config['some_key']['some_nested_key']
124
+ # Fetching `value1` and `value2` by key
125
+ value1 = config['value1']
126
+ value2 = config['value2']
73
127
  ```
74
128
 
75
129
  ## Contributing
@@ -26,4 +26,5 @@ Gem::Specification.new do |gem|
26
26
  gem.add_development_dependency 'pry', '~> 0.10'
27
27
  gem.add_development_dependency 'rake', '~> 10.3'
28
28
  gem.add_development_dependency 'rspec', '~> 3.0'
29
+ gem.add_development_dependency 'webmock', '~> 1.20'
29
30
  end
@@ -5,7 +5,9 @@ require 'ostruct'
5
5
  require 'uri'
6
6
  require 'yaml'
7
7
 
8
+ require 'foundry/refinements/hash'
9
+
8
10
  require 'foundry/configurator'
9
- require 'foundry/loaders/file'
10
- require 'foundry/loaders/uri'
11
+ require 'foundry/sources/file'
12
+ require 'foundry/sources/uri'
11
13
  require 'foundry/version'
@@ -1,52 +1,81 @@
1
1
  module Foundry
2
2
  class Configurator
3
- class << self
4
- def configure(opts={})
5
- structify(
6
- load_yaml(
7
- evaluate_erb(
8
- load_by_filename_or_uri(opts)
9
- )
10
- )
11
- )
3
+ def self.configure(opts)
4
+ Configurator.new.configure(opts)
5
+ end
6
+
7
+ def configure(opts)
8
+ with_opts(opts) do
9
+ transmorgs = transmorgify(opts.fetch(:relative_path))
10
+ merged = mergify(transmorgs)
11
+ structify(merged)
12
12
  end
13
+ end
13
14
 
14
- private
15
+ private
15
16
 
16
- def evaluate_erb(str)
17
- ERB.new(str).result
18
- end
17
+ attr_reader :opts
19
18
 
20
- def load_by_filename_or_uri(opts)
21
- if file_name = opts.delete(:file_name)
22
- Foundry::Loaders::File.load(file_name, opts)
23
- elsif uri = opts.delete(:uri)
24
- Foundry::Loaders::Uri.load(uri, opts)
25
- else
26
- raise NotImplementedError
27
- end
28
- end
19
+ def erbify(str)
20
+ ERB.new(str).result
21
+ end
29
22
 
30
- def load_yaml(str)
31
- YAML.load(str)
32
- end
23
+ def loadify(relative_path)
24
+ source.load(
25
+ root_path,
26
+ relative_path,
27
+ opts
28
+ )
29
+ end
33
30
 
34
- def structify(object)
35
- case object
36
- when Array
37
- object.map do |value|
38
- structify(value)
39
- end
40
- when Hash
41
- OpenStruct.new.tap do |open_struct|
42
- object.each do |key, value|
43
- open_struct.public_send("#{key}=", structify(value))
44
- end
31
+ def mergify(transmorgs)
32
+ transmorgs.reduce({}) { |memo, transmorg| memo.deep_merge(transmorg) }
33
+ end
34
+
35
+ def parsify(str)
36
+ YAML.load(str) || {}
37
+ end
38
+
39
+ def root_path
40
+ opts.fetch(:root_path)
41
+ end
42
+
43
+ def source
44
+ source_type.new
45
+ end
46
+
47
+ def source_type
48
+ opts.fetch(:source_type)
49
+ end
50
+
51
+ def structify(object)
52
+ case object
53
+ when Array
54
+ object.map do |value|
55
+ structify(value)
56
+ end
57
+ when Hash
58
+ OpenStruct.new.tap do |open_struct|
59
+ object.each do |key, value|
60
+ open_struct.send("#{key}=", structify(value))
45
61
  end
46
- else
47
- object
48
62
  end
63
+ else
64
+ object
49
65
  end
50
66
  end
67
+
68
+ def transmorgify(relative_path)
69
+ parsed = parsify(erbify(loadify(relative_path)))
70
+ inherit = parsed.delete('inherit')
71
+ Array(inherit && transmorgify(inherit)) << parsed
72
+ end
73
+
74
+ def with_opts(opts)
75
+ @opts = opts
76
+ yield
77
+ ensure
78
+ @opts = nil
79
+ end
51
80
  end
52
81
  end
@@ -0,0 +1,25 @@
1
+ class Hash
2
+ def deep_merge(other)
3
+ dup.deep_merge!(other)
4
+ end
5
+
6
+ def deep_merge!(other)
7
+ other.each_pair do |other_key, other_value|
8
+ this_value = self[other_key]
9
+ if this_value.is_a?(Hash) && other_value.is_a?(Hash)
10
+ self[other_key] = this_value.deep_merge(other_value)
11
+ else
12
+ self[other_key] = other_value
13
+ end
14
+ end
15
+ self
16
+ end
17
+
18
+ def without(*keys)
19
+ dup.without!(*keys)
20
+ end
21
+
22
+ def without!(*keys)
23
+ self.reject! { |key, _| keys.include?(key) }; self
24
+ end
25
+ end
@@ -0,0 +1,11 @@
1
+ module Foundry
2
+ module Sources
3
+ class File
4
+ def load(root_path, relative_path, opts)
5
+ file_path = ::File.join(root_path, relative_path)
6
+ raise "Unknown configuration file: #{file_path}" unless ::File.exists?(file_path)
7
+ ::File.read(file_path)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,21 @@
1
+ module Foundry
2
+ module Sources
3
+ class URI
4
+ def load(root_path, relative_path, opts)
5
+ uri = ::URI.join(root_path, relative_path)
6
+ client = Net::HTTP.new(uri.host, uri.port)
7
+ if uri.scheme == 'https'
8
+ client.use_ssl = true
9
+ client.verify_mode = OpenSSL::SSL::VERIFY_NONE
10
+ end
11
+ request = Net::HTTP::Get.new(uri.request_uri)
12
+ if (username = opts[:username]) && (password = opts[:password])
13
+ request.basic_auth(username, password)
14
+ end
15
+ response = client.request(request)
16
+ raise "Unknown configuration file: #{uri}" unless response.is_a?(Net::HTTPSuccess)
17
+ response.body
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,3 +1,3 @@
1
1
  module Foundry
2
- VERSION = '0.2.2'
2
+ VERSION = '0.3.0'
3
3
  end
@@ -1,36 +1,45 @@
1
1
  require 'spec_helper'
2
- require 'foundry/configurator'
3
2
 
4
3
  describe Foundry::Configurator do
5
- subject { Foundry::Configurator }
4
+ REQUIRED_OPTS = [
5
+ :root_path,
6
+ :relative_path,
7
+ :source_type,
8
+ ]
6
9
 
7
- it 'must be passed either a "file_name" or "uri"' do
8
- expect { subject.configure }.to raise_error
9
- end
10
+ subject { Foundry::Configurator.new }
11
+ let(:opts) { REQUIRED_OPTS.reduce({}) { |memo, opt| memo[opt] = nil; memo } }
10
12
 
11
- it 'will attempt to load from a file' do
12
- expect(Foundry::Loaders::File).to receive(:load) { '' }
13
- subject.configure(:file_name => '')
13
+ REQUIRED_OPTS.each do |key|
14
+ it %{must be passed a "#{key}"} do
15
+ expect { subject.configure(opts.without(key)) }.to raise_error
16
+ end
14
17
  end
15
18
 
16
- it 'will attempt to load from a uri' do
17
- expect(Foundry::Loaders::Uri).to receive(:load) { '' }
18
- subject.configure(:uri => '')
19
+ it 'will load from a source' do
20
+ with_source do |source|
21
+ expect(source).to receive(:load) { '' }
22
+ expect { subject.configure(opts) }.not_to raise_error
23
+ end
19
24
  end
20
25
 
21
26
  it 'will fail-fast if the YAML is invalid' do
22
- expect(Foundry::Loaders::File).to receive(:load)
23
- expect { subject.configure(:file_name => '') }.to raise_error
27
+ with_source do |source|
28
+ expect(source).to receive(:load)
29
+ expect { subject.configure(opts) }.to raise_error
30
+ end
24
31
  end
25
32
 
26
33
  it 'will fail-fast if the ERB raises an error' do
27
- expect(Foundry::Loaders::File).to receive(:load) { 'foo: <%= 1/0 %>' }
28
- expect { subject.configure(:file_name => '') }.to raise_error
34
+ with_source do |source|
35
+ expect(source).to receive(:load) { 'foo: <%= 1/0 %>' }
36
+ expect { subject.configure(opts) }.to raise_error
37
+ end
29
38
  end
30
39
 
31
- it 'can parse [nested] YAML/ERB' do
32
- expect(Foundry::Loaders::File).to receive(:load) { <<-YAML
33
- root:
40
+ it 'can parse YAML/ERB' do
41
+ with_source do |source|
42
+ expect(source).to receive(:load) { <<-YAML
34
43
  erb: <%= 1 * 2 * 3 %>
35
44
  float: 123.0
36
45
  integer: 42
@@ -39,11 +48,10 @@ describe Foundry::Configurator do
39
48
  - dos
40
49
  - tres
41
50
  string: hello world
42
- YAML
43
- }
44
- expect(subject.configure(:file_name => '')).to eq(
45
- OpenStruct.new(
46
- 'root' => OpenStruct.new(
51
+ YAML
52
+ }
53
+ expect(subject.configure(opts)).to eq(
54
+ OpenStruct.new(
47
55
  'erb' => 6,
48
56
  'float' => 123.0,
49
57
  'integer' => 42,
@@ -51,6 +59,37 @@ describe Foundry::Configurator do
51
59
  'string' => 'hello world'
52
60
  )
53
61
  )
54
- )
62
+ end
63
+ end
64
+
65
+ it 'supports inheritance' do
66
+ with_source(:exactly => :twice) do |source|
67
+ expect(source).to receive(:load).and_return(
68
+ "foo: foo\ninherit: bar",
69
+ "bar: bar"
70
+ )
71
+ expect(subject.configure(opts)).to eq(
72
+ OpenStruct.new(
73
+ 'foo' => 'foo',
74
+ 'bar' => 'bar'
75
+ )
76
+ )
77
+ end
78
+ end
79
+
80
+ private
81
+
82
+ def default_opts
83
+ {
84
+ :exactly => :once,
85
+ :type => Foundry::Sources::File,
86
+ }
87
+ end
88
+
89
+ def with_source(opts={})
90
+ merged_opts = default_opts.merge(opts)
91
+ source = merged_opts[:type].new
92
+ expect(subject).to receive(:source).exactly(merged_opts[:exactly]) { source }
93
+ yield source
55
94
  end
56
95
  end
@@ -0,0 +1,170 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hash do
4
+ subject do
5
+ {
6
+ :A => nil,
7
+ :B => nil,
8
+ :C => nil,
9
+ :D => nil,
10
+ }
11
+ end
12
+ let(:keys) do
13
+ [
14
+ :A,
15
+ :B,
16
+ :C,
17
+ :D,
18
+ ]
19
+ end
20
+
21
+ let(:other) do
22
+ {
23
+ :E => nil,
24
+ :F => nil,
25
+ :G => nil,
26
+ :H => nil,
27
+ }
28
+ end
29
+ let(:other_keys) do
30
+ [
31
+ :E,
32
+ :F,
33
+ :G,
34
+ :H,
35
+ ]
36
+ end
37
+
38
+ let(:nested) do
39
+ {
40
+ :I => nil,
41
+ :J => nil,
42
+ :K => {
43
+ :L => nil,
44
+ },
45
+ }
46
+ end
47
+
48
+ describe 'destructive' do
49
+ describe 'deep_merge!' do
50
+ it 'can merge two hashes' do
51
+ expect(subject.deep_merge!(other)).to eq({
52
+ :A => nil,
53
+ :B => nil,
54
+ :C => nil,
55
+ :D => nil,
56
+ :E => nil,
57
+ :F => nil,
58
+ :G => nil,
59
+ :H => nil,
60
+ })
61
+ expect(subject.size).to eq(keys.size + other_keys.size)
62
+ end
63
+
64
+ it 'can merge nested hashes' do
65
+ expect(subject.deep_merge!(nested)).to eq({
66
+ :A => nil,
67
+ :B => nil,
68
+ :C => nil,
69
+ :D => nil,
70
+ :I => nil,
71
+ :J => nil,
72
+ :K => {
73
+ :L => nil,
74
+ },
75
+ })
76
+ end
77
+ end
78
+
79
+ describe 'without!' do
80
+ it 'can filter one key' do
81
+ expect(subject.without!(:A)).to eq({
82
+ :B => nil,
83
+ :C => nil,
84
+ :D => nil,
85
+ })
86
+ expect(subject.size).to eq(keys.size - 1)
87
+ end
88
+
89
+ it 'can filter multiple keys' do
90
+ expect(subject.without!(:A, :B)).to eq({
91
+ :C => nil,
92
+ :D => nil,
93
+ })
94
+ expect(subject.size).to eq(keys.size - 2)
95
+ end
96
+
97
+ it 'skips keys that do not exist' do
98
+ expect(subject.without!(:E)).to eq({
99
+ :A => nil,
100
+ :B => nil,
101
+ :C => nil,
102
+ :D => nil,
103
+ })
104
+ expect(subject.size).to eq(keys.size)
105
+ end
106
+ end
107
+ end
108
+
109
+ describe 'non-destructive' do
110
+ describe 'deep_merge' do
111
+ it 'can merge two hashes' do
112
+ expect(subject.deep_merge(other)).to eq({
113
+ :A => nil,
114
+ :B => nil,
115
+ :C => nil,
116
+ :D => nil,
117
+ :E => nil,
118
+ :F => nil,
119
+ :G => nil,
120
+ :H => nil,
121
+ })
122
+ expect(subject.size).to eq(keys.size)
123
+ end
124
+
125
+ it 'can merge nested hashes' do
126
+ expect(subject.deep_merge(nested)).to eq({
127
+ :A => nil,
128
+ :B => nil,
129
+ :C => nil,
130
+ :D => nil,
131
+ :I => nil,
132
+ :J => nil,
133
+ :K => {
134
+ :L => nil,
135
+ },
136
+ })
137
+ expect(subject.size).to eq(keys.size)
138
+ end
139
+ end
140
+
141
+ describe 'without' do
142
+ it 'can filter one key' do
143
+ expect(subject.without(:A)).to eq({
144
+ :B => nil,
145
+ :C => nil,
146
+ :D => nil,
147
+ })
148
+ expect(subject.size).to eq(keys.size)
149
+ end
150
+
151
+ it 'can filter multiple keys' do
152
+ expect(subject.without(:A, :B)).to eq({
153
+ :C => nil,
154
+ :D => nil,
155
+ })
156
+ expect(subject.size).to eq(keys.size)
157
+ end
158
+
159
+ it 'skips keys that do not exist' do
160
+ expect(subject.without(:E)).to eq({
161
+ :A => nil,
162
+ :B => nil,
163
+ :C => nil,
164
+ :D => nil,
165
+ })
166
+ expect(subject.size).to eq(keys.size)
167
+ end
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe Foundry::Sources::File do
4
+ subject { Foundry::Sources::File.new }
5
+
6
+ it 'can load a file' do
7
+ expect(File).to receive(:read)
8
+ subject.load('', '', {})
9
+ end
10
+
11
+ it 'will raise an error if the file does not exist' do
12
+ expect { subject.load('', '', {}) }.to raise_error
13
+ end
14
+ end
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+
3
+ describe Foundry::Sources::URI do
4
+ subject { Foundry::Sources::URI.new }
5
+ let(:domain) { 'foo.bar.com' }
6
+ let(:relative_path) { 'config.yml' }
7
+
8
+ let(:http_uri) { "#{http_root_path}/#{relative_path}" }
9
+ let(:http_root_path) { "http://#{domain}" }
10
+ let(:http_response_body) { 'http_response_body' }
11
+ let(:http_opts) { {} }
12
+
13
+ let(:https_uri) { "#{https_root_path}/#{relative_path}" }
14
+ let(:https_root_path) { "https://#{domain}" }
15
+ let(:https_response_body) { 'https_response_body' }
16
+ let(:https_opts) { {} }
17
+
18
+ let(:basic_auth_uri) { "http://#{basic_auth_username}:#{basic_auth_password}@#{domain}/#{relative_path}" }
19
+ let(:basic_auth_root_path) { http_root_path }
20
+ let(:basic_auth_response_body) { 'basic_auth_response_body' }
21
+ let(:basic_auth_username) { 'basic_auth_username' }
22
+ let(:basic_auth_password) { 'basic_auth_password' }
23
+ let(:basic_auth_opts) { { :username => basic_auth_username, :password => basic_auth_password } }
24
+
25
+ before do
26
+ end
27
+
28
+ it 'can load from a HTTP endpoint' do
29
+ stub_request(:get, http_uri).to_return(:body => http_response_body)
30
+
31
+ expect(
32
+ subject.load(
33
+ http_root_path,
34
+ relative_path,
35
+ http_opts
36
+ )
37
+ ).to eq(http_response_body)
38
+ end
39
+
40
+ it 'can load from a HTTPS endpoint' do
41
+ stub_request(:get, https_uri).to_return(:body => https_response_body)
42
+
43
+ expect(
44
+ subject.load(
45
+ https_root_path,
46
+ relative_path,
47
+ https_opts
48
+ )
49
+ ).to eq(https_response_body)
50
+ end
51
+
52
+ it 'can load from a endpoint using basic-auth' do
53
+ stub_request(:get, basic_auth_uri).to_return(:body => basic_auth_response_body)
54
+
55
+ expect(
56
+ subject.load(
57
+ basic_auth_root_path,
58
+ relative_path,
59
+ basic_auth_opts
60
+ )
61
+ ).to eq(basic_auth_response_body)
62
+ end
63
+ end
@@ -1,6 +1,3 @@
1
1
  require 'rspec'
2
+ require 'webmock/rspec'
2
3
  require File.expand_path('../../lib/foundry.rb', __FILE__)
3
-
4
- RSpec.configure do |config|
5
- config.color_enabled = true if config.respond_to?(:color_enabled)
6
- end
metadata CHANGED
@@ -1,71 +1,85 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foundry
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan W. Zaleski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-25 00:00:00.000000000 Z
11
+ date: 2014-10-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ~>
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.6'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ~>
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.6'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: pry
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ~>
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0.10'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ~>
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0.10'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ~>
46
46
  - !ruby/object:Gem::Version
47
47
  version: '10.3'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ~>
53
53
  - !ruby/object:Gem::Version
54
54
  version: '10.3'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ~>
60
60
  - !ruby/object:Gem::Version
61
61
  version: '3.0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ~>
67
67
  - !ruby/object:Gem::Version
68
68
  version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: webmock
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '1.20'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '1.20'
69
83
  description: |2
70
84
  Let's face it, there are a number of problems when application/environment
71
85
  configuration logic is too tightly coupled with the configuration-data itself.
@@ -76,8 +90,8 @@ executables: []
76
90
  extensions: []
77
91
  extra_rdoc_files: []
78
92
  files:
79
- - ".gitignore"
80
- - ".travis.yml"
93
+ - .gitignore
94
+ - .travis.yml
81
95
  - Gemfile
82
96
  - LICENSE.txt
83
97
  - README.md
@@ -86,12 +100,14 @@ files:
86
100
  - foundry.gemspec
87
101
  - lib/foundry.rb
88
102
  - lib/foundry/configurator.rb
89
- - lib/foundry/loaders/file.rb
90
- - lib/foundry/loaders/uri.rb
103
+ - lib/foundry/refinements/hash.rb
104
+ - lib/foundry/sources/file.rb
105
+ - lib/foundry/sources/uri.rb
91
106
  - lib/foundry/version.rb
92
107
  - spec/configurator_spec.rb
93
- - spec/loaders/file_spec.rb
94
- - spec/loaders/uri_spec.rb
108
+ - spec/refinements/hash_spec.rb
109
+ - spec/sources/file_spec.rb
110
+ - spec/sources/uri_spec.rb
95
111
  - spec/spec_helper.rb
96
112
  homepage: https://github.com/jzaleski/foundry
97
113
  licenses:
@@ -103,22 +119,23 @@ require_paths:
103
119
  - lib
104
120
  required_ruby_version: !ruby/object:Gem::Requirement
105
121
  requirements:
106
- - - ">="
122
+ - - '>='
107
123
  - !ruby/object:Gem::Version
108
124
  version: '0'
109
125
  required_rubygems_version: !ruby/object:Gem::Requirement
110
126
  requirements:
111
- - - ">="
127
+ - - '>='
112
128
  - !ruby/object:Gem::Version
113
129
  version: '0'
114
130
  requirements: []
115
131
  rubyforge_project:
116
- rubygems_version: 2.3.0
132
+ rubygems_version: 2.2.2
117
133
  signing_key:
118
134
  specification_version: 4
119
135
  summary: An application configuration gem that aims to keep it simple
120
136
  test_files:
121
137
  - spec/configurator_spec.rb
122
- - spec/loaders/file_spec.rb
123
- - spec/loaders/uri_spec.rb
138
+ - spec/refinements/hash_spec.rb
139
+ - spec/sources/file_spec.rb
140
+ - spec/sources/uri_spec.rb
124
141
  - spec/spec_helper.rb
@@ -1,9 +0,0 @@
1
- module Foundry
2
- module Loaders
3
- class File
4
- def self.load(file_name, opts)
5
- ::File.read(file_name)
6
- end
7
- end
8
- end
9
- end
@@ -1,19 +0,0 @@
1
- module Foundry
2
- module Loaders
3
- class Uri
4
- def self.load(uri, opts)
5
- parsed_uri = URI.parse(uri)
6
- http = Net::HTTP.new(parsed_uri.host, parsed_uri.port)
7
- if parsed_uri.scheme == 'https'
8
- http.use_ssl = true
9
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
10
- end
11
- request = Net::HTTP::Get.new(parsed_uri.request_uri)
12
- if username = opts.delete(:username) && password = opts.delete(:password)
13
- request.basic_auth(username, password)
14
- end
15
- http.request(request).body
16
- end
17
- end
18
- end
19
- end
@@ -1,15 +0,0 @@
1
- require 'spec_helper'
2
- require 'foundry/loaders/file'
3
-
4
- describe Foundry::Loaders::File do
5
- subject { Foundry::Loaders::File }
6
-
7
- it 'can load a file' do
8
- expect(File).to receive(:read)
9
- subject.load('', {})
10
- end
11
-
12
- it 'will raise an error if the file does not exist' do
13
- expect { subject.load('', {}) }.to raise_error
14
- end
15
- end
@@ -1,36 +0,0 @@
1
- require 'spec_helper'
2
- require 'foundry/loaders/uri'
3
-
4
- describe Foundry::Loaders::Uri do
5
- subject { Foundry::Loaders::Uri }
6
- let(:request) { double }
7
- let(:response_body) { 'response_body' }
8
- let(:response) { double(:body => response_body) }
9
- let(:http) { double(:request => response) }
10
- let(:http_url) { 'http://foo.bar.com' }
11
- let(:https_url) { http_url.gsub(/\Ahttp:/, 'https:') }
12
-
13
- before do
14
- expect(Net::HTTP).to receive(:new) { http }
15
- expect(Net::HTTP::Get).to receive(:new) { request }
16
- end
17
-
18
- it 'can load from a HTTP endpoint' do
19
- expect(subject.load(http_url, {})).to eq(response_body)
20
- end
21
-
22
- it 'can load from a HTTPS endpoint' do
23
- expect(http).to receive_messages([:use_ssl=, :verify_mode=])
24
- expect(subject.load(https_url, {})).to eq(response_body)
25
- end
26
-
27
- it 'can load from a endpoint using basic-auth' do
28
- expect(request).to receive(:basic_auth)
29
- expect(subject.load(
30
- http_url, {
31
- :username => 'basic_auth_username',
32
- :password => 'basic_auth_password',
33
- }
34
- )).to eq(response_body)
35
- end
36
- end