env_parser 0.8.0 → 1.3.1

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.
Files changed (43) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +7 -6
  3. data/.rubocop.yml +56 -57
  4. data/.ruby-version +1 -1
  5. data/Gemfile.lock +58 -28
  6. data/README.md +252 -176
  7. data/docs/EnvParser.html +305 -169
  8. data/docs/EnvParser/AutoregisterFileNotFound.html +143 -0
  9. data/docs/EnvParser/Error.html +9 -9
  10. data/docs/EnvParser/TypeAlreadyDefinedError.html +143 -0
  11. data/docs/EnvParser/Types.html +128 -0
  12. data/docs/EnvParser/Types/BaseTypes.html +177 -0
  13. data/docs/EnvParser/Types/ChronologyTypes.html +159 -0
  14. data/docs/EnvParser/Types/InternetTypes.html +159 -0
  15. data/docs/EnvParser/UnknownTypeError.html +143 -0
  16. data/docs/EnvParser/UnparseableAutoregisterSpec.html +143 -0
  17. data/docs/EnvParser/ValueNotAllowedError.html +143 -0
  18. data/docs/EnvParser/ValueNotConvertibleError.html +143 -0
  19. data/docs/EnvParserTypes.html +129 -0
  20. data/docs/EnvParserTypes/BaseTypes.html +178 -0
  21. data/docs/EnvParserTypes/ChronologyTypes.html +159 -0
  22. data/docs/EnvParserTypes/InternetTypes.html +159 -0
  23. data/docs/EnvParserTypes/TimeTypes.html +158 -0
  24. data/docs/_index.html +108 -9
  25. data/docs/class_list.html +3 -3
  26. data/docs/css/style.css +7 -9
  27. data/docs/file.README.html +215 -226
  28. data/docs/file_list.html +2 -2
  29. data/docs/frames.html +2 -2
  30. data/docs/index.html +215 -226
  31. data/docs/js/app.js +69 -3
  32. data/docs/method_list.html +13 -5
  33. data/docs/top-level-namespace.html +9 -9
  34. data/env_parser.gemspec +6 -2
  35. data/lib/env_parser.rb +111 -83
  36. data/lib/env_parser/autoregister.rb +3 -0
  37. data/lib/env_parser/errors.rb +40 -0
  38. data/lib/env_parser/types.rb +3 -0
  39. data/lib/env_parser/types/base_types.rb +99 -26
  40. data/lib/env_parser/types/chronology_types.rb +104 -0
  41. data/lib/env_parser/types/internet_types.rb +99 -0
  42. data/lib/env_parser/version.rb +1 -1
  43. metadata +85 -10
@@ -0,0 +1,3 @@
1
+ require 'env_parser'
2
+
3
+ EnvParser.autoregister
@@ -0,0 +1,40 @@
1
+ class EnvParser
2
+ ## Base error class for EnvParser.
3
+ ##
4
+ class Error < ::StandardError
5
+ end
6
+
7
+ ## Error class used to indicate a type has already been defined.
8
+ ##
9
+ class TypeAlreadyDefinedError < Error
10
+ end
11
+
12
+ ## Error class used to indicate the requested "as" type has not been defined.
13
+ ##
14
+ class UnknownTypeError < Error
15
+ end
16
+
17
+ ## Error class used to indicate value given is not convertible to the requested type.
18
+ ##
19
+ class ValueNotConvertibleError < Error
20
+ end
21
+
22
+ ## Error class used to indicate parsed values that do not pass user-validation, either by not
23
+ ## being part of the given "from_set" list, or by failing the "validated_by" Proc or yield-block
24
+ ## check.
25
+ ##
26
+ class ValueNotAllowedError < Error
27
+ end
28
+
29
+ ## Error class used to indicate a missing auto-registration spec file (used by the "autoregister"
30
+ ## feature).
31
+ ##
32
+ class AutoregisterFileNotFound < Error
33
+ end
34
+
35
+ ## Error class used to indicate an unparseable auto-registration spec (used by the "autoregister"
36
+ ## feature).
37
+ ##
38
+ class UnparseableAutoregisterSpec < Error
39
+ end
40
+ end
@@ -0,0 +1,3 @@
1
+ ## Load all files listed in "/lib/env_parser/types".
2
+ ##
3
+ Dir.glob(File.join(__dir__, 'types', '*.rb')).each { |filename| require_relative filename }
@@ -1,39 +1,112 @@
1
1
  require 'env_parser'
2
2
 
3
- EnvParser.define_type(:string, if_unset: '') do |value|
4
- value
5
- end
3
+ ## The parent module for all EnvParser type definition modules.
4
+ ## Exists only for documentation's sake.
5
+ ##
6
+ module EnvParser::Types
7
+ ## Defines types for primitive classes, adding the following:
8
+ ##
9
+ ## <table>
10
+ ## <tbody>
11
+ ## <tr>
12
+ ## <th><code>:as</code> value</th>
13
+ ## <th>type returned</th>
14
+ ## <th>default</th>
15
+ ## <th>notes</th>
16
+ ## </tr>
17
+ ## </tbody>
18
+ ## <tbody>
19
+ ## <tr>
20
+ ## <td>:string</td>
21
+ ## <td>String</td>
22
+ ## <td><code>''</code></td>
23
+ ## <td></td>
24
+ ## </tr>
25
+ ## <tr>
26
+ ## <td>:symbol</td>
27
+ ## <td>Symbol</td>
28
+ ## <td><code>:''</code></td>
29
+ ## <td></td>
30
+ ## </tr>
31
+ ## <tr>
32
+ ## <td>:boolean</td>
33
+ ## <td>TrueValue / FalseValue</td>
34
+ ## <td><code>false</code></td>
35
+ ## <td></td>
36
+ ## </tr>
37
+ ## <tr>
38
+ ## <td>:int / :integer</td>
39
+ ## <td>Integer</td>
40
+ ## <td><code>0</code></td>
41
+ ## <td></td>
42
+ ## </tr>
43
+ ## <tr>
44
+ ## <td>:float / :decimal / :number</td>
45
+ ## <td>Float</td>
46
+ ## <td><code>0.0</code></td>
47
+ ## <td></td>
48
+ ## </tr>
49
+ ## <tr>
50
+ ## <td>:json</td>
51
+ ## <td>&lt; depends on JSON given &gt;</td>
52
+ ## <td><code>nil</code></td>
53
+ ## <td></td>
54
+ ## </tr>
55
+ ## <tr>
56
+ ## <td>:array</td>
57
+ ## <td>Array</td>
58
+ ## <td><code>[]</code></td>
59
+ ## <td></td>
60
+ ## </tr>
61
+ ## <tr>
62
+ ## <td>:hash</td>
63
+ ## <td>Hash</td>
64
+ ## <td><code>{}</code></td>
65
+ ## <td></td>
66
+ ## </tr>
67
+ ## </tbody>
68
+ ## </table>
69
+ ##
70
+ ## Note JSON is parsed using *quirks-mode* (meaning 'true', '25', and 'null' are all considered
71
+ ## valid, parseable JSON).
72
+ ##
73
+ module BaseTypes
74
+ EnvParser.define_type(:string, if_unset: '') do |value|
75
+ value
76
+ end
6
77
 
7
- EnvParser.define_type(:symbol, if_unset: :'', &:to_sym)
78
+ EnvParser.define_type(:symbol, if_unset: :'', &:to_sym)
8
79
 
9
- EnvParser.define_type(:boolean, if_unset: false) do |value|
10
- case value
11
- when '', '0', 'f', 'false' then false
12
- else true
13
- end
14
- end
80
+ EnvParser.define_type(:boolean, if_unset: false) do |value|
81
+ case value
82
+ when '', '0', 'f', 'false' then false
83
+ else true
84
+ end
85
+ end
15
86
 
16
- EnvParser.define_type(:integer, aliases: %i[int], if_unset: 0, &:to_i)
87
+ EnvParser.define_type(:integer, aliases: %i[int], if_unset: 0, &:to_i)
17
88
 
18
- EnvParser.define_type(:float, aliases: %i[decimal number], if_unset: 0.0, &:to_f)
89
+ EnvParser.define_type(:float, aliases: %i[decimal number], if_unset: 0.0, &:to_f)
19
90
 
20
- EnvParser.define_type(:json, if_unset: nil) do |value|
21
- require 'json'
91
+ EnvParser.define_type(:json, if_unset: nil) do |value|
92
+ require 'json'
22
93
 
23
- decoded_json = JSON.parse(value, quirks_mode: true)
24
- { decoded_json: decoded_json }.with_indifferent_access[:decoded_json]
25
- end
94
+ decoded_json = JSON.parse(value, quirks_mode: true)
95
+ { decoded_json: decoded_json }.with_indifferent_access[:decoded_json]
96
+ end
26
97
 
27
- EnvParser.define_type(:array, if_unset: []) do |value|
28
- decoded_json = EnvParser.parse(value, as: :json)
29
- raise(ArgumentError, 'non-array value') unless decoded_json.is_a? Array
98
+ EnvParser.define_type(:array, if_unset: []) do |value|
99
+ decoded_json = EnvParser.parse(value, as: :json)
100
+ raise(EnvParser::ValueNotConvertibleError, 'non-array value') unless decoded_json.is_a? Array
30
101
 
31
- decoded_json
32
- end
102
+ decoded_json
103
+ end
33
104
 
34
- EnvParser.define_type(:hash, if_unset: {}) do |value|
35
- decoded_json = EnvParser.parse(value, as: :json)
36
- raise(ArgumentError, 'non-hash value') unless decoded_json.is_a? Hash
105
+ EnvParser.define_type(:hash, if_unset: {}) do |value|
106
+ decoded_json = EnvParser.parse(value, as: :json)
107
+ raise(EnvParser::ValueNotConvertibleError, 'non-hash value') unless decoded_json.is_a? Hash
37
108
 
38
- decoded_json
109
+ decoded_json
110
+ end
111
+ end
39
112
  end
@@ -0,0 +1,104 @@
1
+ require 'env_parser'
2
+
3
+ ## The parent module for all EnvParser type definition modules.
4
+ ## Exists only for documentation's sake.
5
+ ##
6
+ module EnvParser::Types
7
+ ## Defines types for date/time-related values, adding the following:
8
+ ##
9
+ ## <table>
10
+ ## <tbody>
11
+ ## <tr>
12
+ ## <th><code>:as</code> value</th>
13
+ ## <th>type returned</th>
14
+ ## <th>default</th>
15
+ ## <th>notes</th>
16
+ ## </tr>
17
+ ## </tbody>
18
+ ## <tbody>
19
+ ## <tr>
20
+ ## <td>:date</td>
21
+ ## <td>Date</td>
22
+ ## <td><code>nil</code></td>
23
+ ## <td>
24
+ ## A natural language or ISO8601-parseable date.
25
+ ## <br />
26
+ ## Actual interpretation of the value is handled by the *chronic* gem.
27
+ ## </td>
28
+ ## </tr>
29
+ ## <tr>
30
+ ## <td>:time / :datetime</td>
31
+ ## <td>Time</td>
32
+ ## <td><code>nil</code></td>
33
+ ## <td>
34
+ ## A natural language or ISO8601-parseable date and time.
35
+ ## <br />
36
+ ## Actual interpretation of the value is handled by the *chronic* gem.
37
+ ## </td>
38
+ ## </tr>
39
+ ## <tr>
40
+ ## <td>:duration</td>
41
+ ## <td>Numeric</td>
42
+ ## <td><code>nil</code></td>
43
+ ## <td>
44
+ ## A natural language or ISO8601-parseable period.
45
+ ## <br />
46
+ ## Value returned is the number of seconds in the given period.
47
+ ## <br />
48
+ ## Actual interpretation of the value is handled by the *chronic_duration* gem.
49
+ ## </td>
50
+ ## </tr>
51
+ ## </tbody>
52
+ ## </table>
53
+ ##
54
+ module ChronologyTypes
55
+ EnvParser.define_type(:date, if_unset: nil) do |value|
56
+ require 'chronic'
57
+
58
+ begin
59
+ value = Chronic.parse value, guess: :begin
60
+ raise StandardError unless value.is_a? Time
61
+ rescue StandardError
62
+ raise EnvParser::ValueNotConvertibleError, 'non-date value'
63
+ end
64
+
65
+ value.to_date
66
+ end
67
+
68
+ EnvParser.define_type(:time, aliases: :datetime, if_unset: nil) do |value|
69
+ require 'chronic'
70
+
71
+ begin
72
+ value = Chronic.parse value, guess: :begin
73
+ raise StandardError unless value.is_a? Time
74
+ rescue StandardError
75
+ raise EnvParser::ValueNotConvertibleError, 'non-time value'
76
+ end
77
+
78
+ value
79
+ end
80
+
81
+ EnvParser.define_type(:duration, if_unset: nil) do |value|
82
+ require 'chronic_duration'
83
+
84
+ begin
85
+ original_raise_setting = ChronicDuration.raise_exceptions
86
+ ChronicDuration.raise_exceptions = true
87
+
88
+ ## With `raise_exceptions` set, ChronicDuration will fail on the "P" and "T" in ISO8601
89
+ ## periods, so we have to check for and remove them.
90
+ ##
91
+ iso_period = %r{^\s*P(?:[0-9.]Y)?(?:[0-9.]M)?(?:[0-9.]W)?(?:[0-9.]D)?(?:T(?:[0-9.]H)?(?:[0-9.]M)?(?:[0-9.]S)?)?\s*$} ## rubocop:disable Layout/LineLength
92
+ value = value.delete 'PT' if value =~ iso_period
93
+
94
+ value = ChronicDuration.parse value, keep_zero: true
95
+ rescue StandardError
96
+ raise EnvParser::ValueNotConvertibleError, 'non-duration value'
97
+ ensure
98
+ ChronicDuration.raise_exceptions = original_raise_setting
99
+ end
100
+
101
+ value
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,99 @@
1
+ require 'env_parser'
2
+
3
+ ## The parent module for all EnvParser type definition modules.
4
+ ## Exists only for documentation's sake.
5
+ ##
6
+ module EnvParser::Types
7
+ ## Defines types for internet-related values, adding the following:
8
+ ##
9
+ ## <table>
10
+ ## <tbody>
11
+ ## <tr>
12
+ ## <th><code>:as</code> value</th>
13
+ ## <th>type returned</th>
14
+ ## <th>default</th>
15
+ ## <th>notes</th>
16
+ ## </tr>
17
+ ## </tbody>
18
+ ## <tbody>
19
+ ## <tr>
20
+ ## <td>:ipv4_address</td>
21
+ ## <td>String</td>
22
+ ## <td><code>nil</code></td>
23
+ ## <td>
24
+ ## An IPv4 address in 4-octet dot-decimal notation,
25
+ ## <br />
26
+ ## with no CIDR or subnet suffix (e.g. <code>'192.168.0.1'</code>).
27
+ ## </td>
28
+ ## </tr>
29
+ ## <tr>
30
+ ## <td>:ipv6_address</td>
31
+ ## <td>String</td>
32
+ ## <td><code>nil</code></td>
33
+ ## <td>An IPv6 address, in RFC5952 format.</td>
34
+ ## </tr>
35
+ ## <tr>
36
+ ## <td>:network_port / :port</td>
37
+ ## <td>Integer</td>
38
+ ## <td><code>nil</code></td>
39
+ ## <td></td>
40
+ ## </tr>
41
+ ## <tr>
42
+ ## <td>:email_address</td>
43
+ ## <td>String</td>
44
+ ## <td><code>nil</code></td>
45
+ ## <td>
46
+ ## A "simple" email address, containing only a username and a domain.
47
+ ## <br />
48
+ ## Note this does not guarantee RFC5322-conformity.
49
+ ## </td>
50
+ ## </tr>
51
+ ## </tbody>
52
+ ## </table>
53
+ ##
54
+ module InternetTypes
55
+ EnvParser.define_type(:ipv4_address, if_unset: nil) do |value|
56
+ begin
57
+ require 'socket'
58
+ address = Addrinfo.getaddrinfo(value, nil, Socket::AF_INET, nil, Socket::IPPROTO_TCP).first
59
+ raise StandardError unless address.ipv4?
60
+ rescue StandardError
61
+ raise EnvParser::ValueNotConvertibleError, 'non-ip value'
62
+ end
63
+
64
+ address.ip_address
65
+ end
66
+
67
+ EnvParser.define_type(:ipv6_address, if_unset: nil) do |value|
68
+ begin
69
+ require 'socket'
70
+ address = Addrinfo.getaddrinfo(value, nil, Socket::AF_INET6, nil, Socket::IPPROTO_TCP).first
71
+ raise StandardError unless address.ipv6?
72
+ rescue StandardError
73
+ raise EnvParser::ValueNotConvertibleError, 'non-ip value'
74
+ end
75
+
76
+ address.ip_address
77
+ end
78
+
79
+ EnvParser.define_type(:network_port, aliases: :port, if_unset: nil) do |value|
80
+ begin
81
+ Integer(value)
82
+ rescue ArgumentError
83
+ raise(EnvParser::ValueNotConvertibleError, 'non-numeric value')
84
+ end
85
+
86
+ value = value.to_i
87
+ raise(EnvParser::ValueNotAllowedError, 'value out of range') unless (0..65535).cover?(value)
88
+
89
+ value
90
+ end
91
+
92
+ EnvParser.define_type(:email_address, if_unset: nil) do |value|
93
+ simple_email = %r[^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$]i ## rubocop:disable Layout/LineLength
94
+ raise(EnvParser::ValueNotConvertibleError, 'not an email') unless value.match?(simple_email)
95
+
96
+ value
97
+ end
98
+ end
99
+ end
@@ -1,3 +1,3 @@
1
1
  class EnvParser
2
- VERSION = '0.8.0'.freeze
2
+ VERSION = '1.3.1'.freeze
3
3
  end
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: 0.8.0
4
+ version: 1.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nestor Custodio
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-12-25 00:00:00.000000000 Z
11
+ date: 2021-01-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.16'
19
+ version: '2.0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.16'
26
+ version: '2.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +66,34 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '='
74
+ - !ruby/object:Gem::Version
75
+ version: '1.7'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '='
81
+ - !ruby/object:Gem::Version
82
+ version: '1.7'
83
+ - !ruby/object:Gem::Dependency
84
+ name: yard
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
69
97
  - !ruby/object:Gem::Dependency
70
98
  name: activesupport
71
99
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +108,34 @@ dependencies:
80
108
  - - ">="
81
109
  - !ruby/object:Gem::Version
82
110
  version: 5.0.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: chronic
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: chronic_duration
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
83
139
  description:
84
140
  email:
85
141
  - sakimorix@gmail.com
@@ -102,9 +158,24 @@ files:
102
158
  - bin/console
103
159
  - bin/setup
104
160
  - docs/EnvParser.html
161
+ - docs/EnvParser/AutoregisterFileNotFound.html
105
162
  - docs/EnvParser/Error.html
106
163
  - docs/EnvParser/TypeAlreadyDefined.html
164
+ - docs/EnvParser/TypeAlreadyDefinedError.html
165
+ - docs/EnvParser/Types.html
166
+ - docs/EnvParser/Types/BaseTypes.html
167
+ - docs/EnvParser/Types/ChronologyTypes.html
168
+ - docs/EnvParser/Types/InternetTypes.html
169
+ - docs/EnvParser/UnknownTypeError.html
170
+ - docs/EnvParser/UnparseableAutoregisterSpec.html
107
171
  - docs/EnvParser/ValueNotAllowed.html
172
+ - docs/EnvParser/ValueNotAllowedError.html
173
+ - docs/EnvParser/ValueNotConvertibleError.html
174
+ - docs/EnvParserTypes.html
175
+ - docs/EnvParserTypes/BaseTypes.html
176
+ - docs/EnvParserTypes/ChronologyTypes.html
177
+ - docs/EnvParserTypes/InternetTypes.html
178
+ - docs/EnvParserTypes/TimeTypes.html
108
179
  - docs/_index.html
109
180
  - docs/class_list.html
110
181
  - docs/css/common.css
@@ -121,7 +192,12 @@ files:
121
192
  - docs/top-level-namespace.html
122
193
  - env_parser.gemspec
123
194
  - lib/env_parser.rb
195
+ - lib/env_parser/autoregister.rb
196
+ - lib/env_parser/errors.rb
197
+ - lib/env_parser/types.rb
124
198
  - lib/env_parser/types/base_types.rb
199
+ - lib/env_parser/types/chronology_types.rb
200
+ - lib/env_parser/types/internet_types.rb
125
201
  - lib/env_parser/version.rb
126
202
  homepage: https://github.com/nestor-custodio/env_parser
127
203
  licenses:
@@ -142,8 +218,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
142
218
  - !ruby/object:Gem::Version
143
219
  version: '0'
144
220
  requirements: []
145
- rubyforge_project:
146
- rubygems_version: 2.6.13
221
+ rubygems_version: 3.1.4
147
222
  signing_key:
148
223
  specification_version: 4
149
224
  summary: A tool for painless parsing and validation of environment variables.