env_parser 1.3.3 → 1.6.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/Gemfile.lock +1 -1
- data/README.md +65 -65
- data/docs/EnvParser/AutoregisterFileNotFound.html +1 -1
- data/docs/EnvParser/Error.html +1 -1
- data/docs/EnvParser/TypeAlreadyDefinedError.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/Types.html +1 -1
- data/docs/EnvParser/UnknownTypeError.html +1 -1
- data/docs/EnvParser/UnparseableAutoregisterSpec.html +1 -1
- data/docs/EnvParser/ValueNotAllowedError.html +1 -1
- data/docs/EnvParser/ValueNotConvertibleError.html +1 -1
- data/docs/EnvParser.html +7 -2
- data/docs/_index.html +1 -1
- data/docs/file.README.html +1 -1
- data/docs/index.html +1 -1
- data/docs/top-level-namespace.html +1 -1
- data/lib/env_parser/types/internet_types.rb +22 -0
- data/lib/env_parser/version.rb +1 -1
- data/lib/env_parser.rb +20 -4
- data/spec/env_parser/types/internet_types_spec.rb +50 -0
- data/spec/env_parser_spec.rb +25 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4106f96ced2bcf4948b4547012b017e8632bf43450e86d9639eaf54aa9802ffb
|
4
|
+
data.tar.gz: c6e54495905a39126f320226a118b6c83405860a8ec502e7711e28ed9ad57de9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2fb35a0bee0ec626b5c070e426cd5214ce42e9be4eef861ce922c9ee0366c75dbddfcf9b352ca5c5d5806cd0e35ed25575181e35babf56b4b748260133215d46
|
7
|
+
data.tar.gz: ddc6daa85de95c97f2a914f8ff563c9e6fd128f14ca8566a2af153458a6d782fe73831b60d34b503e7beee00285d069354a216ef5b1b261a5a4072d5fa7930ed
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -16,13 +16,13 @@ Things can get out of control pretty fast, especially as the number of environme
|
|
16
16
|
- If your project uses [Bundler](https://github.com/bundler/bundler):
|
17
17
|
- Add one of the following to your application's Gemfile:
|
18
18
|
```ruby
|
19
|
-
|
20
|
-
|
19
|
+
# For on-demand usage ...
|
20
|
+
#
|
21
21
|
gem 'env_parser'
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
23
|
+
# To automatically register ENV
|
24
|
+
# constants per ".env_parser.yml" ...
|
25
|
+
#
|
26
26
|
gem 'env_parser', require: 'env_parser/autoregister'
|
27
27
|
```
|
28
28
|
- And then run a:
|
@@ -39,33 +39,33 @@ Things can get out of control pretty fast, especially as the number of environme
|
|
39
39
|
## Syntax Cheat Sheet
|
40
40
|
|
41
41
|
```ruby
|
42
|
-
|
43
|
-
|
42
|
+
# Returns an ENV value parsed "as" a specific type:
|
43
|
+
#
|
44
44
|
EnvParser.parse env_key_as_a_symbol
|
45
|
-
as: …
|
46
|
-
if_unset: …
|
47
|
-
from_set: …
|
48
|
-
validated_by: ->(value) { … }
|
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
49
|
|
50
|
-
|
51
|
-
|
50
|
+
# Parse an ENV value and register it as a constant:
|
51
|
+
#
|
52
52
|
EnvParser.register env_key_as_a_symbol
|
53
|
-
as: …
|
54
|
-
within: …
|
55
|
-
if_unset: …
|
56
|
-
from_set: …
|
57
|
-
validated_by: ->(value) { … }
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
EnvParser.autoregister
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
EnvParser.add_env_bindings
|
68
|
-
|
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
69
|
```
|
70
70
|
|
71
71
|
|
@@ -78,9 +78,9 @@ EnvParser.add_env_bindings ## ENV.parse will now be a proxy for EnvParser.parse
|
|
78
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.
|
79
79
|
|
80
80
|
```ruby
|
81
|
-
|
82
|
-
|
83
|
-
|
81
|
+
# Returns ENV['TIMEOUT_MS'] as an Integer,
|
82
|
+
# or a sensible default (0) if ENV['TIMEOUT_MS'] is unset.
|
83
|
+
#
|
84
84
|
timeout_ms = EnvParser.parse ENV['TIMEOUT_MS'], as: :integer
|
85
85
|
```
|
86
86
|
|
@@ -91,9 +91,9 @@ EnvParser.add_env_bindings ## ENV.parse will now be a proxy for EnvParser.parse
|
|
91
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.
|
92
92
|
|
93
93
|
```ruby
|
94
|
-
|
95
|
-
|
96
|
-
|
94
|
+
# YAY, LESS TYPING! 😃
|
95
|
+
# These two are the same:
|
96
|
+
#
|
97
97
|
more_typing = EnvParser.parse ENV['TIMEOUT_MS'], as: :integer
|
98
98
|
less_typing = EnvParser.parse :TIMEOUT_MS, as: :integer
|
99
99
|
```
|
@@ -103,20 +103,20 @@ EnvParser.add_env_bindings ## ENV.parse will now be a proxy for EnvParser.parse
|
|
103
103
|
The `EnvParser.register` method lets you "promote" `ENV` variables into their own constants, already parsed into the correct type.
|
104
104
|
|
105
105
|
```ruby
|
106
|
-
ENV['API_KEY']
|
106
|
+
ENV['API_KEY'] # => 'unbreakable p4$$w0rd'
|
107
107
|
|
108
108
|
EnvParser.register :API_KEY, as: :string
|
109
|
-
API_KEY
|
109
|
+
API_KEY # => 'unbreakable p4$$w0rd'
|
110
110
|
```
|
111
111
|
|
112
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.
|
113
113
|
|
114
114
|
```ruby
|
115
|
-
ENV['BEST_VIDEO']
|
115
|
+
ENV['BEST_VIDEO'] # => 'https://youtu.be/L_jWHffIx5E'
|
116
116
|
|
117
117
|
EnvParser.register :BEST_VIDEO, as: :string, within: URI
|
118
|
-
URI::BEST_VIDEO
|
119
|
-
BEST_VIDEO
|
118
|
+
URI::BEST_VIDEO # => 'https://youtu.be/L_jWHffIx5E'
|
119
|
+
BEST_VIDEO # => raises NameError
|
120
120
|
```
|
121
121
|
|
122
122
|
You can also register multiple constants with a single call, which is a bit cleaner.
|
@@ -126,7 +126,7 @@ EnvParser.add_env_bindings ## ENV.parse will now be a proxy for EnvParser.parse
|
|
126
126
|
EnvParser.register :PASSWORD, as: :string
|
127
127
|
EnvParser.register :MOCK_API, as: :boolean, within: MyClassOrModule }
|
128
128
|
|
129
|
-
|
129
|
+
# ... is equivalent to ... #
|
130
130
|
|
131
131
|
EnvParser.register USERNAME: { as: :string },
|
132
132
|
PASSWORD: { as: :string },
|
@@ -138,31 +138,31 @@ EnvParser.add_env_bindings ## ENV.parse will now be a proxy for EnvParser.parse
|
|
138
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.
|
139
139
|
|
140
140
|
```ruby
|
141
|
-
ENV['SHORT_PI']
|
142
|
-
ENV['BETTER_PI']
|
141
|
+
ENV['SHORT_PI'] # => '3.1415926'
|
142
|
+
ENV['BETTER_PI'] # => '["flaky crust", "strawberry filling"]'
|
143
143
|
|
144
|
-
|
145
|
-
|
144
|
+
# Bind the proxy methods.
|
145
|
+
#
|
146
146
|
EnvParser.add_env_bindings
|
147
147
|
|
148
|
-
ENV.parse :SHORT_PI, as: :float
|
149
|
-
ENV.register :BETTER_PI, as: :array
|
148
|
+
ENV.parse :SHORT_PI, as: :float # => 3.1415926
|
149
|
+
ENV.register :BETTER_PI, as: :array # Your constant is set!
|
150
150
|
```
|
151
151
|
|
152
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.
|
153
153
|
|
154
154
|
```ruby
|
155
|
-
ENV['SHORT_PI']
|
155
|
+
ENV['SHORT_PI'] # => '3.1415926'
|
156
156
|
|
157
|
-
EnvParser.parse 'SHORT_PI', as: :float
|
158
|
-
EnvParser.parse :SHORT_PI , as: :float
|
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
|
159
159
|
|
160
|
-
|
161
|
-
|
160
|
+
# Bind the proxy methods.
|
161
|
+
#
|
162
162
|
EnvParser.add_env_bindings
|
163
163
|
|
164
|
-
ENV.parse 'SHORT_PI', as: :float
|
165
|
-
ENV.parse :SHORT_PI , as: :float
|
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
166
|
```
|
167
167
|
|
168
168
|
Note also that the `ENV.parse` and `ENV.register` binding is done safely and without polluting the method space for other objects.
|
@@ -177,14 +177,14 @@ EnvParser.add_env_bindings ## ENV.parse will now be a proxy for EnvParser.parse
|
|
177
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.
|
178
178
|
|
179
179
|
```ruby
|
180
|
-
ENV.parse :MISSING_VAR, as: :integer
|
181
|
-
ENV.parse :MISSING_VAR, as: :integer, if_unset: 250
|
180
|
+
ENV.parse :MISSING_VAR, as: :integer # => 0
|
181
|
+
ENV.parse :MISSING_VAR, as: :integer, if_unset: 250 # => 250
|
182
182
|
```
|
183
183
|
|
184
184
|
Note these default values are used as-is with no type conversion, so exercise caution.
|
185
185
|
|
186
186
|
```ruby
|
187
|
-
ENV.parse :MISSING_VAR, as: :integer, if_unset: 'Careful!'
|
187
|
+
ENV.parse :MISSING_VAR, as: :integer, if_unset: 'Careful!' # => 'Careful!' (NOT AN INTEGER)
|
188
188
|
```
|
189
189
|
|
190
190
|
- **Selecting From A Set**
|
@@ -195,9 +195,9 @@ EnvParser.add_env_bindings ## ENV.parse will now be a proxy for EnvParser.parse
|
|
195
195
|
ENV.parse :API_TO_USE, as: :symbol, from_set: %i[internal external]
|
196
196
|
ENV.parse :NETWORK_PORT, as: :integer, from_set: (1..65535), if_unset: 80
|
197
197
|
|
198
|
-
|
199
|
-
|
200
|
-
ENV.parse :TWELVE, as: :integer, from_set: (1..5)
|
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
201
|
```
|
202
202
|
|
203
203
|
- **Custom Validation Of Parsed Values**
|
@@ -205,12 +205,12 @@ EnvParser.add_env_bindings ## ENV.parse will now be a proxy for EnvParser.parse
|
|
205
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.
|
206
206
|
|
207
207
|
```ruby
|
208
|
-
|
209
|
-
|
208
|
+
# Via a "validated_by" lambda ...
|
209
|
+
#
|
210
210
|
ENV.parse :MUST_BE_LOWERCASE, as: :string, validated_by: ->(value) { value == value.downcase }
|
211
211
|
|
212
|
-
|
213
|
-
|
212
|
+
# ... or with a block!
|
213
|
+
#
|
214
214
|
ENV.parse(:MUST_BE_LOWERCASE, as: :string) { |value| value == value.downcase }
|
215
215
|
ENV.parse(:CONNECTION_RETRIES, as: :integer, &:positive?)
|
216
216
|
```
|
@@ -269,7 +269,7 @@ EnvParser.add_env_bindings ## ENV.parse will now be a proxy for EnvParser.parse
|
|
269
269
|
EnvParser.register :PASSWORD, as: :string
|
270
270
|
EnvParser.register :MOCK_API, as: :boolean, within: MyClassOrModule }
|
271
271
|
|
272
|
-
|
272
|
+
# ... is equivalent to ... #
|
273
273
|
|
274
274
|
EnvParser.register USERNAME: { as: :string },
|
275
275
|
PASSWORD: { as: :string },
|
@@ -133,7 +133,7 @@ feature).</p>
|
|
133
133
|
</div>
|
134
134
|
|
135
135
|
<div id="footer">
|
136
|
-
Generated on Sun Dec 25 21:
|
136
|
+
Generated on Sun Dec 25 21:11:48 2022 by
|
137
137
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
138
138
|
0.9.28 (ruby-3.0.4).
|
139
139
|
</div>
|
data/docs/EnvParser/Error.html
CHANGED
@@ -128,7 +128,7 @@
|
|
128
128
|
</div>
|
129
129
|
|
130
130
|
<div id="footer">
|
131
|
-
Generated on Sun Dec 25 21:
|
131
|
+
Generated on Sun Dec 25 21:11:48 2022 by
|
132
132
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
133
133
|
0.9.28 (ruby-3.0.4).
|
134
134
|
</div>
|
@@ -132,7 +132,7 @@
|
|
132
132
|
</div>
|
133
133
|
|
134
134
|
<div id="footer">
|
135
|
-
Generated on Sun Dec 25 21:
|
135
|
+
Generated on Sun Dec 25 21:11:48 2022 by
|
136
136
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
137
137
|
0.9.28 (ruby-3.0.4).
|
138
138
|
</div>
|
@@ -169,7 +169,7 @@ valid, parseable JSON).</p>
|
|
169
169
|
</div>
|
170
170
|
|
171
171
|
<div id="footer">
|
172
|
-
Generated on Sun Dec 25 21:
|
172
|
+
Generated on Sun Dec 25 21:11:48 2022 by
|
173
173
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
174
174
|
0.9.28 (ruby-3.0.4).
|
175
175
|
</div>
|
@@ -150,7 +150,7 @@
|
|
150
150
|
</div>
|
151
151
|
|
152
152
|
<div id="footer">
|
153
|
-
Generated on Sun Dec 25 21:
|
153
|
+
Generated on Sun Dec 25 21:11:48 2022 by
|
154
154
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
155
155
|
0.9.28 (ruby-3.0.4).
|
156
156
|
</div>
|
@@ -150,7 +150,7 @@
|
|
150
150
|
</div>
|
151
151
|
|
152
152
|
<div id="footer">
|
153
|
-
Generated on Sun Dec 25 21:
|
153
|
+
Generated on Sun Dec 25 21:11:48 2022 by
|
154
154
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
155
155
|
0.9.28 (ruby-3.0.4).
|
156
156
|
</div>
|
data/docs/EnvParser/Types.html
CHANGED
@@ -118,7 +118,7 @@ Exists only for documentation’s sake.</p>
|
|
118
118
|
</div>
|
119
119
|
|
120
120
|
<div id="footer">
|
121
|
-
Generated on Sun Dec 25 21:
|
121
|
+
Generated on Sun Dec 25 21:11:48 2022 by
|
122
122
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
123
123
|
0.9.28 (ruby-3.0.4).
|
124
124
|
</div>
|
@@ -132,7 +132,7 @@
|
|
132
132
|
</div>
|
133
133
|
|
134
134
|
<div id="footer">
|
135
|
-
Generated on Sun Dec 25 21:
|
135
|
+
Generated on Sun Dec 25 21:11:48 2022 by
|
136
136
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
137
137
|
0.9.28 (ruby-3.0.4).
|
138
138
|
</div>
|
@@ -133,7 +133,7 @@ feature).</p>
|
|
133
133
|
</div>
|
134
134
|
|
135
135
|
<div id="footer">
|
136
|
-
Generated on Sun Dec 25 21:
|
136
|
+
Generated on Sun Dec 25 21:11:48 2022 by
|
137
137
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
138
138
|
0.9.28 (ruby-3.0.4).
|
139
139
|
</div>
|
@@ -134,7 +134,7 @@ check.</p>
|
|
134
134
|
</div>
|
135
135
|
|
136
136
|
<div id="footer">
|
137
|
-
Generated on Sun Dec 25 21:
|
137
|
+
Generated on Sun Dec 25 21:11:48 2022 by
|
138
138
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
139
139
|
0.9.28 (ruby-3.0.4).
|
140
140
|
</div>
|
@@ -132,7 +132,7 @@
|
|
132
132
|
</div>
|
133
133
|
|
134
134
|
<div id="footer">
|
135
|
-
Generated on Sun Dec 25 21:
|
135
|
+
Generated on Sun Dec 25 21:11:48 2022 by
|
136
136
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
137
137
|
0.9.28 (ruby-3.0.4).
|
138
138
|
</div>
|
data/docs/EnvParser.html
CHANGED
@@ -95,7 +95,7 @@
|
|
95
95
|
<dl>
|
96
96
|
<dt>Defined in:</dt>
|
97
97
|
<dd>lib/env_parser.rb<span class="defines">,<br />
|
98
|
-
lib/env_parser/errors.rb</span>
|
98
|
+
lib/env_parser/errors.rb,<br /> lib/env_parser/version.rb</span>
|
99
99
|
</dd>
|
100
100
|
</dl>
|
101
101
|
|
@@ -147,6 +147,11 @@
|
|
147
147
|
</dt>
|
148
148
|
<dd><pre class="code"><span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>.env_parser.yml</span><span class='tstring_end'>'</span></span><span class='period'>.</span><span class='id identifier rubyid_freeze'>freeze</span></pre></dd>
|
149
149
|
|
150
|
+
<dt id="VERSION-constant" class="">VERSION =
|
151
|
+
|
152
|
+
</dt>
|
153
|
+
<dd><pre class="code"><span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>1.3.3</span><span class='tstring_end'>'</span></span><span class='period'>.</span><span class='id identifier rubyid_freeze'>freeze</span></pre></dd>
|
154
|
+
|
150
155
|
</dl>
|
151
156
|
|
152
157
|
|
@@ -1197,7 +1202,7 @@ validation must give its own “validated_by” Proc.</p>
|
|
1197
1202
|
</div>
|
1198
1203
|
|
1199
1204
|
<div id="footer">
|
1200
|
-
Generated on Sun Dec 25 21:
|
1205
|
+
Generated on Sun Dec 25 21:11:48 2022 by
|
1201
1206
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
1202
1207
|
0.9.28 (ruby-3.0.4).
|
1203
1208
|
</div>
|
data/docs/_index.html
CHANGED
@@ -233,7 +233,7 @@
|
|
233
233
|
</div>
|
234
234
|
|
235
235
|
<div id="footer">
|
236
|
-
Generated on Sun Dec 25 21:
|
236
|
+
Generated on Sun Dec 25 21:11:48 2022 by
|
237
237
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
238
238
|
0.9.28 (ruby-3.0.4).
|
239
239
|
</div>
|
data/docs/file.README.html
CHANGED
@@ -396,7 +396,7 @@ USERNAME:
|
|
396
396
|
</div></div>
|
397
397
|
|
398
398
|
<div id="footer">
|
399
|
-
Generated on Sun Dec 25 21:
|
399
|
+
Generated on Sun Dec 25 21:11:48 2022 by
|
400
400
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
401
401
|
0.9.28 (ruby-3.0.4).
|
402
402
|
</div>
|
data/docs/index.html
CHANGED
@@ -396,7 +396,7 @@ USERNAME:
|
|
396
396
|
</div></div>
|
397
397
|
|
398
398
|
<div id="footer">
|
399
|
-
Generated on Sun Dec 25 21:
|
399
|
+
Generated on Sun Dec 25 21:11:48 2022 by
|
400
400
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
401
401
|
0.9.28 (ruby-3.0.4).
|
402
402
|
</div>
|
@@ -100,7 +100,7 @@
|
|
100
100
|
</div>
|
101
101
|
|
102
102
|
<div id="footer">
|
103
|
-
Generated on Sun Dec 25 21:
|
103
|
+
Generated on Sun Dec 25 21:11:48 2022 by
|
104
104
|
<a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
105
105
|
0.9.28 (ruby-3.0.4).
|
106
106
|
</div>
|
@@ -48,6 +48,18 @@ module EnvParser::Types
|
|
48
48
|
# Note this does not guarantee RFC5322-conformity.
|
49
49
|
# </td>
|
50
50
|
# </tr>
|
51
|
+
# <tr>
|
52
|
+
# <td>:version / :semver</td>
|
53
|
+
# <td>MatchData</td>
|
54
|
+
# <td><code>nil</code></td>
|
55
|
+
# <td>
|
56
|
+
# The resulting MatchData has named captures for "major", "minor", "patch", "prerelease", and "buildmetadata".
|
57
|
+
# <br />
|
58
|
+
# The Regex used for generating this MatchData is available at: https://regex101.com/r/Ly7O1x/3/
|
59
|
+
# <br />
|
60
|
+
# See https://semver.org for additional info.
|
61
|
+
# </td>
|
62
|
+
# </tr>
|
51
63
|
# </tbody>
|
52
64
|
# </table>
|
53
65
|
#
|
@@ -95,5 +107,15 @@ module EnvParser::Types
|
|
95
107
|
|
96
108
|
value
|
97
109
|
end
|
110
|
+
|
111
|
+
EnvParser.define_type(:version, aliases: :semver, if_unset: nil) do |value|
|
112
|
+
# We're using the official semver.org-provided regex.
|
113
|
+
semver = %r{^(?<major>0|[1-9]\d*)\.(?<minor>0|[1-9]\d*)\.(?<patch>0|[1-9]\d*)(?:-(?<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$} ## rubocop:disable Layout/LineLength
|
114
|
+
|
115
|
+
match_data = value.match(semver)
|
116
|
+
raise(EnvParser::ValueNotConvertibleError, 'not a semver-compliant value') unless match_data
|
117
|
+
|
118
|
+
match_data
|
119
|
+
end
|
98
120
|
end
|
99
121
|
end
|
data/lib/env_parser/version.rb
CHANGED
data/lib/env_parser.rb
CHANGED
@@ -132,12 +132,12 @@ class EnvParser
|
|
132
132
|
# variable names and whose values are the options set for each variable's {.register} call.
|
133
133
|
#
|
134
134
|
# <pre>
|
135
|
-
#
|
135
|
+
# # Example shortcut usage:
|
136
136
|
#
|
137
137
|
# EnvParser.register :A, from: one_hash, as: :integer
|
138
138
|
# EnvParser.register :B, from: another_hash, as: :string, if_unset: 'none'
|
139
139
|
#
|
140
|
-
#
|
140
|
+
# # ... is equivalent to ...
|
141
141
|
#
|
142
142
|
# EnvParser.register(
|
143
143
|
# A: { from: one_hash, as: :integer }
|
@@ -152,6 +152,19 @@ class EnvParser
|
|
152
152
|
# @option options [Hash] from (ENV)
|
153
153
|
# The source Hash from which to pull the value referenced by the "name" key.
|
154
154
|
#
|
155
|
+
# @option options [Symbol] named
|
156
|
+
# The name the constant should be given. Valid only when a "within" value is *explicitly*
|
157
|
+
# given. This allows for decoupling ENV variable names from the constant name defined
|
158
|
+
# within its target class or module, allowing for the ENV variables to be namespaced in
|
159
|
+
# some way.
|
160
|
+
#
|
161
|
+
# <pre>
|
162
|
+
# EnvParser.register(
|
163
|
+
# CUSTOM_CLIENT_DEFAULT_HOSTNAME: { as: :string, named: :DEFAULT_HOSTNAME, within: CustomClient },
|
164
|
+
# CUSTOM_CLIENT_DEFAULT_PORT: { as: :integer, named: :DEFAULT_PORT, within: CustomClient }
|
165
|
+
# )
|
166
|
+
# </pre>
|
167
|
+
#
|
155
168
|
# @option options [Module, Class] within (Kernel)
|
156
169
|
# The module or class in which the constant should be created. Creates global constants by
|
157
170
|
# default.
|
@@ -185,6 +198,9 @@ class EnvParser
|
|
185
198
|
from = options.fetch(:from, ENV)
|
186
199
|
within = options.fetch(:within, Kernel)
|
187
200
|
|
201
|
+
named = name
|
202
|
+
named = options.fetch(:named, name) if options.key? :within
|
203
|
+
|
188
204
|
# ENV *seems* like a Hash and it does *some* Hash-y things, but it is NOT a Hash and that can
|
189
205
|
# bite you in some cases. Making sure we're working with a straight-up Hash saves a lot of
|
190
206
|
# sanity checks later on. This is also a good place to make sure we're working with a String
|
@@ -199,7 +215,7 @@ class EnvParser
|
|
199
215
|
|
200
216
|
value = from[name]
|
201
217
|
value = parse(value, options, &validation_block)
|
202
|
-
within.const_set(
|
218
|
+
within.const_set(named.upcase.to_sym, value.dup.freeze)
|
203
219
|
|
204
220
|
value
|
205
221
|
end
|
@@ -248,7 +264,7 @@ class EnvParser
|
|
248
264
|
|
249
265
|
autoregister_spec.deep_symbolize_keys!
|
250
266
|
autoregister_spec.transform_values! do |spec|
|
251
|
-
sanitized = spec.slice(:as, :within, :if_unset, :from_set)
|
267
|
+
sanitized = spec.slice(:as, :named, :within, :if_unset, :from_set)
|
252
268
|
sanitized[:as] = sanitized[:as].to_sym if sanitized.key? :as
|
253
269
|
sanitized[:within] = sanitized[:within].constantize if sanitized.key? :within
|
254
270
|
|
@@ -42,4 +42,54 @@ RSpec.describe EnvParser::Types::InternetTypes do
|
|
42
42
|
|
43
43
|
expect { EnvParser.parse('not an email address', as: :email_address) }.to raise_error(EnvParser::ValueNotConvertibleError)
|
44
44
|
end
|
45
|
+
|
46
|
+
it 'can parse version numbers' do
|
47
|
+
%i[version semver].each do |type|
|
48
|
+
expect(EnvParser.parse(nil, as: type)).to eq(nil)
|
49
|
+
expect(EnvParser.parse('', as: type)).to eq(nil)
|
50
|
+
|
51
|
+
# Our list of valid version strings is a subset of those in the official semver.org-provided regex suite.
|
52
|
+
# rubocop:disable Layout
|
53
|
+
#
|
54
|
+
valid_version_strings = {
|
55
|
+
'0.0.4' => { major: '0' , minor: '0', patch: '4', prerelease: nil , buildmetadata: nil },
|
56
|
+
'1.2.3' => { major: '1' , minor: '2', patch: '3', prerelease: nil , buildmetadata: nil },
|
57
|
+
'1.1.2-prerelease+meta' => { major: '1' , minor: '1', patch: '2', prerelease: 'prerelease' , buildmetadata: 'meta' },
|
58
|
+
'1.1.2+meta' => { major: '1' , minor: '1', patch: '2', prerelease: nil , buildmetadata: 'meta' },
|
59
|
+
'1.1.2+meta-valid' => { major: '1' , minor: '1', patch: '2', prerelease: nil , buildmetadata: 'meta-valid' },
|
60
|
+
'1.0.0-alpha' => { major: '1' , minor: '0', patch: '0', prerelease: 'alpha' , buildmetadata: nil },
|
61
|
+
'1.0.0-beta' => { major: '1' , minor: '0', patch: '0', prerelease: 'beta' , buildmetadata: nil },
|
62
|
+
'1.0.0-alpha.beta' => { major: '1' , minor: '0', patch: '0', prerelease: 'alpha.beta' , buildmetadata: nil },
|
63
|
+
'1.0.0-alpha.beta.1' => { major: '1' , minor: '0', patch: '0', prerelease: 'alpha.beta.1', buildmetadata: nil },
|
64
|
+
'1.0.0-alpha.1' => { major: '1' , minor: '0', patch: '0', prerelease: 'alpha.1' , buildmetadata: nil },
|
65
|
+
'1.0.0-alpha0.valid' => { major: '1' , minor: '0', patch: '0', prerelease: 'alpha0.valid', buildmetadata: nil },
|
66
|
+
'1.0.0-alpha.0valid' => { major: '1' , minor: '0', patch: '0', prerelease: 'alpha.0valid', buildmetadata: nil },
|
67
|
+
'1.0.0-rc.1+build.1' => { major: '1' , minor: '0', patch: '0', prerelease: 'rc.1' , buildmetadata: 'build.1' },
|
68
|
+
'2.0.0-rc.1+build.123' => { major: '2' , minor: '0', patch: '0', prerelease: 'rc.1' , buildmetadata: 'build.123' },
|
69
|
+
'1.2.3-beta' => { major: '1' , minor: '2', patch: '3', prerelease: 'beta' , buildmetadata: nil },
|
70
|
+
'10.2.3-DEV-SNAPSHOT' => { major: '10', minor: '2', patch: '3', prerelease: 'DEV-SNAPSHOT', buildmetadata: nil },
|
71
|
+
'1.2.3-SNAPSHOT-123' => { major: '1' , minor: '2', patch: '3', prerelease: 'SNAPSHOT-123', buildmetadata: nil },
|
72
|
+
'2.0.0+build.1848' => { major: '2' , minor: '0', patch: '0', prerelease: nil , buildmetadata: 'build.1848' },
|
73
|
+
'2.0.1-alpha.1227' => { major: '2' , minor: '0', patch: '1', prerelease: 'alpha.1227' , buildmetadata: nil },
|
74
|
+
'1.0.0-alpha+beta' => { major: '1' , minor: '0', patch: '0', prerelease: 'alpha' , buildmetadata: 'beta' },
|
75
|
+
'1.0.0-0A.is.legal' => { major: '1' , minor: '0', patch: '0', prerelease: '0A.is.legal' , buildmetadata: nil }
|
76
|
+
}
|
77
|
+
# rubocop:enable Layout
|
78
|
+
|
79
|
+
valid_version_strings.each do |version, expected_matches|
|
80
|
+
parsed_value = EnvParser.parse(version, as: type)
|
81
|
+
|
82
|
+
expect(parsed_value).to_not eq(nil)
|
83
|
+
expected_matches.each { |match_name, expected_value| expect(parsed_value[match_name]).to eq(expected_value) }
|
84
|
+
end
|
85
|
+
|
86
|
+
# Our list of invalid version strings is a subset of those in the official semver.org-provided regex suite.
|
87
|
+
#
|
88
|
+
invalid_version_strings = ['1', '1.2', '1.2.3-0123', '1.2.3-0123.0123', '1.1.2+.123', '+invalid', '-invalid', '-invalid+invalid',
|
89
|
+
'-invalid.01', 'alpha', 'alpha.1', 'alpha+beta', '1.0.0-alpha..', '1.0.0-alpha..1', '01.1.1', '1.01.1',
|
90
|
+
'1.1.01', '1.2.3.DEV', '1.2-SNAPSHOT', '+justmeta', '9.8.7+meta+meta', '9.8.7-whatever+meta+meta']
|
91
|
+
|
92
|
+
invalid_version_strings.each { |version| expect { EnvParser.parse(version, as: type) }.to raise_error(EnvParser::ValueNotConvertibleError) }
|
93
|
+
end
|
94
|
+
end
|
45
95
|
end
|
data/spec/env_parser_spec.rb
CHANGED
@@ -60,9 +60,16 @@ RSpec.describe EnvParser do
|
|
60
60
|
end
|
61
61
|
|
62
62
|
it 'creates module constants' do
|
63
|
-
source_hash = {
|
64
|
-
EnvParser.register(:
|
65
|
-
expect(Sample::
|
63
|
+
source_hash = { DEF: '456' }
|
64
|
+
EnvParser.register(:DEF, from: source_hash, as: :integer, within: Sample)
|
65
|
+
expect(Sample::DEF).to eq(456)
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'creates named module constants' do
|
69
|
+
source_hash = { GHI: '789' }
|
70
|
+
EnvParser.register(:GHI, from: source_hash, as: :integer, named: :JKL, within: Sample)
|
71
|
+
expect { Sample::GHI }.to raise_error(NameError)
|
72
|
+
expect(Sample::JKL).to eq(789)
|
66
73
|
end
|
67
74
|
|
68
75
|
it 'will accept a hash keyed by variable names' do
|
@@ -117,6 +124,13 @@ RSpec.describe EnvParser do
|
|
117
124
|
expect(Sample::WXYZ).to eq(5678)
|
118
125
|
end
|
119
126
|
|
127
|
+
it 'creates module constants' do
|
128
|
+
ENV['ORIGINAL_NAME'] = '9999'
|
129
|
+
ENV.register(:ORIGINAL_NAME, as: :integer, named: :DIFFERENT_NAME, within: Sample)
|
130
|
+
expect { Sample::ORIGINAL_NAME }.to raise_error(NameError)
|
131
|
+
expect(Sample::DIFFERENT_NAME).to eq(9999)
|
132
|
+
end
|
133
|
+
|
120
134
|
it 'will accept a hash keyed by variable names' do
|
121
135
|
ENV['FIFTH'] = 'fifth'
|
122
136
|
ENV['SIXTH'] = '99'
|
@@ -156,6 +170,11 @@ RSpec.describe EnvParser do
|
|
156
170
|
CLASS_CONSTANT:
|
157
171
|
as: :string
|
158
172
|
within: String
|
173
|
+
|
174
|
+
NAMED_CLASS_CONSTANT:
|
175
|
+
as: :string
|
176
|
+
named: :OTHER_CLASS_CONSTANT
|
177
|
+
within: String
|
159
178
|
YAML
|
160
179
|
|
161
180
|
file.path
|
@@ -164,11 +183,14 @@ RSpec.describe EnvParser do
|
|
164
183
|
ENV['SOME_INT'] = '99'
|
165
184
|
ENV['SOME_STRING'] = 'twelve'
|
166
185
|
ENV['CLASS_CONSTANT'] = 'tricky'
|
186
|
+
ENV['NAMED_CLASS_CONSTANT'] = 'quizzical'
|
167
187
|
EnvParser.autoregister filename
|
168
188
|
|
169
189
|
expect(SOME_INT).to eq(99)
|
170
190
|
expect(SOME_STRING).to eq('twelve')
|
171
191
|
expect(String::CLASS_CONSTANT).to eq('tricky')
|
192
|
+
expect { String::NAMED_CLASS_CONSTANT }.to raise_error(NameError)
|
193
|
+
expect(String::OTHER_CLASS_CONSTANT).to eq('quizzical')
|
172
194
|
end
|
173
195
|
|
174
196
|
it 'properly handles file-not-found' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: env_parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nestor Custodio
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-12-
|
11
|
+
date: 2022-12-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|