envied 0.3.1 → 0.4.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 +4 -4
- data/.travis.yml +5 -0
- data/CHANGELOG.md +37 -0
- data/README.md +96 -17
- data/lib/envied/version.rb +3 -0
- data/lib/envied.rb +135 -100
- data/spec/envied_spec.rb +127 -32
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5d3ba3eb81e06018962bb52faa7caf1fdf044aca
|
4
|
+
data.tar.gz: a92a83a6a9272771f39eca36b3f0126aac9fd439
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7d4643b26e39b59b534285cc8f58f0228285468ec3860c3479b0a1cd3b5041a2d7fae2b40ce176c985105d4a793f705d226eef3ccf9591bc1c87a50f9d1b90a5
|
7
|
+
data.tar.gz: 2407bd5bf9a1700b76d81d77de7a4de9b2b7da1fba44257119444afb9e0e08ed2e4badf19d0f8d7cdecdf314c9a3affb4ef89119d42e0f3a9426bd0ac1d10bae
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# 0.4.0 / 2014-05-16
|
2
|
+
|
3
|
+
* groups added
|
4
|
+
|
5
|
+
This allows for more fine-grained requiring.
|
6
|
+
See the section in the [README](https://github.com/eval/envied/tree/v0.4.0#groups).
|
7
|
+
|
8
|
+
* configuring is now simpler:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
ENVied.configure { variable :RACK_ENV }
|
12
|
+
# vs
|
13
|
+
ENVied.configure {|env| env.variable :RACK_ENV }
|
14
|
+
```
|
15
|
+
|
16
|
+
* Deprecate `require!`. Use `require` instead.
|
17
|
+
|
18
|
+
Just like requiring groups with Bundler.
|
19
|
+
|
20
|
+
* Deprecate lowercase methods for uppercase ENV-variables.
|
21
|
+
|
22
|
+
`ENV['RACK_ENV']` is no longer accessible as `ENVied.rack_env`, only as `ENVied.RACK_ENV`.
|
23
|
+
This is not only what you would expect, but it also reduces the chance of clashing with existing class-methods.
|
24
|
+
|
25
|
+
# 0.3.0 / 2014-03-14
|
26
|
+
|
27
|
+
* defaults need to be enabled explicitly:
|
28
|
+
|
29
|
+
`ENVied.configure(enable_defaults: Rails.env.development?) { ... }`
|
30
|
+
|
31
|
+
# 0.2.0 / 2014-03-14
|
32
|
+
|
33
|
+
* add defaults
|
34
|
+
|
35
|
+
# 0.1.0 / 2014-03-13
|
36
|
+
|
37
|
+
* add defaults
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# ENVied
|
1
|
+
# ENVied [](https://secure.travis-ci.org/#!/eval/envied)
|
2
2
|
|
3
3
|
### TL;DR ensure presence and type of your app's ENV-variables.
|
4
4
|
|
@@ -20,33 +20,61 @@ Let's configure the ENV-variables we need:
|
|
20
20
|
|
21
21
|
```ruby
|
22
22
|
# e.g. config/application.rb
|
23
|
-
ENVied.configure do
|
24
|
-
|
25
|
-
|
23
|
+
ENVied.configure do
|
24
|
+
variable :FORCE_SSL, :Boolean
|
25
|
+
variable :PORT, :Integer
|
26
26
|
end
|
27
27
|
```
|
28
28
|
|
29
29
|
### 2) Check for presence and type
|
30
30
|
|
31
31
|
```ruby
|
32
|
-
ENVied.require
|
32
|
+
ENVied.require
|
33
33
|
```
|
34
|
-
Excecution will halt unless ENV is something like
|
35
|
-
`{'FORCE_SSL' => 'false', 'PORT' => '3001'}`.
|
36
34
|
|
37
|
-
|
35
|
+
This will throw an error if not:
|
36
|
+
* both `ENV['FORCE_SSL']` and `ENV['PORT']` are present
|
37
|
+
* both the values of `ENV['FORCE_SSL']` and `ENV['PORT']` can be coerced (to resp. Boolean or Integer).
|
38
|
+
|
39
|
+
(The error contains exactly what ENV-variables are missing/faulty.)
|
38
40
|
|
39
41
|
### 3) Use typed variables
|
40
42
|
|
41
43
|
Variables accessed via ENVied have the configured type:
|
42
44
|
|
43
45
|
```ruby
|
44
|
-
ENVied.
|
45
|
-
ENVied.
|
46
|
+
ENVied.PORT # => 3001
|
47
|
+
ENVied.FORCE_SSL # => false
|
46
48
|
```
|
47
49
|
|
48
50
|
## Configuration
|
49
51
|
|
52
|
+
### Groups
|
53
|
+
|
54
|
+
Groups give you more flexibility to define when variables are needed.
|
55
|
+
It's just like you Gemfile:
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
ENVied.configure do
|
59
|
+
variable :FORCE_SSL, :Boolean
|
60
|
+
|
61
|
+
group :production do
|
62
|
+
variable :NEW_RELIC_LICENSE_KEY
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# For local development you would typically do:
|
67
|
+
ENVied.require(:default) #=> Only ENV['FORCE_SSL'] is required
|
68
|
+
# On the server:
|
69
|
+
ENVied.require(:default, :production) #=> ...also ENV['NEW_RELIC_LICENSE_KEY'] is required
|
70
|
+
|
71
|
+
# BTW the following are equivalent:
|
72
|
+
ENVied.require
|
73
|
+
ENVied.require(:default)
|
74
|
+
ENVied.require('default')
|
75
|
+
ENVied.require(nil)
|
76
|
+
```
|
77
|
+
|
50
78
|
### Types
|
51
79
|
|
52
80
|
The following types are supported:
|
@@ -63,20 +91,71 @@ The following types are supported:
|
|
63
91
|
In order to let other developers easily bootstrap the application, you can assign defaults to variables.
|
64
92
|
Defaults can be a value or a `Proc` (see example below).
|
65
93
|
|
66
|
-
Note that 'easily bootstrap' is quite the opposite of 'fail-fast when not all ENV-variables are present'. Therefor
|
94
|
+
Note that 'easily bootstrap' is quite the opposite of 'fail-fast when not all ENV-variables are present'. Therefor you should explicitly state whén defaults are allowed:
|
67
95
|
|
68
96
|
```ruby
|
69
|
-
ENVied.configure(enable_defaults:
|
70
|
-
|
71
|
-
|
97
|
+
ENVied.configure(enable_defaults: ENV['RACK_ENV'] == 'development') do
|
98
|
+
variable :FORCE_SSL, :Boolean, default: false
|
99
|
+
variable :PORT, :Integer, default: proc {|envied| envied.FORCE_SSL ? 443 : 80 }
|
72
100
|
end
|
73
101
|
```
|
74
102
|
|
75
|
-
Please remember that ENVied only **reads** from ENV;
|
76
|
-
|
77
|
-
|
103
|
+
Please remember that ENVied only **reads** from ENV; it doesn't set ENV-variables.
|
104
|
+
Don't let setting a default for, say `RAILS_ENV`, give you the impression that `ENV['RAILS_ENV']` is set.
|
105
|
+
As a rule of thumb you should only use defaults:
|
106
|
+
* for local development
|
78
107
|
* for ENV-variables that your application introduces (i.e. for `ENV['DEFAULT_SENDER']` not for `ENV['REDIS_URL']`)
|
79
108
|
|
109
|
+
### A more extensive example:
|
110
|
+
|
111
|
+
```ruby
|
112
|
+
# We allow defaults for local development (and local tests), but want our CI
|
113
|
+
# to mimic our production as much as possible.
|
114
|
+
# New developers that don't have RACK_ENV set, will in this way not be presented with a huge
|
115
|
+
# list of missing variables, as defaults are still enabled.
|
116
|
+
not_production_nor_ci = ->{ !(ENV['RACK_ENV'] == 'production' || ENV['CI']) }
|
117
|
+
ENVied.configure(enable_defaults: ¬_production_nor_ci) do
|
118
|
+
# Your code will likely not use ENVied.RACK_ENV (better use Rails.env),
|
119
|
+
# we want it to be present though; heck, we're using it in this file!
|
120
|
+
variable :RACK_ENV
|
121
|
+
|
122
|
+
variable :FORCE_SSL, :Boolean, default: false
|
123
|
+
variable :PORT, :Integer, default: 3000
|
124
|
+
# generate the default value using the value of PORT:
|
125
|
+
variable :PUBLIC_HOST_WITH_PORT, :String, default: proc {|envied| "localhost:#{envied.PORT}" }
|
126
|
+
|
127
|
+
group :production do
|
128
|
+
variable :MAIL_PAAS_USERNAME
|
129
|
+
variable :DATABASE_URL, :Symbol
|
130
|
+
end
|
131
|
+
|
132
|
+
group :ci do
|
133
|
+
# ci-only stuff
|
134
|
+
end
|
135
|
+
|
136
|
+
group :not_ci do
|
137
|
+
# CI needs no puma-threads, and sidekiq-stuff etc.
|
138
|
+
# Define that here:
|
139
|
+
variable :MIN_THREADS, :Integer, default: 1
|
140
|
+
# more...
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# Depending on our situation, we can now require the groups needed:
|
145
|
+
# At local machines:
|
146
|
+
ENVied.require(:default, :development, :not_ci) or
|
147
|
+
ENVied.require(:default, :test, :not_ci)
|
148
|
+
|
149
|
+
# At the server:
|
150
|
+
ENVied.require(:default, :production, :not_ci)
|
151
|
+
|
152
|
+
# At CI:
|
153
|
+
ENVied.require(:default, :test, :ci)
|
154
|
+
|
155
|
+
# All in one line:
|
156
|
+
ENVied.require(:default, ENV['RACK_ENV'], (ENV['CI'] ? :ci : :not_ci))
|
157
|
+
```
|
158
|
+
|
80
159
|
|
81
160
|
## Installation
|
82
161
|
|
data/lib/envied.rb
CHANGED
@@ -1,137 +1,172 @@
|
|
1
|
+
require 'virtus'
|
2
|
+
|
1
3
|
class ENVied
|
2
|
-
|
3
|
-
|
4
|
+
class Configuration
|
5
|
+
include Virtus.model
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
end
|
7
|
+
def self.variable(name, type = :String, options = {})
|
8
|
+
options = { strict: true, group: self.current_group }.merge(options)
|
9
|
+
attribute(name, type, options)
|
10
|
+
end
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
12
|
+
def self.group(name, &block)
|
13
|
+
self.current_group = name.to_sym
|
14
|
+
yield
|
15
|
+
ensure
|
16
|
+
self.current_group = :default
|
14
17
|
end
|
15
18
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
19
|
+
def self.enable_defaults
|
20
|
+
@enable_defaults.respond_to?(:call) ?
|
21
|
+
@enable_defaults.call :
|
22
|
+
@enable_defaults
|
20
23
|
end
|
21
24
|
|
22
|
-
class
|
23
|
-
|
24
|
-
|
25
|
-
|
25
|
+
class << self
|
26
|
+
attr_writer :enable_defaults
|
27
|
+
alias_method :defaults_enabled?, :enable_defaults
|
28
|
+
attr_accessor :current_group
|
26
29
|
end
|
27
30
|
|
28
|
-
def self.
|
29
|
-
|
30
|
-
|
31
|
+
def self.current_group
|
32
|
+
@current_group ||= :default
|
33
|
+
end
|
34
|
+
end
|
31
35
|
|
32
|
-
|
33
|
-
|
34
|
-
|
36
|
+
def self.configuration(options = {}, &block)
|
37
|
+
if block_given?
|
38
|
+
@configuration = build_configuration(&block).tap do |c|
|
39
|
+
options.each{|k, v| c.public_send("#{k}=", v) }
|
35
40
|
end
|
36
|
-
base.extend ClassMethods
|
37
41
|
end
|
42
|
+
@configuration ||= build_configuration
|
43
|
+
end
|
38
44
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
#
|
44
|
-
# Will raise VariableTypeError for variables whose ENV-value can't be coerced to the configured type.
|
45
|
-
#
|
46
|
-
# @param env [Hash] the env
|
47
|
-
def parse_env(env)
|
48
|
-
atts = attribute_set.map(&:name).each_with_object({}) do |name, result|
|
49
|
-
variable = attribute_set[name]
|
50
|
-
default = variable.options[:default]
|
51
|
-
value = env[name.to_s] || env[name.to_s.upcase]
|
52
|
-
if !(value || default)
|
53
|
-
raise VariableMissingError, variable
|
54
|
-
end
|
55
|
-
|
56
|
-
try_coercion(variable, value, default)
|
57
|
-
result[name] = value if value
|
58
|
-
end
|
59
|
-
|
60
|
-
new(atts)
|
61
|
-
end
|
45
|
+
class << self
|
46
|
+
alias_method :configure, :configuration
|
47
|
+
attr_accessor :required_groups
|
48
|
+
end
|
62
49
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
50
|
+
def self.build_configuration(&block)
|
51
|
+
Class.new(Configuration).tap do |c|
|
52
|
+
c.instance_eval(&block) if block_given?
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.require(*groups)
|
57
|
+
groups.compact!
|
58
|
+
@instance = nil
|
59
|
+
if groups.any?
|
60
|
+
self.required_groups = groups.map(&:to_sym)
|
61
|
+
else
|
62
|
+
self.required_groups = [:default]
|
63
|
+
end
|
64
|
+
error_on_missing_variables!
|
65
|
+
error_on_uncoercible_variables!
|
77
66
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
end
|
83
|
-
return unless value
|
84
|
-
@variable = variable
|
85
|
-
|
86
|
-
variable.coerce(value)
|
87
|
-
rescue Virtus::CoercionError => e
|
88
|
-
raise VariableTypeError.new(@variable)
|
67
|
+
_required_variables = required_variables
|
68
|
+
group_configuration = build_configuration do
|
69
|
+
_required_variables.each do |v|
|
70
|
+
@attribute_set << v
|
89
71
|
end
|
90
72
|
end
|
73
|
+
@instance = group_configuration.new(ENV.to_hash)
|
91
74
|
end
|
92
75
|
|
93
|
-
|
94
|
-
|
76
|
+
def self.error_on_missing_variables!
|
77
|
+
if missing_variable_names.any?
|
78
|
+
raise "Please set the following ENV-variables: #{missing_variable_names.sort.join(',')}"
|
79
|
+
end
|
95
80
|
end
|
96
81
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
82
|
+
def self.error_on_uncoercible_variables!
|
83
|
+
if non_coercible_variables.any?
|
84
|
+
single_error = "ENV['%{name}'] ('%{value}' can't be coerced to %{type})"
|
85
|
+
errors = non_coercible_variables.map do |v|
|
86
|
+
var_type = v.type.to_s.split("::").last
|
87
|
+
single_error % { name: v.name, value: env_value_or_default(v), type: var_type }
|
88
|
+
end.join ", "
|
89
|
+
|
90
|
+
raise "Some ENV-variables are not coercible: #{errors}"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.env_value(variable)
|
95
|
+
ENV[variable.name.to_s]
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.env_value_or_default(variable)
|
99
|
+
env_value(variable) || default_value(variable)
|
100
|
+
end
|
101
|
+
|
102
|
+
# Yields the assigned default for the variable.
|
103
|
+
# When defaults are disabled, nil is returned.
|
104
|
+
def self.default_value(variable)
|
105
|
+
defaults_enabled? ? variable.default_value.value : nil
|
106
|
+
end
|
107
|
+
|
108
|
+
# A list of all configured variable names.
|
101
109
|
#
|
102
110
|
# @example
|
103
|
-
# ENVied.
|
104
|
-
#
|
105
|
-
# end
|
111
|
+
# ENVied.configured_variable_names
|
112
|
+
# # => [:DATABASE_URL]
|
106
113
|
#
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
k.enable_defaults = options[:enable_defaults]
|
111
|
-
k.instance_eval(&block)
|
112
|
-
end
|
113
|
-
# or define this thing as ENVied::Configuration? prolly not threadsafe
|
114
|
-
ensure
|
115
|
-
@instance = nil
|
114
|
+
# @return [Array<Symbol>] the list of variable names
|
115
|
+
def self.required_variable_names
|
116
|
+
required_variables.map(&:name).map(&:to_sym)
|
116
117
|
end
|
117
118
|
|
118
|
-
def self.
|
119
|
-
|
119
|
+
def self.required_variables
|
120
|
+
from_required_group = ->(var){ self.required_groups.include?(var.options[:group]) }
|
121
|
+
configured_variables.to_a.keep_if(&from_required_group)
|
120
122
|
end
|
121
|
-
|
122
|
-
|
123
|
+
|
124
|
+
def self.configured_variables
|
125
|
+
configuration.attribute_set.dup#.to_a.keep_if(&var_from_required_group)
|
126
|
+
end
|
127
|
+
|
128
|
+
def self.provided_variable_names
|
129
|
+
ENV.keys.map(&:to_sym)
|
130
|
+
end
|
131
|
+
|
132
|
+
def self.non_coercible_variables
|
133
|
+
required_variables.reject(&method(:variable_coercible?))
|
134
|
+
end
|
135
|
+
|
136
|
+
def self.variable_coercible?(variable)
|
137
|
+
var_value = env_value_or_default(variable)
|
138
|
+
return true if var_value.respond_to?(:call)
|
139
|
+
|
140
|
+
variable.coerce var_value
|
141
|
+
rescue Virtus::CoercionError
|
142
|
+
return false
|
143
|
+
end
|
144
|
+
|
145
|
+
def self.missing_variable_names
|
146
|
+
unprovided = required_variable_names - provided_variable_names
|
147
|
+
unprovided -= names_of_required_variables_with_defaults if defaults_enabled?
|
148
|
+
unprovided
|
149
|
+
end
|
150
|
+
|
151
|
+
def self.names_of_required_variables_with_defaults
|
152
|
+
required_variables_with_defaults.map(&:name).map(&:to_sym)
|
153
|
+
end
|
154
|
+
|
155
|
+
def self.required_variables_with_defaults
|
156
|
+
required_variables.map do |v|
|
157
|
+
v unless v.default_value.value.nil?
|
158
|
+
end.compact
|
123
159
|
end
|
124
160
|
|
125
|
-
def self.
|
126
|
-
|
127
|
-
#instance[key] # will raise and complain that <class <>> doesn't response; better?
|
161
|
+
def self.defaults_enabled?
|
162
|
+
configuration.enable_defaults
|
128
163
|
end
|
129
164
|
|
130
165
|
def self.method_missing(method, *args, &block)
|
131
|
-
respond_to_missing?(method) ? instance.public_send(method, *args, &block) : super
|
166
|
+
respond_to_missing?(method) ? @instance.public_send(method, *args, &block) : super
|
132
167
|
end
|
133
168
|
|
134
169
|
def self.respond_to_missing?(method, include_private = false)
|
135
|
-
instance.
|
170
|
+
@instance.respond_to?(method) || super
|
136
171
|
end
|
137
172
|
end
|
data/spec/envied_spec.rb
CHANGED
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe ENVied do
|
4
4
|
subject { described_class }
|
5
5
|
|
6
|
-
it { should respond_to :require
|
6
|
+
it { should respond_to :require }
|
7
7
|
it { should respond_to :configure }
|
8
8
|
|
9
9
|
context 'configured' do
|
@@ -14,14 +14,16 @@ describe ENVied do
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def configure(options = {}, &block)
|
17
|
+
described_class.instance_eval { @configuration = nil }
|
17
18
|
described_class.configure(options, &block)
|
18
19
|
self
|
19
20
|
end
|
20
21
|
|
21
22
|
def configured_with(hash = {})
|
22
|
-
described_class.
|
23
|
+
described_class.instance_eval { @configuration = nil }
|
24
|
+
described_class.configure do
|
23
25
|
hash.each do |name, type|
|
24
|
-
|
26
|
+
variable(name, *type)
|
25
27
|
end
|
26
28
|
end
|
27
29
|
self
|
@@ -37,62 +39,155 @@ describe ENVied do
|
|
37
39
|
end
|
38
40
|
|
39
41
|
it 'responds to configured variables' do
|
40
|
-
configured_with(a: :Integer).and_ENV({'
|
42
|
+
configured_with(a: :Integer).and_ENV({'a' => '1'})
|
43
|
+
described_class.require
|
44
|
+
|
41
45
|
is_expected.to respond_to :a
|
42
46
|
end
|
43
47
|
|
44
48
|
it 'responds not to unconfigured variables' do
|
45
49
|
unconfigured.and_ENV({'A' => '1'})
|
46
|
-
|
50
|
+
described_class.require
|
51
|
+
|
52
|
+
is_expected.to_not respond_to :B
|
47
53
|
end
|
48
54
|
|
49
55
|
context 'ENV contains not all configured variables' do
|
50
56
|
before { configured_with(a: :Integer).and_no_ENV }
|
51
57
|
|
52
|
-
|
53
|
-
expect {
|
54
|
-
ENVied.require!
|
55
|
-
}.to raise_error(ENVied::Configurable::VariableMissingError)
|
56
|
-
end
|
57
|
-
|
58
|
-
it 'raises EnvMissing when interacted with' do
|
58
|
+
specify do
|
59
59
|
expect {
|
60
|
-
ENVied.
|
61
|
-
}.to raise_error
|
60
|
+
ENVied.require
|
61
|
+
}.to raise_error /set the following ENV-variables: a/
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
-
context 'ENV
|
66
|
-
before { configured_with(
|
65
|
+
context 'ENV variables are not coercible' do
|
66
|
+
before { configured_with(A: :Integer).and_ENV('A' => 'NaN') }
|
67
67
|
|
68
68
|
specify do
|
69
69
|
expect {
|
70
|
-
ENVied.
|
71
|
-
}.to raise_error(
|
70
|
+
ENVied.require
|
71
|
+
}.to raise_error /ENV\['A'\] \('NaN' can't be coerced to Integer/
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
|
-
describe '
|
76
|
-
|
77
|
-
|
75
|
+
describe 'defaults' do
|
76
|
+
describe 'setting' do
|
77
|
+
subject { described_class.configuration }
|
78
|
+
|
79
|
+
it 'is disabled by default' do
|
80
|
+
expect(subject.enable_defaults).to_not be
|
81
|
+
end
|
78
82
|
|
79
|
-
|
83
|
+
it 'can be enabled via #configure' do
|
84
|
+
configure(enable_defaults: true){ }
|
85
|
+
|
86
|
+
expect(subject.enable_defaults).to be
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'can be enabled via a configure-block' do
|
90
|
+
configure { self.enable_defaults = true }
|
91
|
+
|
92
|
+
expect(subject.enable_defaults).to be
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'can be assigned a Proc' do
|
96
|
+
configure { self.enable_defaults = -> { true } }
|
97
|
+
|
98
|
+
expect(subject.enable_defaults).to be
|
99
|
+
end
|
80
100
|
end
|
81
101
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
102
|
+
describe 'assigning' do
|
103
|
+
it 'can be a value' do
|
104
|
+
configure(enable_defaults: true) do
|
105
|
+
variable :A, :Integer, default: 1
|
106
|
+
end
|
107
|
+
described_class.require
|
108
|
+
|
109
|
+
expect(described_class.A).to eq 1
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'can be a Proc' do
|
113
|
+
configure(enable_defaults: true) do
|
114
|
+
variable :A, :Integer, default: proc { 1 }
|
115
|
+
end
|
116
|
+
described_class.require
|
86
117
|
|
87
|
-
|
118
|
+
expect(described_class.A).to eq 1
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'is ignored if defaults are disabled' do
|
122
|
+
configure(enable_defaults: false) do
|
123
|
+
variable :A, :Integer, default: 1
|
124
|
+
end.and_no_ENV
|
125
|
+
|
126
|
+
expect {
|
127
|
+
described_class.require
|
128
|
+
}.to raise_error
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'is is ignored if ENV is provided' do
|
132
|
+
configure(enable_defaults: true) do
|
133
|
+
variable :A, :Integer, default: 1
|
134
|
+
end.and_ENV('A' => '2')
|
135
|
+
described_class.require
|
136
|
+
|
137
|
+
expect(described_class.A).to eq 2
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'can be defined in terms of other variables' do
|
141
|
+
configure(enable_defaults: true) do
|
142
|
+
variable :A, :Integer
|
143
|
+
variable :B, :Integer, default: proc {|env| env.A * 2 }
|
144
|
+
end.and_ENV('A' => '1')
|
145
|
+
described_class.require
|
146
|
+
|
147
|
+
expect(described_class.B).to eq 2
|
148
|
+
end
|
88
149
|
end
|
150
|
+
end
|
151
|
+
describe "groups" do
|
152
|
+
context 'a variable in a group' do
|
153
|
+
before do
|
154
|
+
configure do
|
155
|
+
variable :moar
|
156
|
+
|
157
|
+
group :foo do
|
158
|
+
variable :bar
|
159
|
+
end
|
160
|
+
end.and_no_ENV
|
161
|
+
end
|
89
162
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
163
|
+
it 'is required when requiring the group' do
|
164
|
+
expect {
|
165
|
+
described_class.require(:foo)
|
166
|
+
}.to raise_error /bar/
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'is not required when requiring another group' do
|
170
|
+
expect {
|
171
|
+
described_class.require(:bat)
|
172
|
+
}.to_not raise_error
|
173
|
+
end
|
94
174
|
|
95
|
-
|
175
|
+
it 'wont define non-required variables on ENVied' do
|
176
|
+
stub_const("ENV", {'moar' => 'yes'})
|
177
|
+
described_class.require(:default)
|
178
|
+
|
179
|
+
expect {
|
180
|
+
described_class.bar
|
181
|
+
}.to raise_error
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'requires variables without a group when requiring the default group' do
|
185
|
+
[:default, 'default'].each do |groups|
|
186
|
+
expect {
|
187
|
+
described_class.require(*groups)
|
188
|
+
}.to raise_error /moar/
|
189
|
+
end
|
190
|
+
end
|
96
191
|
end
|
97
192
|
end
|
98
193
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: envied
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gert Goet
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-05-
|
11
|
+
date: 2014-05-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: virtus
|
@@ -74,12 +74,15 @@ extensions: []
|
|
74
74
|
extra_rdoc_files: []
|
75
75
|
files:
|
76
76
|
- ".gitignore"
|
77
|
+
- ".travis.yml"
|
78
|
+
- CHANGELOG.md
|
77
79
|
- Gemfile
|
78
80
|
- LICENSE.txt
|
79
81
|
- README.md
|
80
82
|
- Rakefile
|
81
83
|
- envied.gemspec
|
82
84
|
- lib/envied.rb
|
85
|
+
- lib/envied/version.rb
|
83
86
|
- spec/envied_spec.rb
|
84
87
|
- spec/spec_helper.rb
|
85
88
|
- underconstruction.gif
|