envied 0.10.0.alpha3 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +82 -176
- data/lib/envied/cli.rb +0 -9
- data/lib/envied/coercer/envied_string.rb +0 -4
- data/lib/envied/coercer.rb +1 -1
- data/lib/envied/configuration.rb +24 -16
- data/lib/envied/env_proxy.rb +9 -12
- data/lib/envied/variable.rb +11 -2
- data/lib/envied/version.rb +1 -1
- data/lib/envied.rb +6 -36
- metadata +21 -90
- data/.envrc.sample +0 -9
- data/.github/pull_request_template.md +0 -2
- data/.gitignore +0 -15
- data/.gitlab-ci.yml +0 -50
- data/.rspec +0 -3
- data/CHANGELOG.md +0 -208
- data/Gemfile +0 -4
- data/Rakefile +0 -6
- data/bin/bundle +0 -105
- data/bin/console +0 -10
- data/bin/envied +0 -5
- data/bin/rspec +0 -29
- data/bin/setup +0 -8
- data/envied.gemspec +0 -38
- data/examples/extensive_envfile +0 -64
- data/lib/envied/env_interceptor.rb +0 -19
- data/lib/envied/templates/Envfile.tt +0 -10
- data/lib/envied/templates/heroku-env-check.tt +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0511e3b0eba9370a6b0bd51ef3a3642bbfafa30f12b92a5a007b5ce2293b3c14
|
4
|
+
data.tar.gz: 62100f8640f1b5fc14ac46e8d5a916cf5ba2d3c3f7b14c99a246d06e3482a551
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f92d02db070a5bc4f600ccc360c5d41af97c4766e537d3d29880944b45a7e8d7357d5bf01ea16d9167c1cab44398e14db2e4d7691de9c6e622f6035a322d27dc
|
7
|
+
data.tar.gz: 2ccb1f56a3a626d1177a9a27829e718c344ada5293dd12dd4577d384efd030219adfed807f7f9615f456307c89a7f6f8fe308ea70f2e5d720c6500864b643b8e
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -1,36 +1,27 @@
|
|
1
|
-
# ENVied [![
|
2
|
-
|
3
|
-
_Canonical Repository:_ https://gitlab.com/envied/envied/tree/master#envied
|
1
|
+
# ENVied [![Tests](https://github.com/javierjulio/envied/actions/workflows/tests.yml/badge.svg)](https://github.com/javierjulio/envied/actions/workflows/tests.yml)
|
4
2
|
|
5
3
|
### TL;DR ensure presence and type of your app's ENV-variables.
|
6
4
|
|
7
|
-
For the rationale behind this project, see this [blogpost](
|
5
|
+
For the rationale behind this project, see this [blogpost](http://www.gertgoet.com/2014/10/14/envied-or-how-i-stopped-worrying-about-ruby-s-env.html).
|
8
6
|
|
9
|
-
## Features
|
7
|
+
## Features:
|
10
8
|
|
11
9
|
* check for presence and correctness of ENV-variables
|
12
10
|
* access to typed ENV-variables (integers, booleans etc. instead of just strings)
|
13
11
|
* check the presence and correctness of a Heroku config
|
14
12
|
|
15
|
-
## Non-features
|
16
|
-
|
17
|
-
* provide or load ENV-values
|
18
|
-
|
19
13
|
## Contents
|
20
14
|
|
21
15
|
* [Quickstart](#quickstart)
|
22
16
|
* [Installation](#installation)
|
23
17
|
* [Configuration](#configuration)
|
24
18
|
* [Types](#types)
|
25
|
-
* [Key alias](#key-alias-unreleased)
|
26
|
-
* [env-type](#env-type-unreleased)
|
27
19
|
* [Groups](#groups)
|
20
|
+
* [Defaults](#defaults)
|
21
|
+
* [More examples](#more-examples)
|
28
22
|
* [Command-line interface](#command-line-interface)
|
29
|
-
* [
|
30
|
-
* [FAQ](#faq)
|
31
|
-
* [Testing](#testing)
|
23
|
+
* [How do I...?](#how-do-i)
|
32
24
|
* [Development](#development)
|
33
|
-
* [Contributing](#contributing)
|
34
25
|
|
35
26
|
## Quickstart
|
36
27
|
|
@@ -47,13 +38,13 @@ variable :PORT, :integer
|
|
47
38
|
### 2) Check for presence and coercibility
|
48
39
|
|
49
40
|
```ruby
|
50
|
-
# during initialization
|
41
|
+
# during initialization and in a pre-deploy confirmation workflow
|
51
42
|
ENVied.require
|
52
43
|
```
|
53
44
|
|
54
45
|
This will throw an error if:
|
55
|
-
*
|
56
|
-
*
|
46
|
+
* both `ENV['FORCE_SSL']` and `ENV['PORT']` are *not present*.
|
47
|
+
* the values *cannot* be coerced to a boolean and integer.
|
57
48
|
|
58
49
|
### 3) Use coerced variables
|
59
50
|
|
@@ -66,95 +57,66 @@ ENVied.FORCE_SSL # => false
|
|
66
57
|
|
67
58
|
## Installation
|
68
59
|
|
69
|
-
Add
|
70
|
-
|
71
|
-
gem 'envied'
|
72
|
-
|
73
|
-
...then bundle:
|
74
|
-
|
75
|
-
$ bundle
|
76
|
-
|
77
|
-
...then for Rails applications:
|
78
|
-
|
79
|
-
$ bundle exec envied init:rails
|
80
|
-
|
81
|
-
...or for non-Rails applications:
|
82
|
-
|
83
|
-
$ bundle exec envied init
|
84
|
-
|
85
|
-
## Configuration
|
86
|
-
|
87
|
-
### Types
|
88
|
-
|
89
|
-
The following types are supported:
|
90
|
-
|
91
|
-
* `:array` (e.g. 'tag1,tag2' becomes `['tag1', 'tag2']`)
|
92
|
-
* `:boolean` (e.g. '0'/'1', 'f'/'t', 'false'/'true', 'off'/'on', 'no'/'yes' for resp. false and true)
|
93
|
-
* `:date` (e.g. '2014-3-26')
|
94
|
-
* `:env` (similar to `:string`, but accessible via ENV - see [Key alias](#key-alias-unreleased) for details)
|
95
|
-
* `:float`
|
96
|
-
* `:hash` (e.g. 'a=1&b=2' becomes `{'a' => '1', 'b' => '2'}`)
|
97
|
-
* `:integer`
|
98
|
-
* `:string` (implied)
|
99
|
-
* `:symbol`
|
100
|
-
* `:time` (e.g. '14:00')
|
101
|
-
* `:uri` (e.g. 'http://www.google.com' becomes result of `URI.parse('http://www.google.com')`)
|
102
|
-
|
103
|
-
|
104
|
-
### Key alias (unreleased)
|
60
|
+
Add `envied` to your `Gemfile`:
|
105
61
|
|
106
|
-
|
107
|
-
|
108
|
-
|
62
|
+
```ruby
|
63
|
+
gem 'envied'
|
64
|
+
```
|
109
65
|
|
110
|
-
|
66
|
+
If you are using Rails, add this to `config/application.rb` immediately after `Bundler.require(*Rails.groups)`:
|
111
67
|
|
112
|
-
|
68
|
+
```ruby
|
69
|
+
ENVied.require(*ENV['ENVIED_GROUPS'] || Rails.groups)
|
113
70
|
```
|
114
|
-
# file: Envfile
|
115
|
-
key_alias! { Rails.env }
|
116
71
|
|
117
|
-
|
118
|
-
```
|
72
|
+
If you are not using Rails, add the following snippet (or similar) to your app's initialization:
|
119
73
|
|
120
|
-
|
121
|
-
|
122
|
-
# file: .envrc
|
123
|
-
export REDIS_URL_DEVELOPMENT=redis://localhost:6379/0
|
124
|
-
export REDIS_URL_TEST=redis://localhost:6379/1
|
74
|
+
```ruby
|
75
|
+
ENVied.require(*ENV['ENVIED_GROUPS'] || [:default, ENV['RACK_ENV']])
|
125
76
|
```
|
126
|
-
Now commands like `rails console` and `rails test` automatically point to the right redis database.
|
127
77
|
|
128
|
-
|
129
|
-
Also: any truthy value provided as key_alias is converted to an upcased string.
|
130
|
-
Finally: this setting is optional.
|
78
|
+
Create an `Envfile` with the following as a starter:
|
131
79
|
|
80
|
+
```ruby
|
81
|
+
enable_defaults! { ENV['RACK_ENV'] != 'production' }
|
132
82
|
|
133
|
-
|
83
|
+
variable :LOG_LEVEL, :string, default: 'debug'
|
134
84
|
|
135
|
-
|
85
|
+
group :production do
|
86
|
+
variable :SECRET_KEY_BASE
|
87
|
+
end
|
88
|
+
```
|
136
89
|
|
137
|
-
|
90
|
+
Refer to the [Types](#types) section to start configuring your project's environment variables.
|
138
91
|
|
139
|
-
|
140
|
-
# file: Envfile
|
92
|
+
### Pre-deploy ENV check
|
141
93
|
|
142
|
-
|
94
|
+
To confirm that your ENV variables are set in a pre-deploy workflow, provide the application's current ENV to a Ruby script that loads it and runs the envied check.
|
143
95
|
|
144
|
-
|
96
|
+
```ruby
|
97
|
+
ENV.replace(your_current_env)
|
98
|
+
ENVied.require(*RAILS_GROUPS)
|
99
|
+
puts "All required ENV variables are present and valid."
|
145
100
|
```
|
146
101
|
|
147
|
-
|
148
|
-
```shell
|
149
|
-
$ DATABASE_URL_DEVELOPMENT=postgres://localhost/blog_development rails runner "p ENV['DATABASE_URL']"
|
150
|
-
"postgres://localhost/blog_development"
|
151
|
-
```
|
102
|
+
If any required ENV are missing, then the check will fail with an error message listing the missing environment variable names.
|
152
103
|
|
153
|
-
|
154
|
-
Also: no coercion is done (like you would expect when accessing ENV-values directly).
|
104
|
+
## Configuration
|
155
105
|
|
156
|
-
|
106
|
+
### Types
|
157
107
|
|
108
|
+
The following types are supported:
|
109
|
+
|
110
|
+
* `:string` (implied)
|
111
|
+
* `:boolean` (e.g. '0'/'1', 'f'/'t', 'false'/'true', 'off'/'on', 'no'/'yes' for resp. false and true)
|
112
|
+
* `:integer`
|
113
|
+
* `:float`
|
114
|
+
* `:symbol`
|
115
|
+
* `:date` (e.g. '2014-3-26')
|
116
|
+
* `:time` (e.g. '14:00')
|
117
|
+
* `:hash` (e.g. 'a=1&b=2' becomes `{'a' => '1', 'b' => '2'}`)
|
118
|
+
* `:array` (e.g. 'tag1,tag2' becomes `['tag1', 'tag2']`)
|
119
|
+
* `:uri` (e.g. 'http://www.google.com' becomes result of `URI.parse('http://www.google.com')`)
|
158
120
|
|
159
121
|
### Groups
|
160
122
|
|
@@ -163,7 +125,7 @@ It's similar to groups in a Gemfile:
|
|
163
125
|
|
164
126
|
```ruby
|
165
127
|
# file: Envfile
|
166
|
-
variable :FORCE_SSL, :boolean
|
128
|
+
variable :FORCE_SSL, :boolean, default: 'false'
|
167
129
|
|
168
130
|
group :production do
|
169
131
|
variable :SECRET_KEY_BASE
|
@@ -195,6 +157,32 @@ ENVied.require('default')
|
|
195
157
|
ENVied.require(nil)
|
196
158
|
```
|
197
159
|
|
160
|
+
### Defaults
|
161
|
+
|
162
|
+
In order to let other developers easily bootstrap the application, you can assign defaults to variables.
|
163
|
+
Defaults can be a value or a `Proc` (see example below).
|
164
|
+
|
165
|
+
Note that 'easily bootstrap' is quite the opposite of 'fail-fast when not all ENV-variables are present'. Therefore you should explicitly state when defaults are allowed:
|
166
|
+
|
167
|
+
```ruby
|
168
|
+
# Envfile
|
169
|
+
enable_defaults! { ENV['RACK_ENV'] == 'development' }
|
170
|
+
|
171
|
+
variable :FORCE_SSL, :boolean, default: 'false'
|
172
|
+
variable :PORT, :integer, default: proc {|envied| envied.FORCE_SSL ? 443 : 80 }
|
173
|
+
```
|
174
|
+
|
175
|
+
Please remember that ENVied only **reads** from ENV; it doesn't mutate ENV.
|
176
|
+
Don't let setting a default for, say `RAILS_ENV`, give you the impression that `ENV['RAILS_ENV']` is set.
|
177
|
+
As a rule of thumb you should only use defaults:
|
178
|
+
* for local development
|
179
|
+
* for ENV-variables that are solely used by your application (i.e. for `ENV['STAFF_EMAILS']`, not for `ENV['RAILS_ENV']`)
|
180
|
+
|
181
|
+
### More examples
|
182
|
+
|
183
|
+
* See the [examples](/examples)-folder for a more extensive Envfile
|
184
|
+
* See [the Envfile](https://github.com/eval/bunny_drain/blob/c54d7d977afb5e23a92da7a2fd0d39f6a7e29bf1/Envfile) for the bunny_drain application
|
185
|
+
|
198
186
|
## Command-line interface
|
199
187
|
|
200
188
|
For help on a specific command, use `envied help <command>`.
|
@@ -212,55 +200,9 @@ Commands:
|
|
212
200
|
envied version, --version, -v # Shows version number
|
213
201
|
```
|
214
202
|
|
215
|
-
##
|
216
|
-
|
217
|
-
Some best practices when using ENVied or working with env-configurable applications in general.
|
218
|
-
|
219
|
-
### include a .envrc.sample
|
220
|
-
|
221
|
-
While ENVied will warn you when you start an application that is 'under-configured', it won't tell users what good default values are. To solve this add a file to the root of your project that contains sane defaults and instructions:
|
222
|
-
```
|
223
|
-
# file: .envrc.sample
|
224
|
-
# copy this file to .envrc and adjust values if needed
|
225
|
-
# then do `source .envrc` to load
|
203
|
+
## How do I
|
226
204
|
|
227
|
-
|
228
|
-
# export FORCE_SSL=true # only needed for production
|
229
|
-
|
230
|
-
# you can find this token on the Heroku-dashboard
|
231
|
-
export DEPLOY_TOKEN=1234-ABC-5678
|
232
|
-
```
|
233
|
-
|
234
|
-
### let [direnv](https://direnv.net/) manage your environment
|
235
|
-
|
236
|
-
[direnv](https://direnv.net/) will auto-(un)load values from `.envrc` when you switch folders.
|
237
|
-
|
238
|
-
As a bonus it has some powerful commands in it's [stdlib](https://direnv.net/#man/direnv-stdlib.1).
|
239
|
-
For example:
|
240
|
-
```
|
241
|
-
# this adds the project's bin-folder to $PATH
|
242
|
-
PATH_add bin
|
243
|
-
# so instead of `./bin/rails -h` you can do `rails -h` from anywhere (deep) in the project
|
244
|
-
|
245
|
-
# the following will use the .envrc.sample as a basis
|
246
|
-
# when new variables are introduced upstream, you'll automatically use these defaults
|
247
|
-
if [ -f .envrc.sample ]; then
|
248
|
-
source_env .envrc.sample
|
249
|
-
fi
|
250
|
-
...your overrides
|
251
|
-
|
252
|
-
# a variant of this is source_up
|
253
|
-
# an .envrc in a subfolder can load the .envrc from the root of the project and override specific values
|
254
|
-
# this would allow e.g. for a specific test-environment in the subfolder:
|
255
|
-
# in my-project/test/.envrc
|
256
|
-
source_up .envrc
|
257
|
-
export DATABASE_URL=the-test-db-url
|
258
|
-
```
|
259
|
-
|
260
|
-
|
261
|
-
## FAQ
|
262
|
-
|
263
|
-
### How to find all ENV-variables my app is currently using?
|
205
|
+
### ...find all ENV-variables my app is currently using?
|
264
206
|
|
265
207
|
```
|
266
208
|
$ bundle exec envied extract
|
@@ -270,7 +212,7 @@ This comes in handy when you're not using ENVied yet. It will find all `ENV['KEY
|
|
270
212
|
|
271
213
|
It assumes a standard project layout (see the default value for the globs-option).
|
272
214
|
|
273
|
-
###
|
215
|
+
### ...check the config of a Heroku app?
|
274
216
|
|
275
217
|
The easiest/quickest is to run:
|
276
218
|
|
@@ -293,44 +235,8 @@ This way you can do stuff like:
|
|
293
235
|
$ ./bin/heroku-env-check && git push live master
|
294
236
|
```
|
295
237
|
|
296
|
-
### What happened to default values??
|
297
|
-
|
298
|
-
The short version: simplicity, i.e. the best tool for the job.
|
299
|
-
|
300
|
-
In the early days of ENVied it was possible to provide default values for a variable.
|
301
|
-
While convenient, it had several drawbacks:
|
302
|
-
- it would introduce a value for ENVied.FOO, while ENV['FOO'] was nil: confusing and a potential source of bugs.
|
303
|
-
- it hides the fact that an application can actually be configged via the environment.
|
304
|
-
- it creates an in-process environment which is hard to inspect (as opposed to doing `printenv FOO` in a shell, after or before starting the application).
|
305
|
-
- there are better ways: e.g. a sample file in a project with a bunch of exports (ie `export FOO=sane-default # and even some documentation`) that someone can source in their shell (see [Best Practices](#best-practices)).
|
306
|
-
- made the code quite complex.
|
307
|
-
|
308
|
-
As an alternative include a file `.envrc.sample` in the root of your project containing default values (ie `export FOO=bar`) that users can source in their shell. See also [Best Practices](#best-practices).
|
309
|
-
|
310
|
-
|
311
238
|
## Development
|
312
239
|
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
# run tests
|
317
|
-
$ ./bin/rspec
|
318
|
-
|
319
|
-
# hack with pry
|
320
|
-
$ ./bin/console
|
321
|
-
|
322
|
-
# run CLI:
|
323
|
-
$ ./bin/envied
|
324
|
-
```
|
325
|
-
|
326
|
-
There's a `.envrc.sample` included that can be used in combination with [direnv](http://direnv.net/).
|
327
|
-
|
328
|
-
## Contributing
|
329
|
-
|
330
|
-
To suggest a new feature, [open an Issue](https://gitlab.com/envied/envied/issues/new) before opening a PR.
|
331
|
-
|
332
|
-
1. Fork it: https://gitlab.com/envied/envied/-/forks/new
|
333
|
-
2. Create your feature branch: `git checkout -b my-new-feature`
|
334
|
-
3. Commit your changes: `git commit -am 'Add some feature'`
|
335
|
-
4. Push to the branch: `git push origin my-new-feature`
|
336
|
-
5. Create a new pull request for your feature branch
|
240
|
+
- `bin/setup`
|
241
|
+
- Run tests: `RUBYOPT="-W:deprecated" bundle exec rspec`
|
242
|
+
- For an interactive console: `bin/console`
|
data/lib/envied/cli.rb
CHANGED
@@ -70,9 +70,6 @@ class ENVied
|
|
70
70
|
option :groups, type: :array, desc: "uses ENV['ENVIED_GROUPS'] as default if present", default: ENV['ENVIED_GROUPS'] || %w(default), banner: 'default production'
|
71
71
|
option :quiet, type: :boolean, desc: 'Communicate success of the check only via the exit status.'
|
72
72
|
def check
|
73
|
-
if rails_project?
|
74
|
-
require File.expand_path 'config/environment.rb'
|
75
|
-
end
|
76
73
|
ENVied.require(*options[:groups])
|
77
74
|
unless options[:quiet]
|
78
75
|
puts "All variables for group(s) #{options[:groups]} are present and valid"
|
@@ -129,11 +126,5 @@ class ENVied
|
|
129
126
|
template("heroku-env-check.tt", full_dest)
|
130
127
|
FileUtils.chmod 0755, full_dest
|
131
128
|
end
|
132
|
-
|
133
|
-
no_tasks do
|
134
|
-
def rails_project?
|
135
|
-
File.exists?('config/environment.rb')
|
136
|
-
end
|
137
|
-
end
|
138
129
|
end
|
139
130
|
end
|
data/lib/envied/coercer.rb
CHANGED
@@ -22,7 +22,7 @@ class ENVied::Coercer
|
|
22
22
|
|
23
23
|
def self.supported_types
|
24
24
|
@supported_types ||= begin
|
25
|
-
[:
|
25
|
+
[:hash, :array, :time, :date, :symbol, :boolean, :integer, :string, :uri, :float].sort
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
data/lib/envied/configuration.rb
CHANGED
@@ -1,30 +1,28 @@
|
|
1
1
|
class ENVied
|
2
2
|
class Configuration
|
3
|
-
attr_reader :current_group, :coercer
|
3
|
+
attr_reader :current_group, :defaults_enabled, :coercer
|
4
4
|
|
5
5
|
def initialize(**options, &block)
|
6
6
|
@coercer = options.fetch(:coercer, Coercer.new)
|
7
|
-
@
|
7
|
+
@defaults_enabled = options.fetch(:enable_defaults, defaults_enabled_default)
|
8
8
|
instance_eval(&block) if block_given?
|
9
9
|
end
|
10
10
|
|
11
|
-
def
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
@key_alias && @key_alias.to_s.upcase
|
11
|
+
def self.load(file='Envfile', **options)
|
12
|
+
envfile = File.expand_path(file)
|
13
|
+
new(**options).tap do |v|
|
14
|
+
v.instance_eval(File.read(envfile), envfile)
|
15
|
+
end
|
17
16
|
end
|
18
17
|
|
19
|
-
def enable_defaults!(
|
20
|
-
|
18
|
+
def enable_defaults!(value = true, &block)
|
19
|
+
@defaults_enabled = block_given? ? block.call : value
|
21
20
|
end
|
22
21
|
|
23
|
-
def
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
22
|
+
def defaults_enabled?
|
23
|
+
@defaults_enabled.respond_to?(:call) ?
|
24
|
+
@defaults_enabled.call :
|
25
|
+
@defaults_enabled
|
28
26
|
end
|
29
27
|
|
30
28
|
def variable(name, type = :string, **options)
|
@@ -32,7 +30,7 @@ class ENVied
|
|
32
30
|
raise ArgumentError, "#{type.inspect} is not a supported type. Should be one of #{coercer.supported_types}"
|
33
31
|
end
|
34
32
|
options[:group] = current_group if current_group
|
35
|
-
variables << ENVied::Variable.new(name, type, options)
|
33
|
+
variables << ENVied::Variable.new(name, type, **options)
|
36
34
|
end
|
37
35
|
|
38
36
|
def group(*names, &block)
|
@@ -47,5 +45,15 @@ class ENVied
|
|
47
45
|
def variables
|
48
46
|
@variables ||= []
|
49
47
|
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def defaults_enabled_default
|
52
|
+
if ENV['ENVIED_ENABLE_DEFAULTS'].nil?
|
53
|
+
false
|
54
|
+
else
|
55
|
+
@coercer.coerce(ENV['ENVIED_ENABLE_DEFAULTS'], :boolean)
|
56
|
+
end
|
57
|
+
end
|
50
58
|
end
|
51
59
|
end
|
data/lib/envied/env_proxy.rb
CHANGED
@@ -28,10 +28,7 @@ class ENVied
|
|
28
28
|
|
29
29
|
def value_to_coerce(var)
|
30
30
|
return env_value_of(var) unless env_value_of(var).nil?
|
31
|
-
|
32
|
-
|
33
|
-
def variables
|
34
|
-
@variables ||= config.variables.select {|v| groups.include?(v.group) }
|
31
|
+
config.defaults_enabled? ? default_value_of(var) : nil
|
35
32
|
end
|
36
33
|
|
37
34
|
private
|
@@ -50,22 +47,22 @@ class ENVied
|
|
50
47
|
coercer.coercible?(value_to_coerce(var), var.type)
|
51
48
|
end
|
52
49
|
|
53
|
-
def
|
54
|
-
|
50
|
+
def default_value_of(var)
|
51
|
+
var.default_value(ENVied, var)
|
55
52
|
end
|
56
53
|
|
57
|
-
def
|
58
|
-
|
59
|
-
|
60
|
-
result = [base_key]
|
61
|
-
result.unshift "#{base_key}_#{key_alias}" if key_alias
|
62
|
-
result
|
54
|
+
def env_value_of(var)
|
55
|
+
ENV[var.name.to_s]
|
63
56
|
end
|
64
57
|
|
65
58
|
def missing?(var)
|
66
59
|
value_to_coerce(var).nil?
|
67
60
|
end
|
68
61
|
|
62
|
+
def variables
|
63
|
+
@variables ||= config.variables.select {|v| groups.include?(v.group) }
|
64
|
+
end
|
65
|
+
|
69
66
|
def variables_by_name
|
70
67
|
@variables_by_name ||= variables.map {|v| [v.name, v] }.to_h
|
71
68
|
end
|
data/lib/envied/variable.rb
CHANGED
@@ -1,14 +1,23 @@
|
|
1
1
|
class ENVied::Variable
|
2
|
-
attr_reader :name, :type, :group
|
2
|
+
attr_reader :name, :type, :group, :default
|
3
3
|
|
4
4
|
def initialize(name, type, **options)
|
5
5
|
@name = name.to_sym
|
6
6
|
@type = type.to_sym
|
7
7
|
@group = options.fetch(:group, :default).to_sym
|
8
|
+
@default = options[:default]
|
9
|
+
|
10
|
+
#if !@default.is_a? String
|
11
|
+
# raise ArgumentError, "Default values should be strings (variable #{@name})"
|
12
|
+
#end
|
13
|
+
end
|
14
|
+
|
15
|
+
def default_value(*args)
|
16
|
+
default.respond_to?(:call) ? default[*args] : default
|
8
17
|
end
|
9
18
|
|
10
19
|
def ==(other)
|
11
20
|
self.class == other.class &&
|
12
|
-
[name, type, group] == [other.name, other.type, other.group]
|
21
|
+
[name, type, group, default] == [other.name, other.type, other.group, other.default]
|
13
22
|
end
|
14
23
|
end
|
data/lib/envied/version.rb
CHANGED
data/lib/envied.rb
CHANGED
@@ -5,7 +5,6 @@ require 'envied/coercer'
|
|
5
5
|
require 'envied/coercer/envied_string'
|
6
6
|
require 'envied/variable'
|
7
7
|
require 'envied/configuration'
|
8
|
-
require 'envied/env_interceptor'
|
9
8
|
|
10
9
|
class ENVied
|
11
10
|
class << self
|
@@ -15,12 +14,10 @@ class ENVied
|
|
15
14
|
|
16
15
|
def self.require(*args, **options)
|
17
16
|
requested_groups = (args && !args.empty?) ? args : ENV['ENVIED_GROUPS']
|
18
|
-
env!(requested_groups, options)
|
19
|
-
|
20
|
-
|
21
|
-
error_on_uncoercible_variables!(options)
|
17
|
+
env!(requested_groups, **options)
|
18
|
+
error_on_missing_variables!(**options)
|
19
|
+
error_on_uncoercible_variables!(**options)
|
22
20
|
|
23
|
-
intercept_env_vars!
|
24
21
|
ensure_spring_after_fork_require(args, options)
|
25
22
|
end
|
26
23
|
|
@@ -29,20 +26,8 @@ class ENVied
|
|
29
26
|
@env = EnvProxy.new(@config, groups: required_groups(*requested_groups))
|
30
27
|
end
|
31
28
|
|
32
|
-
def self.error_on_duplicate_variables!(options)
|
33
|
-
var_types_by_name = env.variables.reduce({}) do |acc, v|
|
34
|
-
(acc[v.name] ||= []).push v.type
|
35
|
-
acc
|
36
|
-
end
|
37
|
-
dups = var_types_by_name.select {|name, types| types.uniq.count > 1 }
|
38
|
-
|
39
|
-
if dups.any?
|
40
|
-
raise "The following variables are defined more than once with different types: #{dups.keys.join(', ')}"
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
29
|
def self.error_on_missing_variables!(**options)
|
45
|
-
names = env.missing_variables.map(&:name)
|
30
|
+
names = env.missing_variables.map(&:name)
|
46
31
|
if names.any?
|
47
32
|
msg = "The following environment variables should be set: #{names.join(', ')}."
|
48
33
|
msg << "\nPlease make sure to stop Spring before retrying." if spring_enabled? && !options[:via_spring]
|
@@ -67,23 +52,9 @@ class ENVied
|
|
67
52
|
result.any? ? result.map(&:to_sym) : [:default]
|
68
53
|
end
|
69
54
|
|
70
|
-
def self.
|
71
|
-
env.variables.select{|v| v.type == :env }.map{|var| var.name.to_s }
|
72
|
-
end
|
73
|
-
|
74
|
-
def self.intercept_env_vars!
|
75
|
-
if (keys = env_keys_to_intercept).any?
|
76
|
-
ENV.instance_eval { @__envied_env_keys = keys }
|
77
|
-
class << ENV
|
78
|
-
prepend(ENVied::EnvInterceptor)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
private_class_method :intercept_env_vars!, :env_keys_to_intercept
|
83
|
-
|
84
|
-
def self.ensure_spring_after_fork_require(args, **options)
|
55
|
+
def self.ensure_spring_after_fork_require(args, options)
|
85
56
|
if spring_enabled? && !options[:via_spring]
|
86
|
-
Spring.after_fork { ENVied.require(args, options.merge(via_spring: true)) }
|
57
|
+
Spring.after_fork { ENVied.require(*args, **options.merge(via_spring: true)) }
|
87
58
|
end
|
88
59
|
end
|
89
60
|
|
@@ -112,5 +83,4 @@ class ENVied
|
|
112
83
|
def self.respond_to_missing?(method, include_private = false)
|
113
84
|
(env && env.has_key?(method)) || super
|
114
85
|
end
|
115
|
-
|
116
86
|
end
|