env_setting 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://travis-ci.org/ormtech/env_setting.svg?branch=master)](https://travis-ci.org/ormtech/env_setting)
|
10
|
+
[![Coverage Status](https://coveralls.io/repos/github/ormtech/env_setting/badge.svg?branch=master)](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