env_parser 1.2.0 → 1.3.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/.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
|
+
[](https://rubygems.org/gems/env_parser)
|
2
|
+
[](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).
|