env_parser 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +48 -57
- data/Gemfile.lock +19 -1
- data/README.md +214 -125
- data/docs/EnvParser.html +214 -32
- data/docs/EnvParser/AutoregisterFileNotFound.html +144 -0
- data/docs/EnvParser/Error.html +2 -2
- data/docs/EnvParser/TypeAlreadyDefinedError.html +1 -1
- data/docs/EnvParser/Types.html +1 -1
- data/docs/EnvParser/Types/BaseTypes.html +1 -1
- data/docs/EnvParser/Types/ChronologyTypes.html +1 -1
- data/docs/EnvParser/Types/InternetTypes.html +1 -1
- data/docs/EnvParser/UnknownTypeError.html +1 -1
- data/docs/EnvParser/UnparseableAutoregisterSpec.html +144 -0
- data/docs/EnvParser/ValueNotAllowedError.html +1 -1
- data/docs/EnvParser/ValueNotConvertibleError.html +1 -1
- data/docs/_index.html +26 -1
- data/docs/class_list.html +1 -1
- data/docs/file.README.html +296 -169
- data/docs/index.html +296 -169
- data/docs/method_list.html +11 -3
- data/docs/top-level-namespace.html +1 -1
- data/env_parser.gemspec +2 -0
- data/lib/env_parser.rb +47 -3
- data/lib/env_parser/autoregister.rb +3 -0
- data/lib/env_parser/errors.rb +12 -0
- data/lib/env_parser/types/chronology_types.rb +1 -1
- data/lib/env_parser/types/internet_types.rb +2 -2
- data/lib/env_parser/version.rb +1 -1
- metadata +33 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c332d39f13b5bc1bb69de8ea62bf563201cf9424
|
4
|
+
data.tar.gz: 3f1318fa50244fedf66831472c70482acbfbe8a9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ded5ae799d4457095e940a2737e95fcc58177fbc574deadc02ddaaee5c52b32a8edfbaf3be2984aef994507f73a4abf4721ef32930e4178ef0fe0c9427ee9598
|
7
|
+
data.tar.gz: 8e2330caa387e8425e74453b73a0b7f45251ac60de85adba8f7fa39f58f2080fab9af51c900f30656b35dc937d77e5b68d8ca6f2086a42ba75a977b28f04aa16
|
data/.rubocop.yml
CHANGED
@@ -1,78 +1,69 @@
|
|
1
1
|
AllCops:
|
2
2
|
TargetRubyVersion: 2.4
|
3
3
|
Include:
|
4
|
+
- "**/*.rb"
|
4
5
|
- "**/*.rake"
|
5
6
|
- "**/Gemfile"
|
6
|
-
- "**/Rakefile"
|
7
|
-
- "**/Capfile"
|
8
|
-
- "**/Berksfile"
|
9
|
-
- "**/Cheffile"
|
10
7
|
Exclude:
|
11
|
-
- "
|
12
|
-
- "db/**/*"
|
8
|
+
- ".git/**/*"
|
13
9
|
- "tmp/**/*"
|
14
10
|
- "true/**/*"
|
15
|
-
|
16
|
-
|
11
|
+
- "vendor/**/*"
|
12
|
+
|
13
|
+
|
14
|
+
Layout/EmptyLineAfterGuardClause:
|
15
|
+
# Add empty line after guard clause.
|
17
16
|
Enabled: false
|
18
|
-
|
19
|
-
|
20
|
-
Metrics/
|
21
|
-
|
17
|
+
|
18
|
+
|
19
|
+
Metrics/AbcSize:
|
20
|
+
# A calculated magnitude based on number of assignments, branches, and conditions.
|
22
21
|
Enabled: false
|
23
|
-
|
22
|
+
|
24
23
|
Metrics/BlockLength:
|
24
|
+
# Avoid long blocks with many lines.
|
25
25
|
Exclude:
|
26
26
|
- 'spec/**/*.rb'
|
27
|
-
|
28
|
-
Description: Avoid methods longer than 10 lines of code.
|
29
|
-
StyleGuide: https://github.com/bbatsov/ruby-style-guide#short-methods
|
30
|
-
Enabled: false
|
31
|
-
CountComments: false
|
32
|
-
Max: 10
|
33
|
-
Metrics/AbcSize:
|
34
|
-
Description: A calculated magnitude based on number of assignments, branches, and conditions.
|
35
|
-
Enabled: false
|
36
|
-
Max: 15
|
27
|
+
|
37
28
|
Metrics/CyclomaticComplexity:
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
EnforcedStyle: percent_r
|
29
|
+
# A complexity metric that is strongly correlated to the number of test cases needed to validate a method.
|
30
|
+
Max: 10
|
31
|
+
|
32
|
+
Metrics/LineLength:
|
33
|
+
# Limit lines to 100 characters.
|
34
|
+
Max: 100
|
35
|
+
Exclude:
|
36
|
+
- 'spec/**/*.rb'
|
37
|
+
|
38
|
+
Metrics/MethodLength:
|
39
|
+
# Avoid methods longer than 25 lines of code.
|
40
|
+
Max: 25
|
41
|
+
|
42
|
+
|
53
43
|
Style/AsciiComments:
|
54
|
-
#
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
Description: This cop checks for big numeric literals without _ between groups of digits in them.
|
59
|
-
Enabled: false
|
60
|
-
Style/Documentation:
|
61
|
-
Description: Document classes and non-namespace modules.
|
44
|
+
# This cop checks for non-ascii (non-English) characters in comments.
|
45
|
+
#
|
46
|
+
# NLC: Disabling this so we can use non-breaking spaces (' ') in documentation comments, preventing browsers from collapsing
|
47
|
+
# multiple spaces in code blocks.
|
62
48
|
Enabled: false
|
49
|
+
|
50
|
+
Style/BlockDelimiters:
|
51
|
+
# Check for uses of braces or do/end around single line or multi-line blocks.
|
52
|
+
Exclude:
|
53
|
+
- 'spec/**/*.rb'
|
54
|
+
|
63
55
|
Style/ClassAndModuleChildren:
|
64
|
-
|
56
|
+
# Use nested modules/class definitions instead of compact style.
|
65
57
|
Enabled: false
|
58
|
+
|
66
59
|
Style/FrozenStringLiteralComment:
|
60
|
+
# Add the frozen_string_literal comment to the top of files to help transition to frozen string literals by default.
|
67
61
|
Enabled: false
|
68
|
-
|
62
|
+
|
63
|
+
Style/NumericLiterals:
|
64
|
+
# his cop checks for big numeric literals without _ between groups of digits in them.
|
69
65
|
Enabled: false
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
Style/BlockDelimiters:
|
75
|
-
Description: Check for uses of braces or do/end around single line or multi-line blocks.
|
76
|
-
Enabled: true
|
77
|
-
Exclude:
|
78
|
-
- 'spec/**/*.rb'
|
66
|
+
|
67
|
+
Style/RegexpLiteral:
|
68
|
+
# Enforces using / or %r around regular expressions.
|
69
|
+
EnforcedStyle: percent_r
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
env_parser (1.
|
4
|
+
env_parser (1.3.0)
|
5
5
|
activesupport (>= 5.0.0)
|
6
6
|
chronic
|
7
7
|
chronic_duration
|
@@ -14,6 +14,7 @@ GEM
|
|
14
14
|
i18n (>= 0.7, < 2)
|
15
15
|
minitest (~> 5.1)
|
16
16
|
tzinfo (~> 1.1)
|
17
|
+
ast (2.4.0)
|
17
18
|
chronic (0.10.2)
|
18
19
|
chronic_duration (0.10.6)
|
19
20
|
numerizer (~> 0.1.1)
|
@@ -21,8 +22,13 @@ GEM
|
|
21
22
|
diff-lcs (1.3)
|
22
23
|
i18n (1.7.0)
|
23
24
|
concurrent-ruby (~> 1.0)
|
25
|
+
jaro_winkler (1.5.3)
|
24
26
|
minitest (5.12.2)
|
25
27
|
numerizer (0.1.1)
|
28
|
+
parallel (1.18.0)
|
29
|
+
parser (2.6.5.0)
|
30
|
+
ast (~> 2.4.0)
|
31
|
+
rainbow (3.0.0)
|
26
32
|
rake (10.5.0)
|
27
33
|
rspec (3.7.0)
|
28
34
|
rspec-core (~> 3.7.0)
|
@@ -39,9 +45,19 @@ GEM
|
|
39
45
|
rspec-support (3.7.0)
|
40
46
|
rspec_junit_formatter (0.3.0)
|
41
47
|
rspec-core (>= 2, < 4, != 2.12.0)
|
48
|
+
rubocop (0.75.1)
|
49
|
+
jaro_winkler (~> 1.5.1)
|
50
|
+
parallel (~> 1.10)
|
51
|
+
parser (>= 2.6)
|
52
|
+
rainbow (>= 2.2.2, < 4.0)
|
53
|
+
ruby-progressbar (~> 1.7)
|
54
|
+
unicode-display_width (>= 1.4.0, < 1.7)
|
55
|
+
ruby-progressbar (1.10.1)
|
42
56
|
thread_safe (0.3.6)
|
43
57
|
tzinfo (1.2.5)
|
44
58
|
thread_safe (~> 0.1)
|
59
|
+
unicode-display_width (1.6.0)
|
60
|
+
yard (0.9.20)
|
45
61
|
|
46
62
|
PLATFORMS
|
47
63
|
ruby
|
@@ -52,6 +68,8 @@ DEPENDENCIES
|
|
52
68
|
rake (~> 10.0)
|
53
69
|
rspec (~> 3.0)
|
54
70
|
rspec_junit_formatter
|
71
|
+
rubocop
|
72
|
+
yard
|
55
73
|
|
56
74
|
BUNDLED WITH
|
57
75
|
1.16.0
|
data/README.md
CHANGED
@@ -1,227 +1,316 @@
|
|
1
|
-
|
1
|
+
[![Gem Version](https://img.shields.io/github/v/release/nestor-custodio/env_parser?color=green&label=gem%20version)](https://rubygems.org/gems/env_parser)
|
2
|
+
[![MIT License](https://img.shields.io/github/license/nestor-custodio/env_parser)](https://github.com/nestor-custodio/env_parser/blob/master/LICENSE.txt)
|
3
|
+
|
4
|
+
|
5
|
+
# EnvParser
|
2
6
|
|
3
7
|
If your code uses environment variables, you know that `ENV` will always surface these as strings. Interpreting these strings as the value you *actually* want to see/use takes some work, however: for numbers you need to cast with `to_i` or `to_f` ... for booleans you need to check for a specific value (`ENV['SOME_VAR'] == 'true'`) ... maybe you want to set non-trivial defaults (something other than `0` or `''`)? ... maybe you only want to allow values from a limited set? ...
|
4
8
|
|
5
|
-
Things can get out of control pretty fast, especially as the number of environment variables in play grows. Tools like [dotenv](https://github.com/bkeepers/dotenv) help to make sure you're loading the correct **set** of variables, but [EnvParser](https://github.com/nestor-custodio/env_parser) makes
|
9
|
+
Things can get out of control pretty fast, especially as the number of environment variables in play grows. Tools like [dotenv](https://github.com/bkeepers/dotenv) help to make sure you're loading the correct **set** of variables, but [EnvParser](https://github.com/nestor-custodio/env_parser) makes **the values themselves** usable with a minimum of effort.
|
10
|
+
|
11
|
+
[Full documentation is available here](http://nestor-custodio.github.io/env_parser/EnvParser.html), but do read below for a crash course on availble featues!
|
6
12
|
|
7
13
|
|
8
14
|
## Installation
|
9
15
|
|
10
|
-
|
16
|
+
- If your project uses [Bundler](https://github.com/bundler/bundler):
|
17
|
+
- Add one of the following to your application's Gemfile:
|
18
|
+
```ruby
|
19
|
+
## For on-demand usage ...
|
20
|
+
##
|
21
|
+
gem 'env_parser'
|
11
22
|
|
12
|
-
|
13
|
-
|
14
|
-
|
23
|
+
## To automatically register ENV
|
24
|
+
## constants per ".env_parser.yml" ...
|
25
|
+
##
|
26
|
+
gem 'env_parser', require: 'env_parser/autoregister'
|
27
|
+
```
|
28
|
+
- And then run a:
|
29
|
+
```shell
|
30
|
+
$ bundle install
|
31
|
+
```
|
15
32
|
|
16
|
-
|
33
|
+
- Or, you can keep things simple with a manual install:
|
34
|
+
```shell
|
35
|
+
$ gem install env_parser
|
36
|
+
```
|
17
37
|
|
18
|
-
$ bundle
|
19
38
|
|
20
|
-
|
39
|
+
## Syntax Cheat Sheet
|
21
40
|
|
22
|
-
|
41
|
+
```ruby
|
42
|
+
## Returns an ENV value parsed "as" a specific type:
|
43
|
+
##
|
44
|
+
EnvParser.parse env_key_as_a_symbol
|
45
|
+
as: … ## ➜ required
|
46
|
+
if_unset: … ## ➜ optional; default value
|
47
|
+
from_set: … ## ➜ optional; an Array or Range
|
48
|
+
validated_by: ->(value) { … } ## ➜ optional; may also be given as a block
|
49
|
+
|
50
|
+
## Parse an ENV value and register it as a constant:
|
51
|
+
##
|
52
|
+
EnvParser.register env_key_as_a_symbol
|
53
|
+
as: … ## ➜ required
|
54
|
+
within: … ## ➜ optional; Class or Module
|
55
|
+
if_unset: … ## ➜ optional; default value
|
56
|
+
from_set: … ## ➜ optional; an Array or Range
|
57
|
+
validated_by: ->(value) { … } ## ➜ optional; may also be given as a block
|
58
|
+
|
59
|
+
## Registers all ENV variables as spec'ed in ".env_parser.yml":
|
60
|
+
##
|
61
|
+
EnvParser.autoregister ## Note this is automatically called if your
|
62
|
+
## Gemfile included the "env_parser" gem with
|
63
|
+
## the "require: 'env_parser/autoregister'" option.
|
64
|
+
|
65
|
+
## Lets you call "parse" and "register" on ENV itself:
|
66
|
+
##
|
67
|
+
EnvParser.add_env_bindings ## ENV.parse will now be a proxy for EnvParser.parse
|
68
|
+
## and ENV.register will now be a proxy for EnvParser.register
|
69
|
+
```
|
23
70
|
|
24
71
|
|
25
|
-
##
|
72
|
+
## Extended How-To-Use
|
26
73
|
|
27
|
-
|
74
|
+
#### Basic Usage
|
28
75
|
|
29
|
-
|
76
|
+
- **Parsing `ENV` Values**
|
30
77
|
|
31
|
-
|
32
|
-
## Returns ENV['TIMEOUT_MS'] as an Integer,
|
33
|
-
## or 0 if ENV['TIMEOUT_MS'] is unset or nil.
|
78
|
+
At its core, EnvParser is a straight-forward parser for string values (since that's all `ENV` ever gives you), allowing you to read a given string **_as_** a variety of types.
|
34
79
|
|
35
|
-
|
80
|
+
```ruby
|
81
|
+
## Returns ENV['TIMEOUT_MS'] as an Integer,
|
82
|
+
## or a sensible default (0) if ENV['TIMEOUT_MS'] is unset.
|
83
|
+
##
|
84
|
+
timeout_ms = EnvParser.parse ENV['TIMEOUT_MS'], as: :integer
|
85
|
+
```
|
36
86
|
|
87
|
+
You can check the full documentation for [a list of all **_as_** types available right out of the box](http://nestor-custodio.github.io/env_parser/EnvParser/Types.html).
|
37
88
|
|
38
|
-
|
39
|
-
## If you pass in a Symbol instead of a String, EnvParser
|
40
|
-
## will use the value behind the matching String key in ENV.
|
41
|
-
## (i.e. passing in ENV['X'] is equivalent to passing in :X)
|
89
|
+
- **How About Less Typing?**
|
42
90
|
|
43
|
-
|
44
|
-
```
|
91
|
+
EnvParser is all about ~~simplification~~ ~~less typing~~ *laziness*. If you pass in a symbol instead of a string, EnvParser will look to `ENV` and use the value from the corresponding (string) key.
|
45
92
|
|
46
|
-
|
93
|
+
```ruby
|
94
|
+
## YAY, LESS TYPING! 😃
|
95
|
+
## These two are the same:
|
96
|
+
##
|
97
|
+
more_typing = EnvParser.parse ENV['TIMEOUT_MS'], as: :integer
|
98
|
+
less_typing = EnvParser.parse :TIMEOUT_MS, as: :integer
|
99
|
+
```
|
47
100
|
|
48
|
-
|
101
|
+
- **Registering Constants From `ENV` Values**
|
49
102
|
|
50
|
-
|
103
|
+
The `EnvParser.register` method lets you "promote" `ENV` variables into their own constants, already parsed into the correct type.
|
51
104
|
|
52
|
-
```ruby
|
53
|
-
##
|
54
|
-
## the return value is a sensible default for the given "as" type
|
55
|
-
## (0 or 0.0 for numbers, an empty tring, an empty Array or Hash, etc).
|
56
|
-
## Sometimes you want a non-trivial default, however.
|
105
|
+
```ruby
|
106
|
+
ENV['API_KEY'] ## => 'unbreakable p4$$w0rd'
|
57
107
|
|
58
|
-
EnvParser.
|
59
|
-
|
108
|
+
EnvParser.register :API_KEY, as: :string
|
109
|
+
API_KEY ## => 'unbreakable p4$$w0rd'
|
110
|
+
```
|
60
111
|
|
112
|
+
By default, `EnvParser.register` will create the requested constant within the Kernel module (making it available everywhere), but you can specify any class or module you like.
|
61
113
|
|
62
|
-
|
114
|
+
```ruby
|
115
|
+
ENV['BEST_VIDEO'] ## => 'https://youtu.be/L_jWHffIx5E'
|
63
116
|
|
64
|
-
EnvParser.
|
65
|
-
|
117
|
+
EnvParser.register :BEST_VIDEO, as: :string, within: URI
|
118
|
+
URI::BEST_VIDEO ## => 'https://youtu.be/L_jWHffIx5E'
|
119
|
+
BEST_VIDEO ## => raises NameError
|
120
|
+
```
|
66
121
|
|
67
|
-
|
122
|
+
You can also register multiple constants with a single call, which is a bit cleaner.
|
68
123
|
|
69
|
-
|
124
|
+
```ruby
|
125
|
+
EnvParser.register :USERNAME, as: :string
|
126
|
+
EnvParser.register :PASSWORD, as: :string
|
127
|
+
EnvParser.register :MOCK_API, as: :boolean, within: MyClassOrModule }
|
70
128
|
|
71
|
-
|
72
|
-
## Global constants...
|
129
|
+
## ... is equivalent to ... ##
|
73
130
|
|
74
|
-
|
131
|
+
EnvParser.register USERNAME: { as: :string },
|
132
|
+
PASSWORD: { as: :string },
|
133
|
+
MOCK_API: { as: :boolean, within: MyClassOrModule }
|
134
|
+
```
|
75
135
|
|
76
|
-
|
77
|
-
API_KEY ## => 'unbreakable p4$$w0rd' (registered within the Kernel module, so it's available everywhere)
|
136
|
+
- **Okay, But... How About Even Less Typing?**
|
78
137
|
|
138
|
+
Calling `EnvParser.add_env_bindings` binds proxy `parse` and `register` methods onto `ENV`. With these bindings in place, you can call `parse` or `register` on `ENV` itself, which is more legible and feels more straight-forward.
|
79
139
|
|
80
|
-
|
140
|
+
```ruby
|
141
|
+
ENV['SHORT_PI'] ## => '3.1415926'
|
142
|
+
ENV['BETTER_PI'] ## => '["flaky crust", "strawberry filling"]'
|
81
143
|
|
82
|
-
|
144
|
+
## Bind the proxy methods.
|
145
|
+
##
|
146
|
+
EnvParser.add_env_bindings
|
83
147
|
|
84
|
-
|
85
|
-
|
148
|
+
ENV.parse :SHORT_PI, as: :float ## => 3.1415926
|
149
|
+
ENV.register :BETTER_PI, as: :array ## Your constant is set!
|
150
|
+
```
|
86
151
|
|
87
|
-
|
152
|
+
Note that the proxy `ENV.parse` method will (naturally) *always* interpret the value given as an `ENV` key (converting it to a string, if necessary), which is slightly different from the original `EnvParser.parse` method.
|
88
153
|
|
154
|
+
```ruby
|
155
|
+
ENV['SHORT_PI'] ## => '3.1415926'
|
89
156
|
|
157
|
+
EnvParser.parse 'SHORT_PI', as: :float ## => 'SHORT_PI' as a float: 0.0
|
158
|
+
EnvParser.parse :SHORT_PI , as: :float ## => ENV['SHORT_PI'] as a float: 3.1415926
|
90
159
|
|
160
|
+
## Bind the proxy methods.
|
161
|
+
##
|
162
|
+
EnvParser.add_env_bindings
|
91
163
|
|
92
|
-
|
164
|
+
ENV.parse 'SHORT_PI', as: :float ## => ENV['SHORT_PI'] as a float: 3.1415926
|
165
|
+
ENV.parse :SHORT_PI , as: :float ## => ENV['SHORT_PI'] as a float: 3.1415926
|
166
|
+
```
|
93
167
|
|
94
|
-
|
95
|
-
EnvParser.register :B, as: :integer, if_unset: 25
|
96
|
-
EnvParser.register :C, as: :boolean, if_unset: true
|
168
|
+
Note also that the `ENV.parse` and `ENV.register` binding is done safely and without polluting the method space for other objects.
|
97
169
|
|
170
|
+
**All additional examples below will assume that `ENV` bindings are already in place, for brevity's sake.**
|
98
171
|
|
99
|
-
## ... is equivalent to ...
|
100
172
|
|
101
|
-
|
102
|
-
A: { as: :string },
|
103
|
-
B: { as: :integer, if_unset: 25 },
|
104
|
-
C: { as: :boolean, if_unset: true }
|
105
|
-
)
|
106
|
-
```
|
173
|
+
#### Ensuring Usable Values
|
107
174
|
|
108
|
-
|
175
|
+
- **Sensible Defaults**
|
109
176
|
|
110
|
-
|
177
|
+
If the `ENV` variable you want is unset (`nil`) or blank (`''`), the return value is a sensible default for the given **_as_** type: 0 or 0.0 for numbers, an empty string/array/hash, etc. Sometimes you want a non-trivial default, however. The **_if_unset_** option lets you specify a default that better meets your needs.
|
111
178
|
|
112
|
-
```ruby
|
113
|
-
|
114
|
-
|
179
|
+
```ruby
|
180
|
+
ENV.parse :MISSING_VAR, as: :integer ## => 0
|
181
|
+
ENV.parse :MISSING_VAR, as: :integer, if_unset: 250 ## => 250
|
182
|
+
```
|
115
183
|
|
116
|
-
|
184
|
+
Note these default values are used as-is with no type conversion, so exercise caution.
|
117
185
|
|
186
|
+
```ruby
|
187
|
+
ENV.parse :MISSING_VAR, as: :integer, if_unset: 'Careful!' ## => 'Careful!' (NOT AN INTEGER)
|
188
|
+
```
|
118
189
|
|
119
|
-
|
120
|
-
## which is more legible and feels more straight-forward.
|
190
|
+
- **Selecting From A Set**
|
121
191
|
|
122
|
-
|
192
|
+
Sometimes setting the **_as_** type is a bit too open-ended. The **_from_set_** option lets you restrict the domain of allowed values.
|
123
193
|
|
124
|
-
|
125
|
-
ENV.
|
194
|
+
```ruby
|
195
|
+
ENV.parse :API_TO_USE, as: :symbol, from_set: %i[internal external]
|
196
|
+
ENV.parse :NETWORK_PORT, as: :integer, from_set: (1..65535), if_unset: 80
|
126
197
|
|
198
|
+
## And if the value is not in the allowed set ...
|
199
|
+
##
|
200
|
+
ENV.parse :TWELVE, as: :integer, from_set: (1..5) ## => raises EnvParser::ValueNotAllowedError
|
201
|
+
```
|
127
202
|
|
128
|
-
|
129
|
-
## value given as an ENV key (converting to a String, if necessary).
|
130
|
-
## This is different from the non-proxy "parse" method, which will use
|
131
|
-
## String values as-is and only looks up ENV values when given a Symbol.
|
132
|
-
```
|
203
|
+
- **Custom Validation Of Parsed Values**
|
133
204
|
|
205
|
+
You can write your own, more complex validations by passing in a **_validated_by_** lambda or an equivalent block. The lambda/block should take one value and return true if the given value passes the custom validation.
|
134
206
|
|
135
|
-
|
207
|
+
```ruby
|
208
|
+
## Via a "validated_by" lambda ...
|
209
|
+
##
|
210
|
+
ENV.parse :MUST_BE_LOWERCASE, as: :string, validated_by: ->(value) { value == value.downcase }
|
136
211
|
|
137
|
-
|
212
|
+
## ... or with a block!
|
213
|
+
##
|
214
|
+
ENV.parse(:MUST_BE_LOWERCASE, as: :string) { |value| value == value.downcase }
|
215
|
+
ENV.parse(:CONNECTION_RETRIES, as: :integer, &:positive?)
|
216
|
+
```
|
138
217
|
|
139
|
-
|
140
|
-
## Sometimes setting the type alone is a bit too open-ended.
|
141
|
-
## The "from_set" option lets you restrict the set of allowed values.
|
218
|
+
- **Defining Your Own EnvParser "*as*" Types**
|
142
219
|
|
143
|
-
EnvParser.parse
|
144
|
-
EnvParser.parse :SOME_CUSTOM_NETWORK_PORT, as: :integer, from_set: (1..65535), if_unset: 80
|
220
|
+
If you use a particular validation many times or are often manipulating values in the same way after EnvParser has done its thing, you may want to register a new type altogether. Defining a new type makes your code both more maintainable (all the logic for your special type is only defined once) and more readable (your `parse` calls aren't littered with type-checking cruft).
|
145
221
|
|
222
|
+
Something as repetitive as:
|
146
223
|
|
147
|
-
|
224
|
+
```ruby
|
225
|
+
a = ENV.parse :A, as: :int, if_unset: 6
|
226
|
+
raise unless passes_all_my_checks?(a)
|
148
227
|
|
149
|
-
|
228
|
+
b = ENV.parse :B, as: :int, if_unset: 6
|
229
|
+
raise unless passes_all_my_checks?(b)
|
230
|
+
```
|
150
231
|
|
232
|
+
... is perhaps best handled by defining a new type:
|
151
233
|
|
234
|
+
```ruby
|
235
|
+
EnvParser.define_type(:my_special_type_of_number, if_unset: 6) do |value|
|
236
|
+
value = value.to_i
|
237
|
+
unless passes_all_my_checks?(value)
|
238
|
+
raise(EnvParser::ValueNotConvertibleError, 'cannot parse as a "special type number"')
|
239
|
+
end
|
152
240
|
|
241
|
+
value
|
242
|
+
end
|
153
243
|
|
154
|
-
|
244
|
+
a = ENV.parse :A, as: :my_special_type_of_number
|
245
|
+
b = ENV.parse :B, as: :my_special_type_of_number
|
246
|
+
```
|
155
247
|
|
156
|
-
EnvParser.parse :MUST_BE_LOWERCASE, as: :string, validated_by: ->(value) { value == value.downcase }
|
157
248
|
|
249
|
+
#### Auto-Registering Constants
|
158
250
|
|
159
|
-
|
251
|
+
- **The `autoregister` Call**
|
160
252
|
|
161
|
-
EnvParser.
|
162
|
-
EnvParser.parse(:CONNECTION_RETRIES, as: :integer, &:positive?)
|
163
|
-
```
|
253
|
+
Consolidating all of your `EnvParser.register` calls into a single place only makes sense. A single `EnvParser.autoregister` call take a filename to read and process as a series of constant registration requests. If no filename is given, the default `".env_parser.yml"` is assumed.
|
164
254
|
|
165
|
-
|
255
|
+
You'll normally want to call `EnvParser.autoregister` as early in your application as possible. For Rails applications (and other frameworks that call `require 'bundler/setup'`), requiring the EnvParser gem via ...
|
166
256
|
|
167
|
-
|
257
|
+
```ruby
|
258
|
+
gem 'env_parser', require: 'env_parser/autoregister'
|
259
|
+
```
|
168
260
|
|
169
|
-
|
170
|
-
## If you use a particular validation many times,
|
171
|
-
## or are often manipulating values in the same way
|
172
|
-
## after EnvParser has done its thing, you may want
|
173
|
-
## to register a new type altogether.
|
261
|
+
... will automatically make the autoregistration call for you as soon as the gem is loaded (which should be early enough for most uses). If this is *still* not early enough for your needs, you can always `require 'env_parser/autoregister'` yourself even before `bundler/setup` is invoked.
|
174
262
|
|
175
|
-
|
176
|
-
raise unless passes_all_my_checks?(a)
|
263
|
+
- **The ".env_parser.yml" File**
|
177
264
|
|
178
|
-
|
179
|
-
raise unless passes_all_my_checks?(b)
|
265
|
+
If you recall, multiple constants can be registered via a single `EnvParser.register` call:
|
180
266
|
|
267
|
+
```ruby
|
268
|
+
EnvParser.register :USERNAME, as: :string
|
269
|
+
EnvParser.register :PASSWORD, as: :string
|
270
|
+
EnvParser.register :MOCK_API, as: :boolean, within: MyClassOrModule }
|
181
271
|
|
182
|
-
## ... is
|
272
|
+
## ... is equivalent to ... ##
|
183
273
|
|
184
|
-
EnvParser.
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
end
|
274
|
+
EnvParser.register USERNAME: { as: :string },
|
275
|
+
PASSWORD: { as: :string },
|
276
|
+
MOCK_API: { as: :boolean, within: MyClassOrModule }
|
277
|
+
```
|
189
278
|
|
190
|
-
value
|
191
|
-
end
|
279
|
+
The autoregistraton file is intended to read as a YAML version of what you'd pass to the single-call version of `EnvParser.register`: a single hash with keys for each of the constants you'd like to register, with each value being the set of options to parse that constant.
|
192
280
|
|
193
|
-
|
194
|
-
b = EnvParser.parse :B, as: :my_special_type_of_number
|
281
|
+
The equivalent autoregistration file for the above would be:
|
195
282
|
|
283
|
+
```yaml
|
284
|
+
USERNAME:
|
285
|
+
as: :string
|
196
286
|
|
197
|
-
|
198
|
-
|
199
|
-
## and more readable (your "parse" calls aren't littered with
|
200
|
-
## type-checking cruft).
|
201
|
-
```
|
287
|
+
PASSWORD:
|
288
|
+
as: :string
|
202
289
|
|
203
|
-
|
290
|
+
MOCK_API:
|
291
|
+
as: :boolean
|
292
|
+
within: MyClassOrModule
|
293
|
+
```
|
204
294
|
|
205
|
-
|
295
|
+
Because no Ruby *statements* can be safely represented via YAML, the set of `EnvParser.register` options available via autoregistration is limited to **_as_**, **_within_**, **_if_unset_**, and **_from_set_**. As an additional restriction, **_from_set_** (if given) must be an array, as ranges cannot be represented in YAML.
|
206
296
|
|
207
297
|
|
208
298
|
## Feature Roadmap / Future Development
|
209
299
|
|
210
|
-
Additional features
|
300
|
+
Additional features coming in the future:
|
211
301
|
|
212
|
-
-
|
213
|
-
- Continue to round out the "as" type selection as ideas come to mind, suggestions are made, and pull requests are submitted.
|
302
|
+
- Continue to round out the **_as_** type selection as ideas come to mind, suggestions are made, and pull requests are submitted.
|
214
303
|
|
215
304
|
|
216
305
|
## Contribution / Development
|
217
306
|
|
218
|
-
Bug reports and pull requests are welcome
|
307
|
+
Bug reports and pull requests are welcome at: [https://github.com/nestor-custodio/env_parser](https://github.com/nestor-custodio/env_parser)
|
219
308
|
|
220
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `
|
309
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
221
310
|
|
222
|
-
Linting is courtesy of [Rubocop](https://
|
311
|
+
Linting is courtesy of [Rubocop](https://docs.rubocop.org/) (`bundle exec rubocop`) and documentation is built using [Yard](https://yardoc.org/) (`bundle exec yard`). Please ensure you have a clean bill of health from Rubocop and that any new features and/or changes to behaviour are reflected in the documentation before submitting a pull request.
|
223
312
|
|
224
313
|
|
225
314
|
## License
|
226
315
|
|
227
|
-
|
316
|
+
EnvParser is available as open source under the terms of the [MIT License](https://tldrlegal.com/license/mit-license).
|