foundry 0.2.2 → 0.3.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: 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