env_setting 1.0.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 +7 -0
- checksums.yaml.gz.sig +2 -0
- data.tar.gz.sig +1 -0
- data/.gitignore +19 -0
- data/.travis.yml +6 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +23 -0
- data/README.md +333 -0
- data/Rakefile +13 -0
- data/certs/wspurgin.pem +22 -0
- data/env_setting.gemspec +28 -0
- data/lib/env_setting.rb +113 -0
- data/lib/env_setting/classes.rb +60 -0
- data/lib/env_setting/formatter.rb +20 -0
- data/lib/env_setting/version.rb +3 -0
- data/spec/env_setting_spec.rb +300 -0
- data/spec/spec_helper.rb +17 -0
- metadata +138 -0
- metadata.gz.sig +3 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 96310d9ae84d2c930ac48bf3a6fd90b6a954d413
|
4
|
+
data.tar.gz: 6935b91753a1c70aef433eb9d7823439009c14a2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6b4a876883750972e645f49d54c1f02427e6114e4e9ae3312e579a74877c053495b5ff6573badc4b132e1c17e7427de1c3fc5c944f044c51f9a9db52f20c203d
|
7
|
+
data.tar.gz: bfce18429b78b30f255baa2791228591e6b220cb49f8f5b27559e67b4c4c29092a08690cc1642b7dc5a04b0452714585fdca0ac7a399e56027aa82424ac84778
|
checksums.yaml.gz.sig
ADDED
data.tar.gz.sig
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
y��^$?�#�~ml��v��Ni�U�YN�YbD>Q{�����火'��}J�v���#{��a9�E�c��,�����tQ!���f���+x7�JN�%���o^l��8������V�G#,����"sb��\����贸��,�?)�&4�y�]ɓ^��O�aTuv,^�z֎s�M?������N��+H��t�.r]-�{up�������5��ՋZ����1��Oų�:7���[+g��z��z�%
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
Copyright (c) 2016 ORM Technologies
|
2
|
+
Copyright (c) 2013 Jonathan Camenisch
|
3
|
+
|
4
|
+
MIT License
|
5
|
+
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
7
|
+
a copy of this software and associated documentation files (the
|
8
|
+
"Software"), to deal in the Software without restriction, including
|
9
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
10
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
11
|
+
permit persons to whom the Software is furnished to do so, subject to
|
12
|
+
the following conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be
|
15
|
+
included in all copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
18
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
19
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
20
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
21
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
22
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
23
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,333 @@
|
|
1
|
+
# env_setting
|
2
|
+
|
3
|
+
Inspired by [ENV!](https://rubygems.org/gems/env_bang) and [David Copeland's
|
4
|
+
article on UNIX
|
5
|
+
Environment](http://naildrivin5.com/blog/2016/06/10/dont-use-ENV-directly.html),
|
6
|
+
`env_setting` is a slight rewrite of `env_bang` to provide OOP style access to
|
7
|
+
your ENV.
|
8
|
+
|
9
|
+
[](https://travis-ci.org/ormtech/env_setting)
|
10
|
+
[](https://coveralls.io/github/ormtech/env_setting?branch=master)
|
11
|
+
|
12
|
+
`env_setting` is very similar to `ENV!`, it sets out to accomplish the same
|
13
|
+
purpose:
|
14
|
+
|
15
|
+
> - Provide a central place to specify all your app’s environment variables.
|
16
|
+
> - Fail loudly and helpfully if any environment variables are missing.
|
17
|
+
> - Prevent an application from starting up with missing environment variables.
|
18
|
+
> (This is especially helpful in environments like Heroku, as your app will
|
19
|
+
> continue running the old code until the server is configured for a new
|
20
|
+
> revision.)
|
21
|
+
|
22
|
+
But with one extra requirement:
|
23
|
+
|
24
|
+
- Provide access to environment variables in keeping with OOP doctrine.
|
25
|
+
|
26
|
+
To accomplish that goal, Environment variables are just methods on the
|
27
|
+
`EnvSetting` class after they are configured:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
ENV["SOME_SETTING"] = "something"
|
31
|
+
|
32
|
+
EnvSetting.use "SOME_SETTING"
|
33
|
+
|
34
|
+
...
|
35
|
+
|
36
|
+
EnvSetting.some_setting
|
37
|
+
# => "something"
|
38
|
+
EnvSetting.some_setting?
|
39
|
+
# => true
|
40
|
+
```
|
41
|
+
|
42
|
+
## Installation
|
43
|
+
|
44
|
+
Add this line to your application’s Gemfile:
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
gem 'env_setting'
|
48
|
+
```
|
49
|
+
|
50
|
+
Or for Rails apps, use `env_setting-rails` instead for more convenience:
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
gem 'env_setting-rails'
|
54
|
+
```
|
55
|
+
|
56
|
+
And then execute:
|
57
|
+
|
58
|
+
```sh
|
59
|
+
$ bundle
|
60
|
+
```
|
61
|
+
|
62
|
+
## Usage
|
63
|
+
|
64
|
+
### Basic Configuration
|
65
|
+
|
66
|
+
Configuration style is _exactly_ the same for `env_bang` and `env_setting`, only
|
67
|
+
that there's no "ENV!" method... just the normal class: `EnvSetting` that is
|
68
|
+
called and configured.
|
69
|
+
|
70
|
+
First, configure your environment variables somewhere in your app’s startup
|
71
|
+
process. If you use the `env_setting-rails` gem, place this in `config/env.rb`
|
72
|
+
to load before application configuration.
|
73
|
+
|
74
|
+
Example configuration:
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
EnvSetting.config do
|
78
|
+
use :APP_HOST
|
79
|
+
use :RAILS_SECRET_TOKEN
|
80
|
+
use :STRIPE_SECRET_KEY
|
81
|
+
use :STRIPE_PUBLISHABLE_KEY
|
82
|
+
# ... etc.
|
83
|
+
end
|
84
|
+
```
|
85
|
+
|
86
|
+
Once a variable is specified with the `use` method, access it with
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
EnvSetting.my_var
|
90
|
+
```
|
91
|
+
|
92
|
+
Or you can still use the Hash syntax if you prefer it:
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
EnvSetting["MY_VAR"]
|
96
|
+
```
|
97
|
+
|
98
|
+
This will function just like accessing `ENV` directly, except that it will
|
99
|
+
require the variable to have been specified, and, if no default value is
|
100
|
+
specified, it will raise a `KeyError` with an explanation of what needs to be
|
101
|
+
configured. In the event you reference a variable that you haven't specified,
|
102
|
+
it will produce a `NoMethodError` (if using the method syntax) or a `KeyError`
|
103
|
+
if using the Hash syntax.
|
104
|
+
|
105
|
+
### Adding a default value
|
106
|
+
|
107
|
+
For some variables, you’ll want to include a default value in your code, and
|
108
|
+
allow each environment to omit the variable for default behaviors. You can
|
109
|
+
accomplish this with the `:default` option:
|
110
|
+
|
111
|
+
```ruby
|
112
|
+
EnvSetting.config do
|
113
|
+
# ...
|
114
|
+
use :MAIL_DELIVERY_METHOD, default: 'smtp'
|
115
|
+
# ...
|
116
|
+
end
|
117
|
+
```
|
118
|
+
|
119
|
+
### Adding a description
|
120
|
+
|
121
|
+
When a new team member installs or deploys your project, they may run into a
|
122
|
+
missing environment variable error. Save them time by including documentation
|
123
|
+
along with the error that is raised. To accomplish this, provide a description
|
124
|
+
(of any length) to the `use` method:
|
125
|
+
|
126
|
+
```ruby
|
127
|
+
EnvSetting.config do
|
128
|
+
use 'RAILS_SECRET_KEY_BASE',
|
129
|
+
'Generate a fresh one with `SecureRandom.urlsafe_base64(64)`; see http://guides.rubyonrails.org/security.html#session-storage'
|
130
|
+
end
|
131
|
+
```
|
132
|
+
|
133
|
+
Now if someone installs or deploys the app without setting the
|
134
|
+
`RAILS_SECRET_KEY_BASE` variable, they will see these instructions immediately
|
135
|
+
upon running the app.
|
136
|
+
|
137
|
+
### Automatic type conversion
|
138
|
+
|
139
|
+
`env_setting` can convert your environment variables for you, keeping that
|
140
|
+
tedium out of your application code. To specify a type, use the `:class` option:
|
141
|
+
|
142
|
+
```ruby
|
143
|
+
EnvSetting.config do
|
144
|
+
use :COPYRIGHT_YEAR, class: Integer
|
145
|
+
use :MEMCACHED_SERVERS, class: Array
|
146
|
+
use :MAIL_DELIVERY_METHOD, class: Symbol, default: :smtp
|
147
|
+
use :DEFAULT_FRACTION, class: Float
|
148
|
+
use :ENABLE_SOUNDTRACK, class: :boolean
|
149
|
+
use :PUPPETMASTERS, class: Hash
|
150
|
+
end
|
151
|
+
```
|
152
|
+
|
153
|
+
**Note** that arrays will be derived by splitting the value on commas (','). To
|
154
|
+
get arrays of a specific type of value, use the `:of` option:
|
155
|
+
|
156
|
+
```ruby
|
157
|
+
EnvSetting.config do
|
158
|
+
use :YEARS_OF_INTEREST, class: Array, of: Integer
|
159
|
+
end
|
160
|
+
```
|
161
|
+
|
162
|
+
Hashes are split on commas (',') and key:value pairs are delimited by colon
|
163
|
+
(':'). To get hashes of a specific type of value, use the `:of` option, and to
|
164
|
+
use a different type for keys (default is `Symbol`), use the `:keys` option:
|
165
|
+
|
166
|
+
```ruby
|
167
|
+
EnvSetting.config do
|
168
|
+
use :BIRTHDAYS, class: Hash, of: Integer, keys: String
|
169
|
+
end
|
170
|
+
```
|
171
|
+
|
172
|
+
#### Default type conversion behavior
|
173
|
+
|
174
|
+
If you don’t specify a `:class` option for a variable, `env_setting` defaults to
|
175
|
+
a special type conversion called `:StringUnlessFalsey`. This conversion returns
|
176
|
+
a string, unless the value is a "falsey" string `['false', 'no', 'off', '0',
|
177
|
+
'disable', 'disabled']`. To turn off this magic for one variable, pass in
|
178
|
+
`class: String`. To disable it globally, set
|
179
|
+
|
180
|
+
```ruby
|
181
|
+
EnvSetting.config do
|
182
|
+
default_class String
|
183
|
+
end
|
184
|
+
```
|
185
|
+
|
186
|
+
Or if you just dislike what is considered "falsey", configure your own regex
|
187
|
+
pattern of what strings are "falsey":
|
188
|
+
|
189
|
+
```ruby
|
190
|
+
EnvSetting.config do
|
191
|
+
default_falsey_regex(/0|fubar|false|n/i)
|
192
|
+
end
|
193
|
+
```
|
194
|
+
|
195
|
+
#### Custom type conversion
|
196
|
+
|
197
|
+
Suppose your app needs a special type conversion that doesn’t come with
|
198
|
+
`env_setting`. You can implement the conversion yourself with the `add_class`
|
199
|
+
method in the `EnvSetting.config` block. For example, to convert one of your
|
200
|
+
environment variables to type `Set`, you could write the following
|
201
|
+
configuration:
|
202
|
+
|
203
|
+
```sh
|
204
|
+
# In your environment:
|
205
|
+
export NUMBER_SET=1,3,5,7,9
|
206
|
+
```
|
207
|
+
|
208
|
+
```ruby
|
209
|
+
# In your env.rb configuration file:
|
210
|
+
require 'set'
|
211
|
+
|
212
|
+
EnvSetting.config do
|
213
|
+
add_class Set do |value, options|
|
214
|
+
Set.new self.Array(value, options || {})
|
215
|
+
end
|
216
|
+
|
217
|
+
use :NUMBER_SET, class: Set, of: Integer
|
218
|
+
end
|
219
|
+
```
|
220
|
+
|
221
|
+
```ruby
|
222
|
+
# Somewhere in your application:
|
223
|
+
EnvSetting.number_set
|
224
|
+
#=> #<Set: {1, 3, 5, 7, 9}>
|
225
|
+
```
|
226
|
+
|
227
|
+
## What if I don't like `EnvSetting` for my settings class name?
|
228
|
+
|
229
|
+
We don't blame you, the easiest way to "rename" the settings class from
|
230
|
+
`EnvSetting` is to define a new class that inherits from `EnvSetting` like so:
|
231
|
+
|
232
|
+
```ruby
|
233
|
+
class Settings < EnvSetting
|
234
|
+
end
|
235
|
+
|
236
|
+
Settings.config do
|
237
|
+
...
|
238
|
+
end
|
239
|
+
|
240
|
+
# elsewhere in your app
|
241
|
+
Settings.my_special_env_var
|
242
|
+
```
|
243
|
+
|
244
|
+
## Implementation Notes
|
245
|
+
|
246
|
+
1. Any method that can be run within an `EnvSetting.config` block can also be
|
247
|
+
run as a method directly on `EnvSetting`. For instance, instead of
|
248
|
+
|
249
|
+
```ruby
|
250
|
+
EnvSetting.config do
|
251
|
+
add_class Set do
|
252
|
+
...
|
253
|
+
end
|
254
|
+
|
255
|
+
use :NUMBER_SET, class: Set
|
256
|
+
end
|
257
|
+
```
|
258
|
+
|
259
|
+
It would also work to run
|
260
|
+
|
261
|
+
```ruby
|
262
|
+
EnvSetting.add_class Set do
|
263
|
+
...
|
264
|
+
end
|
265
|
+
|
266
|
+
EnvSetting.use :NUMBER_SET, class: Set
|
267
|
+
```
|
268
|
+
|
269
|
+
While the `config` block is designed to provide a cleaner configuration
|
270
|
+
file, calling the methods directly can occasionally be handy, such as when
|
271
|
+
trying things out in an IRB/Pry session.
|
272
|
+
|
273
|
+
2. `EnvSetting` is a wrapper for global state, and while it appears that
|
274
|
+
everything is stored/modified on the class level, it is actually defining and
|
275
|
+
delegating everything to a Singleton. Effectively that means that all the
|
276
|
+
ENV variable access methods are actually defined on an instance Singleton and
|
277
|
+
**not** on the `EnvSetting` class itself. For example:
|
278
|
+
|
279
|
+
```ruby
|
280
|
+
EnvSetting.use "BUNDLE_BIN_PATH"
|
281
|
+
|
282
|
+
# The class appears to respond to respond to our envrionment variable method
|
283
|
+
EnvSetting.bundle_bin_path
|
284
|
+
# => "/srv/app/shared/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/bundler-1.11.2/exe/bundle"
|
285
|
+
EnvSetting.:bundle_bin_path?
|
286
|
+
# => true
|
287
|
+
|
288
|
+
# However the Singelton is the true responder
|
289
|
+
EnvSetting.instance.bundle_bin_path
|
290
|
+
# => "/srv/app/shared/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/bundler-1.11.2/exe/bundle"
|
291
|
+
EnvSetting.instance.bundle_bin_path?
|
292
|
+
# => true
|
293
|
+
|
294
|
+
# Swapping in a different Singelton instance shows the truth.
|
295
|
+
EnvSetting.set_instance(EnvSetting.new)
|
296
|
+
EnvSetting.respond_to?(:bundle_bin_path)
|
297
|
+
# => false
|
298
|
+
EnvSetting.respond_to?(:bundle_bin_path?)
|
299
|
+
# => false
|
300
|
+
|
301
|
+
EnvSetting.instance.respond_to?(:bundle_bin_path)
|
302
|
+
# => false
|
303
|
+
EnvSetting.instance.respond_to?(:bundle_bin_path?)
|
304
|
+
# => false
|
305
|
+
```
|
306
|
+
|
307
|
+
3. `EnvSetting` stores the converted ENV variable values in a cache (just to
|
308
|
+
avoid having to repeat a laborious conversion). In the event that you want
|
309
|
+
all the cache to be cleared out and all the conversions applied again, use
|
310
|
+
the `clear_cache!` method on the **instance Singelton**:
|
311
|
+
|
312
|
+
```ruby
|
313
|
+
EnvSetting.instance.clear_cache!
|
314
|
+
```
|
315
|
+
|
316
|
+
## Acknowledgements
|
317
|
+
|
318
|
+
Jonathan Camenisch, the author of `ENV!`, has done substantial work of which
|
319
|
+
this gem takes advantage. This gem would not be possible without that work.
|
320
|
+
This gem simply changes the style in which the work that `ENV!` does is exposed
|
321
|
+
(i.e. via methods).
|
322
|
+
|
323
|
+
## License
|
324
|
+
|
325
|
+
This gem is licensed under the MIT License
|
326
|
+
|
327
|
+
## Contributing
|
328
|
+
|
329
|
+
1. Fork it
|
330
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
331
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
332
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
333
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rspec/core/rake_task"
|
3
|
+
|
4
|
+
namespace 'dotenv' do
|
5
|
+
Bundler::GemHelper.install_tasks :name => 'env_setting'
|
6
|
+
end
|
7
|
+
|
8
|
+
desc 'Run all tests'
|
9
|
+
RSpec::Core::RakeTask.new(:spec) do |s|
|
10
|
+
s.rspec_opts = '-f d -c'
|
11
|
+
s.pattern = 'spec/**/*_spec.rb'
|
12
|
+
end
|
13
|
+
task :default => :spec
|
data/certs/wspurgin.pem
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIDjjCCAnagAwIBAgIBATANBgkqhkiG9w0BAQUFADBGMRUwEwYDVQQDDAx3aWxs
|
3
|
+
LnNwdXJnaW4xGDAWBgoJkiaJk/IsZAEZFghvcm0tdGVjaDETMBEGCgmSJomT8ixk
|
4
|
+
ARkWA2NvbTAeFw0xNjA2MjAxNTU4NDJaFw0xNzA2MjAxNTU4NDJaMEYxFTATBgNV
|
5
|
+
BAMMDHdpbGwuc3B1cmdpbjEYMBYGCgmSJomT8ixkARkWCG9ybS10ZWNoMRMwEQYK
|
6
|
+
CZImiZPyLGQBGRYDY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
|
7
|
+
vRMpVroSt8OrOY/zyh/00HzNryjthX5JabsyIlZBBkqJSBakNa4p9y3EleODdvP8
|
8
|
+
3DPnDgAax5/nYd+UumPbcqPB7lhXHn+vw+082DVVOaL2IMg1fbqLRSpCXGvgz4za
|
9
|
+
P4QKMusXXRAo1+nLjl68pumyLfAD6dEF7bNk2diHpKppknb1ENsvs/v8/uWQBv27
|
10
|
+
AnIrHntPpKCLwSjxufgCa9IKdSy9EdwCBCwX9IOGTjUhFoRy+Fsx7pUi0NM7eaER
|
11
|
+
h0VYrXIPnembxN51iVA6LcM7wnzl6uVnSb/TJshc3zSIqZibvHSPKL1g17S2s8qa
|
12
|
+
2AspSOGAQ7iDAkt1lRnccQIDAQABo4GGMIGDMAkGA1UdEwQCMAAwCwYDVR0PBAQD
|
13
|
+
AgSwMB0GA1UdDgQWBBTdymM1YAMQyvVpddd//6sgBWrCOTAkBgNVHREEHTAbgRl3
|
14
|
+
aWxsLnNwdXJnaW5Ab3JtLXRlY2guY29tMCQGA1UdEgQdMBuBGXdpbGwuc3B1cmdp
|
15
|
+
bkBvcm0tdGVjaC5jb20wDQYJKoZIhvcNAQEFBQADggEBAK4zjjfK53r01ZtIB+xF
|
16
|
+
GT8OR3ri+iSrcTAaC7dk4XmjNU42hGBlFZ34RjnzxBGBjBZH9w+3jwCjN8FkPfmO
|
17
|
+
f1kiI4+tCt+weUzWFqhKsIaC23TjEDrlhyZ2203HldlW4p26onVwDpIn3YOYG9Qr
|
18
|
+
c+9wUpquUpi5e4bBVsIaHoYnECMOrGIgRSleI8YWLAakTWAXRL63dtekC945+3ep
|
19
|
+
vbrWi4+bt0feapcxjBsEk2q1TW6XmEWU8HokYJOxNbqKt5XuWZq/fcGgBV+CftFN
|
20
|
+
8o95YBJ2TniSxvMvbz2P9Q/Mh1AhMN4J0OqtcAo1One8UgJBXU8xZHj/qWMLwT9L
|
21
|
+
gtM=
|
22
|
+
-----END CERTIFICATE-----
|
data/env_setting.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'env_setting/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "env_setting"
|
8
|
+
spec.version = EnvSetting::VERSION
|
9
|
+
spec.authors = ["Will Spurgin"]
|
10
|
+
spec.email = ["will.spurgin@orm-tech.com"]
|
11
|
+
spec.summary = %q{Mange your environment variables in OOP style}
|
12
|
+
spec.description = %q{Allows OOP access to ENV variables by a slight re-write of the env_bang gem.}
|
13
|
+
spec.homepage = "https://github.com/ormtech/env_setting"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.cert_chain = ['certs/wspurgin.pem']
|
17
|
+
spec.signing_key = File.expand_path("~/.ssh/gem-private_key.pem") if $0 =~ /gem\z/
|
18
|
+
|
19
|
+
spec.files = `git ls-files`.split($/)
|
20
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
21
|
+
spec.test_files = spec.files.grep(%r{^(test)/})
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
spec.add_development_dependency "rake"
|
25
|
+
spec.add_development_dependency "rspec", "~> 3.4"
|
26
|
+
spec.add_development_dependency "simplecov"
|
27
|
+
spec.add_development_dependency "coveralls"
|
28
|
+
end
|
data/lib/env_setting.rb
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
require "env_setting/version"
|
2
|
+
require "env_setting/classes"
|
3
|
+
require "env_setting/formatter"
|
4
|
+
|
5
|
+
class EnvSetting
|
6
|
+
def self.config(&block)
|
7
|
+
class_eval(&block)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.use(var, *args)
|
11
|
+
var = var.to_s
|
12
|
+
description = args.first.is_a?(String) && args.shift
|
13
|
+
description ||= ""
|
14
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
15
|
+
|
16
|
+
unless ENV.has_key?(var)
|
17
|
+
ENV[var] = options.fetch(:default) { raise_formatted_error(var, description) }.to_s
|
18
|
+
end
|
19
|
+
|
20
|
+
vars[var] = options
|
21
|
+
|
22
|
+
method_name = var.downcase
|
23
|
+
|
24
|
+
instance.define_singleton_method(method_name) do
|
25
|
+
cache[method_name] ||= self.class.get_value(var)
|
26
|
+
end
|
27
|
+
|
28
|
+
method_name_bool = "#{method_name}?"
|
29
|
+
instance.define_singleton_method(method_name_bool) do
|
30
|
+
cache[method_name_bool] ||= !!(self.send(method_name))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.raise_formatted_error(var, description)
|
35
|
+
raise KeyError.new Formatter.formatted_error(var, description)
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.add_class(klass, &block)
|
39
|
+
Classes.send :define_singleton_method, klass.to_s, &block
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.default_class(*args)
|
43
|
+
if args.any?
|
44
|
+
Classes.default_class = args.first
|
45
|
+
else
|
46
|
+
Classes.default_class
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.default_falsey_regex(regex = nil)
|
51
|
+
if regex
|
52
|
+
Classes.default_falsey_regex = regex
|
53
|
+
else
|
54
|
+
Classes.default_falsey_regex
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.respond_to?(method_sym)
|
59
|
+
instance.respond_to?(method_sym) || super
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.method_missing(method, *args, &block)
|
63
|
+
instance.send(method, *args, &block)
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.instance
|
67
|
+
@@instance ||= new
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.set_instance(obj)
|
71
|
+
raise ArgumentError.new "Object must be a derivative of EnvSetting" unless obj.is_a?(EnvSetting)
|
72
|
+
@@instance = obj
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.vars
|
76
|
+
@@vars ||= {}
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.keys
|
80
|
+
vars.keys
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.values
|
84
|
+
keys.map { |k| self[k] }
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.get_value(var)
|
88
|
+
var = var.to_s
|
89
|
+
raise KeyError.new("#{var} is not configured in the ENV") unless vars.has_key?(var)
|
90
|
+
|
91
|
+
Classes.cast ENV[var], vars[var]
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.[](var)
|
95
|
+
self.get_value(var)
|
96
|
+
end
|
97
|
+
|
98
|
+
def cache
|
99
|
+
@cache ||= {}
|
100
|
+
end
|
101
|
+
|
102
|
+
def clear_cache!
|
103
|
+
@cache = nil
|
104
|
+
end
|
105
|
+
|
106
|
+
def respond_to?(method_sym)
|
107
|
+
ENV.respond_to?(method_sym) || super
|
108
|
+
end
|
109
|
+
|
110
|
+
def method_missing(method, *args, &block)
|
111
|
+
ENV.send(method, *args, &block)
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
class EnvSetting
|
2
|
+
module Classes
|
3
|
+
class << self
|
4
|
+
attr_writer :default_class
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.default_class
|
8
|
+
@@default_class ||= :StringUnlessFalsey
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.default_falsey_regex
|
12
|
+
@@default_falsey_regex ||= /^(|0|disabled?|false|no|off)$/i
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.default_falsey_regex=(regex)
|
16
|
+
@@default_falsey_regex = regex
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.cast(value, options = {})
|
20
|
+
public_send(:"#{options.fetch(:class, default_class)}", value, options)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.boolean(value, options)
|
24
|
+
!(value =~ default_falsey_regex)
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.Array(value, options)
|
28
|
+
item_options = options.merge(class: options.fetch(:of, default_class))
|
29
|
+
value.split(',').map { |v| cast(v.strip, item_options) }
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.Hash(value, options)
|
33
|
+
key_options = options.merge(class: options.fetch(:keys, Symbol))
|
34
|
+
value_options = options.merge(class: options.fetch(:of, default_class))
|
35
|
+
{}.tap do |h|
|
36
|
+
value.split(',').each do |pair|
|
37
|
+
key, value = pair.split(':')
|
38
|
+
h[cast(key.strip, key_options)] = cast(value.strip, value_options)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.Symbol(value, options)
|
44
|
+
value.to_sym
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.StringUnlessFalsey(value, options)
|
48
|
+
boolean(value, options) && value
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.respond_to?(method_sym)
|
52
|
+
Kernel.respond_to?(method_sym) || super
|
53
|
+
end
|
54
|
+
|
55
|
+
# Delegate methods like Integer(), Float(), String(), etc. to the Kernel module
|
56
|
+
def self.method_missing(klass, value, options = {}, &block)
|
57
|
+
Kernel.send(klass, value)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class EnvSetting
|
2
|
+
module Formatter
|
3
|
+
def self.formatted_error(var, description)
|
4
|
+
indent 4, <<-EOS
|
5
|
+
|
6
|
+
Missing required environment variable: #{var}#{ description and "\n" <<
|
7
|
+
unindent(description) }
|
8
|
+
EOS
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.unindent(string)
|
12
|
+
width = string.scan(/^ */).map(&:length).min
|
13
|
+
string.gsub(/^ {#{width}}/, '')
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.indent(width, string)
|
17
|
+
string.gsub "\n", "\n#{' ' * width}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,300 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe EnvSetting do
|
4
|
+
|
5
|
+
it "Raises exception if unconfigured ENV var requested" do
|
6
|
+
ENV['UNCONFIGURED'] = 'unconfigured'
|
7
|
+
expect { described_class.unconfigured }.to raise_error NoMethodError
|
8
|
+
expect { described_class['UNCONFIGURED'] }.to raise_error KeyError
|
9
|
+
end
|
10
|
+
|
11
|
+
it "Raises exception if configured ENV var is not present" do
|
12
|
+
ENV.delete('NOT_PRESENT')
|
13
|
+
|
14
|
+
expect {
|
15
|
+
described_class.config do
|
16
|
+
use 'NOT_PRESENT'
|
17
|
+
end
|
18
|
+
}.to raise_error KeyError
|
19
|
+
end
|
20
|
+
|
21
|
+
it "Should define two methods for each configured ENV var" do
|
22
|
+
ENV['CUSTOM_VAR'] = 'foo'
|
23
|
+
|
24
|
+
described_class.config do
|
25
|
+
use 'CUSTOM_VAR'
|
26
|
+
end
|
27
|
+
|
28
|
+
expect(described_class).to respond_to(:custom_var)
|
29
|
+
expect(described_class.custom_var).to eq 'foo'
|
30
|
+
|
31
|
+
expect(described_class).to respond_to(:custom_var?)
|
32
|
+
expect(described_class.custom_var?).to eq true
|
33
|
+
end
|
34
|
+
|
35
|
+
it "Uses provided default value if ENV var not already present" do
|
36
|
+
ENV.delete('WASNT_PRESENT')
|
37
|
+
|
38
|
+
described_class.config do
|
39
|
+
use 'WASNT_PRESENT', default: 'a default value'
|
40
|
+
end
|
41
|
+
expect(described_class.wasnt_present).to eq 'a default value'
|
42
|
+
end
|
43
|
+
|
44
|
+
it "Returns actual value from ENV if present" do
|
45
|
+
ENV['PRESENT'] = 'present in environment'
|
46
|
+
|
47
|
+
described_class.config do
|
48
|
+
use 'PRESENT', default: "You won't need this."
|
49
|
+
end
|
50
|
+
expect(described_class.present).to eq 'present in environment'
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "Type casting" do
|
54
|
+
let(:truthy_values) { %w[true on yes yo yup anything] }
|
55
|
+
let(:falsey_values) { %w[false no off disable disabled 0] << '' }
|
56
|
+
let(:integers) { %w[0 1 10 -42 -55] }
|
57
|
+
let(:floats) { %w[0.1 1.3 10 -42.3 -55] }
|
58
|
+
|
59
|
+
it "Casts Integers" do
|
60
|
+
integer = integers.sample
|
61
|
+
ENV['INTEGER'] = integer
|
62
|
+
described_class.use 'INTEGER', class: Integer
|
63
|
+
|
64
|
+
expect(described_class.integer).to eq integer.to_i
|
65
|
+
end
|
66
|
+
|
67
|
+
it "Casts Symbols" do
|
68
|
+
ENV['SYMBOL'] = 'symbol'
|
69
|
+
described_class.use 'SYMBOL', class: Symbol
|
70
|
+
|
71
|
+
expect(described_class.symbol).to eq :symbol
|
72
|
+
end
|
73
|
+
|
74
|
+
it "Casts Floats" do
|
75
|
+
float = floats.sample
|
76
|
+
ENV['FLOAT'] = float
|
77
|
+
described_class.use 'FLOAT', class: Float
|
78
|
+
|
79
|
+
expect(described_class.float).to eq float.to_f
|
80
|
+
expect(described_class.float).to be_a Float
|
81
|
+
end
|
82
|
+
|
83
|
+
it "Casts Arrays" do
|
84
|
+
ENV['ARRAY'] = 'one,two , three, four'
|
85
|
+
described_class.use 'ARRAY', class: Array
|
86
|
+
|
87
|
+
expect(described_class.array).to match_array(%w[one two three four])
|
88
|
+
end
|
89
|
+
|
90
|
+
it "Casts Arrays of Integers" do
|
91
|
+
ENV['INTEGERS'] = integers.join(',')
|
92
|
+
described_class.use 'INTEGERS', class: Array, of: Integer
|
93
|
+
|
94
|
+
expect(described_class.integers).to match_array(integers.map(&:to_i))
|
95
|
+
end
|
96
|
+
|
97
|
+
it "Casts Arrays of Floats" do
|
98
|
+
ENV['FLOATS'] = floats.join(',')
|
99
|
+
described_class.use 'FLOATS', class: Array, of: Float
|
100
|
+
|
101
|
+
expect(described_class.floats).to match_array(floats.map(&:to_f))
|
102
|
+
end
|
103
|
+
|
104
|
+
it "regression: Casting Array always returns Array" do
|
105
|
+
ENV['ARRAY'] = 'one,two , three, four'
|
106
|
+
described_class.use 'ARRAY', class: Array
|
107
|
+
|
108
|
+
2.times do
|
109
|
+
expect(described_class.array).to match_array(%w[one two three four])
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
it "Casts Hashes" do
|
114
|
+
ENV['HASH_VAR'] = 'one: two, three: four'
|
115
|
+
described_class.use 'HASH_VAR', class: Hash
|
116
|
+
|
117
|
+
expect(described_class.hash_var).to eq({one: 'two', three: 'four'})
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'Casts Hashes of Integers' do
|
121
|
+
ENV['INT_HASH'] = 'one: 111, two: 222'
|
122
|
+
described_class.use 'INT_HASH', class: Hash, of: Integer
|
123
|
+
|
124
|
+
expect(described_class.int_hash).to eq({one: 111, two: 222})
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'Casts Hashes with String keys' do
|
128
|
+
ENV['STRKEY_HASH'] = 'one: two, three: four'
|
129
|
+
described_class.use 'STRKEY_HASH', class: Hash, keys: String
|
130
|
+
|
131
|
+
expect(described_class.strkey_hash).to eq({'one' => 'two', 'three' => 'four'})
|
132
|
+
end
|
133
|
+
|
134
|
+
it "Casts true" do
|
135
|
+
ENV['TRUE'] = truthy_values.sample
|
136
|
+
described_class.use 'TRUE', class: :boolean
|
137
|
+
|
138
|
+
expect(described_class.true).to eq true
|
139
|
+
expect(described_class.true?).to eq true
|
140
|
+
end
|
141
|
+
|
142
|
+
it "Casts false" do
|
143
|
+
ENV['FALSE'] = falsey_values.sample
|
144
|
+
described_class.use 'FALSE', class: :boolean
|
145
|
+
|
146
|
+
expect(described_class.false).to eq false
|
147
|
+
expect(described_class.false?).to eq false
|
148
|
+
end
|
149
|
+
|
150
|
+
it "converts falsey or empty string to false by default" do
|
151
|
+
ENV['FALSE'] = falsey_values.sample
|
152
|
+
described_class.use 'FALSE'
|
153
|
+
|
154
|
+
expect(described_class.false).to eq false
|
155
|
+
end
|
156
|
+
|
157
|
+
it "leaves falsey string as string if specified" do
|
158
|
+
ENV['FALSE'] = falsey_values.sample
|
159
|
+
described_class.use 'FALSE', class: String
|
160
|
+
|
161
|
+
expect(described_class.false).to be_a String
|
162
|
+
end
|
163
|
+
|
164
|
+
it "allows default class to be overridden" do
|
165
|
+
expect(described_class.default_class).to eq :StringUnlessFalsey
|
166
|
+
orig = described_class.default_class
|
167
|
+
|
168
|
+
described_class.config { default_class String }
|
169
|
+
ENV['FALSE'] = falsey_values.sample
|
170
|
+
described_class.use 'FALSE'
|
171
|
+
|
172
|
+
expect(described_class.false).to be_a String
|
173
|
+
|
174
|
+
described_class.default_class orig
|
175
|
+
end
|
176
|
+
|
177
|
+
it "allows default falsey regex to be overridden" do
|
178
|
+
expect(described_class.default_falsey_regex).to eq(/^(|0|disabled?|false|no|off)$/i)
|
179
|
+
orig = described_class.default_falsey_regex
|
180
|
+
|
181
|
+
described_class.config { default_falsey_regex(/fubar/i) }
|
182
|
+
|
183
|
+
ENV['FALSEY'] = 'fubar'
|
184
|
+
described_class.use 'FALSEY'
|
185
|
+
|
186
|
+
expect(described_class.falsey).to be_a FalseClass
|
187
|
+
|
188
|
+
# Reset the default for rest of tests.
|
189
|
+
described_class.default_falsey_regex orig
|
190
|
+
end
|
191
|
+
|
192
|
+
it "allows addition of custom types" do
|
193
|
+
require 'set'
|
194
|
+
|
195
|
+
ENV['NUMBER_SET'] = '1,3,5,7,9'
|
196
|
+
described_class.config do
|
197
|
+
add_class Set do |value, options|
|
198
|
+
Set.new self.Array(value, options || {})
|
199
|
+
end
|
200
|
+
|
201
|
+
use :NUMBER_SET, class: Set, of: Integer
|
202
|
+
end
|
203
|
+
expect(described_class::Classes).to respond_to(:Set)
|
204
|
+
|
205
|
+
expect(described_class.number_set).to eq Set.new [1, 3, 5, 7, 9]
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
describe "Hash-like behavior" do
|
210
|
+
it "provides configured keys" do
|
211
|
+
ENV['VAR1'] = 'something'
|
212
|
+
ENV['VAR2'] = 'something else'
|
213
|
+
described_class.use 'VAR1'
|
214
|
+
described_class.use 'VAR2'
|
215
|
+
|
216
|
+
expect(described_class.keys).to include(*%w[VAR1 VAR2])
|
217
|
+
end
|
218
|
+
|
219
|
+
it "provides configured values" do
|
220
|
+
ENV['VAR1'] = 'something'
|
221
|
+
ENV['VAR2'] = 'something else'
|
222
|
+
described_class.use 'VAR1'
|
223
|
+
described_class.use 'VAR2'
|
224
|
+
|
225
|
+
expect(described_class.values).to include(*%w[something something\ else])
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
describe "Formatting" do
|
230
|
+
it "Includes provided description in error message" do
|
231
|
+
ENV.delete('NOT_PRESENT')
|
232
|
+
|
233
|
+
expect {
|
234
|
+
described_class.config do
|
235
|
+
use 'NOT_PRESENT', 'You need a NOT_PRESENT var in your ENV'
|
236
|
+
end
|
237
|
+
}.to raise_error(KeyError, /You need a NOT_PRESENT var in your ENV/)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
describe ".instance" do
|
242
|
+
it "returns the instance singleton of #{described_class}" do
|
243
|
+
expect(described_class.instance).to be_a(described_class)
|
244
|
+
end
|
245
|
+
|
246
|
+
it "should have a local instance cache of the ENV variables' method names and their return values" do
|
247
|
+
ENV['VAR1'] = 'something'
|
248
|
+
described_class.use 'VAR1'
|
249
|
+
|
250
|
+
described_class.var1
|
251
|
+
described_class.var1?
|
252
|
+
|
253
|
+
expect(described_class.instance.cache).to have_key("var1")
|
254
|
+
expect(described_class.instance.cache).to have_key("var1?")
|
255
|
+
end
|
256
|
+
|
257
|
+
it "allows the cache to be cleared" do
|
258
|
+
ENV['VAR1'] = 'something'
|
259
|
+
described_class.use 'VAR1'
|
260
|
+
|
261
|
+
described_class.var1
|
262
|
+
described_class.var1?
|
263
|
+
|
264
|
+
expect(described_class.instance.cache.keys). to include "var1", "var1?"
|
265
|
+
|
266
|
+
described_class.instance.clear_cache!
|
267
|
+
expect(described_class.instance.cache).to be_empty
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
describe "#set_instance" do
|
272
|
+
let(:setting_class) { Class.new(described_class) }
|
273
|
+
it "should set the instance Singleton to the given object" do
|
274
|
+
obj = setting_class.new
|
275
|
+
described_class.set_instance(obj)
|
276
|
+
expect(described_class.instance).to be obj
|
277
|
+
|
278
|
+
obj = described_class.new
|
279
|
+
described_class.set_instance(obj)
|
280
|
+
expect(described_class.instance).to be obj
|
281
|
+
end
|
282
|
+
|
283
|
+
it "should raise an argument error if the given class is not a derivative of #{described_class}" do
|
284
|
+
expect { described_class.set_instance(Object.new) }.to raise_error(ArgumentError)
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
describe "#instance" do
|
289
|
+
it "should have the ENV variable methods defined on the Singelton, not the class" do
|
290
|
+
# Reset Singleton for fresh test
|
291
|
+
described_class.set_instance(described_class.new)
|
292
|
+
ENV["MY_SPECIAL_VAR"] = "foo"
|
293
|
+
|
294
|
+
described_class.use :MY_SPECIAL_VAR
|
295
|
+
expect(described_class.method_defined? :my_special_var).to eq false
|
296
|
+
expect(described_class.instance).to respond_to(:my_special_var)
|
297
|
+
expect(described_class.instance.public_methods).to include :my_special_var, :my_special_var?
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'simplecov'
|
3
|
+
require 'coveralls'
|
4
|
+
|
5
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([
|
6
|
+
SimpleCov::Formatter::HTMLFormatter,
|
7
|
+
Coveralls::SimpleCov::Formatter
|
8
|
+
])
|
9
|
+
SimpleCov.start
|
10
|
+
|
11
|
+
Coveralls.wear!
|
12
|
+
|
13
|
+
require 'bundler/setup'
|
14
|
+
Bundler.setup
|
15
|
+
|
16
|
+
require 'env_setting'
|
17
|
+
|
metadata
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: env_setting
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Will Spurgin
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain:
|
11
|
+
- |
|
12
|
+
-----BEGIN CERTIFICATE-----
|
13
|
+
MIIDjjCCAnagAwIBAgIBATANBgkqhkiG9w0BAQUFADBGMRUwEwYDVQQDDAx3aWxs
|
14
|
+
LnNwdXJnaW4xGDAWBgoJkiaJk/IsZAEZFghvcm0tdGVjaDETMBEGCgmSJomT8ixk
|
15
|
+
ARkWA2NvbTAeFw0xNjA2MjAxNTU4NDJaFw0xNzA2MjAxNTU4NDJaMEYxFTATBgNV
|
16
|
+
BAMMDHdpbGwuc3B1cmdpbjEYMBYGCgmSJomT8ixkARkWCG9ybS10ZWNoMRMwEQYK
|
17
|
+
CZImiZPyLGQBGRYDY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
|
18
|
+
vRMpVroSt8OrOY/zyh/00HzNryjthX5JabsyIlZBBkqJSBakNa4p9y3EleODdvP8
|
19
|
+
3DPnDgAax5/nYd+UumPbcqPB7lhXHn+vw+082DVVOaL2IMg1fbqLRSpCXGvgz4za
|
20
|
+
P4QKMusXXRAo1+nLjl68pumyLfAD6dEF7bNk2diHpKppknb1ENsvs/v8/uWQBv27
|
21
|
+
AnIrHntPpKCLwSjxufgCa9IKdSy9EdwCBCwX9IOGTjUhFoRy+Fsx7pUi0NM7eaER
|
22
|
+
h0VYrXIPnembxN51iVA6LcM7wnzl6uVnSb/TJshc3zSIqZibvHSPKL1g17S2s8qa
|
23
|
+
2AspSOGAQ7iDAkt1lRnccQIDAQABo4GGMIGDMAkGA1UdEwQCMAAwCwYDVR0PBAQD
|
24
|
+
AgSwMB0GA1UdDgQWBBTdymM1YAMQyvVpddd//6sgBWrCOTAkBgNVHREEHTAbgRl3
|
25
|
+
aWxsLnNwdXJnaW5Ab3JtLXRlY2guY29tMCQGA1UdEgQdMBuBGXdpbGwuc3B1cmdp
|
26
|
+
bkBvcm0tdGVjaC5jb20wDQYJKoZIhvcNAQEFBQADggEBAK4zjjfK53r01ZtIB+xF
|
27
|
+
GT8OR3ri+iSrcTAaC7dk4XmjNU42hGBlFZ34RjnzxBGBjBZH9w+3jwCjN8FkPfmO
|
28
|
+
f1kiI4+tCt+weUzWFqhKsIaC23TjEDrlhyZ2203HldlW4p26onVwDpIn3YOYG9Qr
|
29
|
+
c+9wUpquUpi5e4bBVsIaHoYnECMOrGIgRSleI8YWLAakTWAXRL63dtekC945+3ep
|
30
|
+
vbrWi4+bt0feapcxjBsEk2q1TW6XmEWU8HokYJOxNbqKt5XuWZq/fcGgBV+CftFN
|
31
|
+
8o95YBJ2TniSxvMvbz2P9Q/Mh1AhMN4J0OqtcAo1One8UgJBXU8xZHj/qWMLwT9L
|
32
|
+
gtM=
|
33
|
+
-----END CERTIFICATE-----
|
34
|
+
date: 2016-06-20 00:00:00.000000000 Z
|
35
|
+
dependencies:
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rake
|
38
|
+
requirement: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
type: :development
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0'
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
name: rspec
|
52
|
+
requirement: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - "~>"
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '3.4'
|
57
|
+
type: :development
|
58
|
+
prerelease: false
|
59
|
+
version_requirements: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - "~>"
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '3.4'
|
64
|
+
- !ruby/object:Gem::Dependency
|
65
|
+
name: simplecov
|
66
|
+
requirement: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
type: :development
|
72
|
+
prerelease: false
|
73
|
+
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: coveralls
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
type: :development
|
86
|
+
prerelease: false
|
87
|
+
version_requirements: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
description: Allows OOP access to ENV variables by a slight re-write of the env_bang
|
93
|
+
gem.
|
94
|
+
email:
|
95
|
+
- will.spurgin@orm-tech.com
|
96
|
+
executables: []
|
97
|
+
extensions: []
|
98
|
+
extra_rdoc_files: []
|
99
|
+
files:
|
100
|
+
- ".gitignore"
|
101
|
+
- ".travis.yml"
|
102
|
+
- Gemfile
|
103
|
+
- LICENSE.txt
|
104
|
+
- README.md
|
105
|
+
- Rakefile
|
106
|
+
- certs/wspurgin.pem
|
107
|
+
- env_setting.gemspec
|
108
|
+
- lib/env_setting.rb
|
109
|
+
- lib/env_setting/classes.rb
|
110
|
+
- lib/env_setting/formatter.rb
|
111
|
+
- lib/env_setting/version.rb
|
112
|
+
- spec/env_setting_spec.rb
|
113
|
+
- spec/spec_helper.rb
|
114
|
+
homepage: https://github.com/ormtech/env_setting
|
115
|
+
licenses:
|
116
|
+
- MIT
|
117
|
+
metadata: {}
|
118
|
+
post_install_message:
|
119
|
+
rdoc_options: []
|
120
|
+
require_paths:
|
121
|
+
- lib
|
122
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
123
|
+
requirements:
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
127
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
requirements: []
|
133
|
+
rubyforge_project:
|
134
|
+
rubygems_version: 2.2.2
|
135
|
+
signing_key:
|
136
|
+
specification_version: 4
|
137
|
+
summary: Mange your environment variables in OOP style
|
138
|
+
test_files: []
|
metadata.gz.sig
ADDED