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.
- checksums.yaml +5 -5
- data/.circleci/config.yml +7 -6
- data/.rubocop.yml +56 -57
- data/.ruby-version +1 -1
- data/Gemfile.lock +58 -28
- data/README.md +252 -176
- data/docs/EnvParser.html +305 -169
- data/docs/EnvParser/AutoregisterFileNotFound.html +143 -0
- data/docs/EnvParser/Error.html +9 -9
- data/docs/EnvParser/TypeAlreadyDefinedError.html +143 -0
- data/docs/EnvParser/Types.html +128 -0
- data/docs/EnvParser/Types/BaseTypes.html +177 -0
- data/docs/EnvParser/Types/ChronologyTypes.html +159 -0
- data/docs/EnvParser/Types/InternetTypes.html +159 -0
- data/docs/EnvParser/UnknownTypeError.html +143 -0
- data/docs/EnvParser/UnparseableAutoregisterSpec.html +143 -0
- data/docs/EnvParser/ValueNotAllowedError.html +143 -0
- data/docs/EnvParser/ValueNotConvertibleError.html +143 -0
- data/docs/EnvParserTypes.html +129 -0
- data/docs/EnvParserTypes/BaseTypes.html +178 -0
- data/docs/EnvParserTypes/ChronologyTypes.html +159 -0
- data/docs/EnvParserTypes/InternetTypes.html +159 -0
- data/docs/EnvParserTypes/TimeTypes.html +158 -0
- data/docs/_index.html +108 -9
- data/docs/class_list.html +3 -3
- data/docs/css/style.css +7 -9
- data/docs/file.README.html +215 -226
- data/docs/file_list.html +2 -2
- data/docs/frames.html +2 -2
- data/docs/index.html +215 -226
- data/docs/js/app.js +69 -3
- data/docs/method_list.html +13 -5
- data/docs/top-level-namespace.html +9 -9
- data/env_parser.gemspec +6 -2
- data/lib/env_parser.rb +111 -83
- data/lib/env_parser/autoregister.rb +3 -0
- data/lib/env_parser/errors.rb +40 -0
- data/lib/env_parser/types.rb +3 -0
- data/lib/env_parser/types/base_types.rb +99 -26
- data/lib/env_parser/types/chronology_types.rb +104 -0
- data/lib/env_parser/types/internet_types.rb +99 -0
- data/lib/env_parser/version.rb +1 -1
- metadata +85 -10
data/docs/js/app.js
CHANGED
@@ -120,6 +120,49 @@ function summaryToggle() {
|
|
120
120
|
} else { localStorage.summaryCollapsed = "expand"; }
|
121
121
|
}
|
122
122
|
|
123
|
+
function constantSummaryToggle() {
|
124
|
+
$('.constants_summary_toggle').click(function(e) {
|
125
|
+
e.preventDefault();
|
126
|
+
localStorage.summaryCollapsed = $(this).text();
|
127
|
+
$('.constants_summary_toggle').each(function() {
|
128
|
+
$(this).text($(this).text() == "collapse" ? "expand" : "collapse");
|
129
|
+
var next = $(this).parent().parent().nextAll('dl.constants').first();
|
130
|
+
if (next.hasClass('compact')) {
|
131
|
+
next.toggle();
|
132
|
+
next.nextAll('dl.constants').first().toggle();
|
133
|
+
}
|
134
|
+
else if (next.hasClass('constants')) {
|
135
|
+
var list = $('<dl class="constants compact" />');
|
136
|
+
list.html(next.html());
|
137
|
+
list.find('dt').each(function() {
|
138
|
+
$(this).addClass('summary_signature');
|
139
|
+
$(this).text( $(this).text().split('=')[0]);
|
140
|
+
if ($(this).has(".deprecated").length) {
|
141
|
+
$(this).addClass('deprecated');
|
142
|
+
};
|
143
|
+
});
|
144
|
+
// Add the value of the constant as "Tooltip" to the summary object
|
145
|
+
list.find('pre.code').each(function() {
|
146
|
+
console.log($(this).parent());
|
147
|
+
var dt_element = $(this).parent().prev();
|
148
|
+
var tooltip = $(this).text();
|
149
|
+
if (dt_element.hasClass("deprecated")) {
|
150
|
+
tooltip = 'Deprecated. ' + tooltip;
|
151
|
+
};
|
152
|
+
dt_element.attr('title', tooltip);
|
153
|
+
});
|
154
|
+
list.find('.docstring, .tags, dd').remove();
|
155
|
+
next.before(list);
|
156
|
+
next.toggle();
|
157
|
+
}
|
158
|
+
});
|
159
|
+
return false;
|
160
|
+
});
|
161
|
+
if (localStorage.summaryCollapsed == "collapse") {
|
162
|
+
$('.constants_summary_toggle').first().click();
|
163
|
+
} else { localStorage.summaryCollapsed = "expand"; }
|
164
|
+
}
|
165
|
+
|
123
166
|
function generateTOC() {
|
124
167
|
if ($('#filecontents').length === 0) return;
|
125
168
|
var _toc = $('<ol class="top"></ol>');
|
@@ -128,6 +171,7 @@ function generateTOC() {
|
|
128
171
|
var counter = 0;
|
129
172
|
var tags = ['h2', 'h3', 'h4', 'h5', 'h6'];
|
130
173
|
var i;
|
174
|
+
var curli;
|
131
175
|
if ($('#filecontents h1').length > 1) tags.unshift('h1');
|
132
176
|
for (i = 0; i < tags.length; i++) { tags[i] = '#filecontents ' + tags[i]; }
|
133
177
|
var lastTag = parseInt(tags[0][1], 10);
|
@@ -147,15 +191,25 @@ function generateTOC() {
|
|
147
191
|
}
|
148
192
|
if (thisTag > lastTag) {
|
149
193
|
for (i = 0; i < thisTag - lastTag; i++) {
|
150
|
-
|
194
|
+
if ( typeof(curli) == "undefined" ) {
|
195
|
+
curli = $('<li/>');
|
196
|
+
toc.append(curli);
|
197
|
+
}
|
198
|
+
toc = $('<ol/>');
|
199
|
+
curli.append(toc);
|
200
|
+
curli = undefined;
|
151
201
|
}
|
152
202
|
}
|
153
203
|
if (thisTag < lastTag) {
|
154
|
-
for (i = 0; i < lastTag - thisTag; i++)
|
204
|
+
for (i = 0; i < lastTag - thisTag; i++) {
|
205
|
+
toc = toc.parent();
|
206
|
+
toc = toc.parent();
|
207
|
+
}
|
155
208
|
}
|
156
209
|
var title = $(this).attr('toc-title');
|
157
210
|
if (typeof(title) == "undefined") title = $(this).text();
|
158
|
-
|
211
|
+
curli =$('<li><a href="#' + this.id + '">' + title + '</a></li>');
|
212
|
+
toc.append(curli);
|
159
213
|
lastTag = thisTag;
|
160
214
|
});
|
161
215
|
if (!show) return;
|
@@ -232,6 +286,16 @@ function mainFocus() {
|
|
232
286
|
setTimeout(function() { $('#main').focus(); }, 10);
|
233
287
|
}
|
234
288
|
|
289
|
+
function navigationChange() {
|
290
|
+
// This works around the broken anchor navigation with the YARD template.
|
291
|
+
window.onpopstate = function() {
|
292
|
+
var hash = window.location.hash;
|
293
|
+
if (hash !== '' && $(hash)[0]) {
|
294
|
+
$(hash)[0].scrollIntoView();
|
295
|
+
}
|
296
|
+
};
|
297
|
+
}
|
298
|
+
|
235
299
|
$(document).ready(function() {
|
236
300
|
navResizer();
|
237
301
|
navExpander();
|
@@ -241,8 +305,10 @@ $(document).ready(function() {
|
|
241
305
|
searchFrameButtons();
|
242
306
|
linkSummaries();
|
243
307
|
summaryToggle();
|
308
|
+
constantSummaryToggle();
|
244
309
|
generateTOC();
|
245
310
|
mainFocus();
|
311
|
+
navigationChange();
|
246
312
|
});
|
247
313
|
|
248
314
|
})();
|
data/docs/method_list.html
CHANGED
@@ -4,9 +4,9 @@
|
|
4
4
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
5
5
|
<meta charset="utf-8" />
|
6
6
|
|
7
|
-
<link rel="stylesheet" href="css/full_list.css" type="text/css" media="screen"
|
7
|
+
<link rel="stylesheet" href="css/full_list.css" type="text/css" media="screen" />
|
8
8
|
|
9
|
-
<link rel="stylesheet" href="css/common.css" type="text/css" media="screen"
|
9
|
+
<link rel="stylesheet" href="css/common.css" type="text/css" media="screen" />
|
10
10
|
|
11
11
|
|
12
12
|
|
@@ -54,13 +54,21 @@
|
|
54
54
|
|
55
55
|
<li class="even ">
|
56
56
|
<div class="item">
|
57
|
-
<span class='object_link'><a href="EnvParser.html#
|
57
|
+
<span class='object_link'><a href="EnvParser.html#autoregister-class_method" title="EnvParser.autoregister (method)">autoregister</a></span>
|
58
58
|
<small>EnvParser</small>
|
59
59
|
</div>
|
60
60
|
</li>
|
61
61
|
|
62
62
|
|
63
63
|
<li class="odd ">
|
64
|
+
<div class="item">
|
65
|
+
<span class='object_link'><a href="EnvParser.html#define_type-class_method" title="EnvParser.define_type (method)">define_type</a></span>
|
66
|
+
<small>EnvParser</small>
|
67
|
+
</div>
|
68
|
+
</li>
|
69
|
+
|
70
|
+
|
71
|
+
<li class="even ">
|
64
72
|
<div class="item">
|
65
73
|
<span class='object_link'><a href="top-level-namespace.html#filename-instance_method" title="#filename (method)">#filename</a></span>
|
66
74
|
<small>Top Level Namespace</small>
|
@@ -68,7 +76,7 @@
|
|
68
76
|
</li>
|
69
77
|
|
70
78
|
|
71
|
-
<li class="
|
79
|
+
<li class="odd ">
|
72
80
|
<div class="item">
|
73
81
|
<span class='object_link'><a href="EnvParser.html#parse-class_method" title="EnvParser.parse (method)">parse</a></span>
|
74
82
|
<small>EnvParser</small>
|
@@ -76,7 +84,7 @@
|
|
76
84
|
</li>
|
77
85
|
|
78
86
|
|
79
|
-
<li class="
|
87
|
+
<li class="even ">
|
80
88
|
<div class="item">
|
81
89
|
<span class='object_link'><a href="EnvParser.html#register-class_method" title="EnvParser.register (method)">register</a></span>
|
82
90
|
<small>EnvParser</small>
|
@@ -6,15 +6,15 @@
|
|
6
6
|
<title>
|
7
7
|
Top Level Namespace
|
8
8
|
|
9
|
-
— Documentation by YARD 0.9.
|
9
|
+
— Documentation by YARD 0.9.26
|
10
10
|
|
11
11
|
</title>
|
12
12
|
|
13
|
-
<link rel="stylesheet" href="css/style.css" type="text/css"
|
13
|
+
<link rel="stylesheet" href="css/style.css" type="text/css" />
|
14
14
|
|
15
|
-
<link rel="stylesheet" href="css/common.css" type="text/css"
|
15
|
+
<link rel="stylesheet" href="css/common.css" type="text/css" />
|
16
16
|
|
17
|
-
<script type="text/javascript"
|
17
|
+
<script type="text/javascript">
|
18
18
|
pathId = "";
|
19
19
|
relpath = '';
|
20
20
|
</script>
|
@@ -162,12 +162,12 @@
|
|
162
162
|
<pre class="lines">
|
163
163
|
|
164
164
|
|
165
|
-
|
165
|
+
3</pre>
|
166
166
|
</td>
|
167
167
|
<td>
|
168
|
-
<pre class="code"><span class="info file"># File 'lib/env_parser.rb', line
|
168
|
+
<pre class="code"><span class="info file"># File 'lib/env_parser/types.rb', line 3</span>
|
169
169
|
|
170
|
-
<span class='const'>Dir</span><span class='period'>.</span><span class='id identifier rubyid_glob'>glob</span><span class='lparen'>(</span><span class='const'>File</span><span class='period'>.</span><span class='id identifier rubyid_join'>join</span><span class='lparen'>(</span><span class='id identifier rubyid___dir__'>__dir__</span><span class='comma'>,</span> <span class='
|
170
|
+
<span class='const'>Dir</span><span class='period'>.</span><span class='id identifier rubyid_glob'>glob</span><span class='lparen'>(</span><span class='const'>File</span><span class='period'>.</span><span class='id identifier rubyid_join'>join</span><span class='lparen'>(</span><span class='id identifier rubyid___dir__'>__dir__</span><span class='comma'>,</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>types</span><span class='tstring_end'>'</span></span><span class='comma'>,</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>*.rb</span><span class='tstring_end'>'</span></span><span class='rparen'>)</span><span class='rparen'>)</span><span class='period'>.</span><span class='id identifier rubyid_each'>each</span> <span class='lbrace'>{</span> <span class='op'>|</span><span class='id identifier rubyid_filename'>filename</span><span class='op'>|</span> <span class='id identifier rubyid_require_relative'>require_relative</span> <span class='id identifier rubyid_filename'>filename</span> <span class='rbrace'>}</span></pre>
|
171
171
|
</td>
|
172
172
|
</tr>
|
173
173
|
</table>
|
@@ -178,9 +178,9 @@
|
|
178
178
|
</div>
|
179
179
|
|
180
180
|
<div id="footer">
|
181
|
-
Generated on
|
181
|
+
Generated on Sat Jan 2 17:31:17 2021 by
|
182
182
|
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
183
|
-
0.9.
|
183
|
+
0.9.26 (ruby-2.7.2).
|
184
184
|
</div>
|
185
185
|
|
186
186
|
</div>
|
data/env_parser.gemspec
CHANGED
@@ -20,10 +20,14 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
21
|
spec.require_paths = ['lib']
|
22
22
|
|
23
|
-
spec.add_development_dependency 'bundler', '~>
|
24
|
-
spec.add_development_dependency 'rake'
|
23
|
+
spec.add_development_dependency 'bundler', '~> 2.0'
|
24
|
+
spec.add_development_dependency 'rake'
|
25
25
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
26
26
|
spec.add_development_dependency 'rspec_junit_formatter'
|
27
|
+
spec.add_development_dependency 'rubocop', '1.7'
|
28
|
+
spec.add_development_dependency 'yard'
|
27
29
|
|
28
30
|
spec.add_dependency 'activesupport', '>= 5.0.0'
|
31
|
+
spec.add_dependency 'chronic'
|
32
|
+
spec.add_dependency 'chronic_duration'
|
29
33
|
end
|
data/lib/env_parser.rb
CHANGED
@@ -1,61 +1,52 @@
|
|
1
|
+
require 'env_parser/errors'
|
1
2
|
require 'env_parser/version'
|
2
3
|
require 'active_support/all'
|
4
|
+
require 'psych'
|
3
5
|
|
4
6
|
## The EnvParser class simplifies parsing of environment variables as different data types.
|
5
7
|
##
|
6
8
|
class EnvParser
|
7
|
-
##
|
9
|
+
## The default filename to use for {.autoregister} requests.
|
8
10
|
##
|
9
|
-
|
10
|
-
end
|
11
|
-
|
12
|
-
## Exception class used to indicate parsed values not allowed per a "from_set" option.
|
13
|
-
##
|
14
|
-
class ValueNotAllowed < Error
|
15
|
-
end
|
16
|
-
|
17
|
-
## Exception class used to indicate a type has already been defined.
|
18
|
-
##
|
19
|
-
class TypeAlreadyDefined < Error
|
20
|
-
end
|
11
|
+
AUTOREGISTER_FILE = '.env_parser.yml'.freeze
|
21
12
|
|
22
13
|
class << self
|
23
|
-
## Defines a new type for use as the "as" option on a subsequent
|
14
|
+
## Defines a new type for use as the "as" option on a subsequent {.parse} or {.register} call.
|
24
15
|
##
|
25
16
|
## @param name [Symbol]
|
26
17
|
## The name to assign to the type.
|
27
18
|
##
|
28
|
-
## @option options
|
19
|
+
## @option options [Array<Symbol>] aliases
|
29
20
|
## An array of additional names you'd like to see refer to this same type.
|
30
21
|
##
|
31
|
-
## @option options if_unset
|
22
|
+
## @option options if_unset (nil)
|
32
23
|
## Specifies a "sensible default" to return for this type if the value being parsed (via
|
33
|
-
##
|
34
|
-
## overridden by the user via the
|
24
|
+
## {.parse} or {.register}) is either unset (`nil`) or blank (`''`). Note this may be
|
25
|
+
## overridden by the user via the {.parse}/{.register} "if_unset" option.
|
35
26
|
##
|
36
|
-
## @yield
|
27
|
+
## @yield [value]
|
37
28
|
## A block to act as the parser for the this type. If no block is given, an ArgumentError is
|
38
29
|
## raised.
|
39
30
|
##
|
40
|
-
## When the type defined is used via a
|
31
|
+
## When the type defined is used via a {.parse}/{.register} call, this block is invoked with
|
41
32
|
## the value to be parsed. Said value is guaranteed to be a non-empty String (the "if_unset"
|
42
33
|
## check will have already run), but no other assurances as to content are given. The block
|
43
34
|
## should return the final output of parsing the given String value as the type being defined.
|
44
35
|
##
|
45
36
|
## If the value given cannot be sensibly parsed into the type defined, the block should raise
|
46
|
-
## an EnvParser::
|
37
|
+
## an {EnvParser::ValueNotConvertibleError}.
|
47
38
|
##
|
48
39
|
## @return [nil]
|
49
40
|
## This generates no usable value.
|
50
41
|
##
|
51
|
-
## @raise [ArgumentError, EnvParser::
|
42
|
+
## @raise [ArgumentError, EnvParser::TypeAlreadyDefinedError]
|
52
43
|
##
|
53
44
|
def define_type(name, options = {}, &parser)
|
54
45
|
raise(ArgumentError, 'no parsing block given') unless block_given?
|
55
46
|
|
56
47
|
given_types = (Array(name) + Array(options[:aliases])).map(&:to_s).map(&:to_sym)
|
57
48
|
given_types.each do |type|
|
58
|
-
raise(
|
49
|
+
raise(TypeAlreadyDefinedError, "cannot redefine #{type.inspect}") if known_types.key?(type)
|
59
50
|
|
60
51
|
known_types[type] = {
|
61
52
|
parser: parser,
|
@@ -72,12 +63,13 @@ class EnvParser
|
|
72
63
|
## The value to parse/interpret. If a String is given, the value will be used as-is. If a
|
73
64
|
## Symbol is given, the ENV value for the matching string key will be used.
|
74
65
|
##
|
75
|
-
## @option options
|
66
|
+
## @option options [Symbol] as
|
76
67
|
## The expected return type. A best-effort attempt is made to convert the source String to the
|
77
68
|
## requested type.
|
78
69
|
##
|
79
|
-
## If no "as" option is given
|
80
|
-
##
|
70
|
+
## If no "as" option is given, an ArgumentError is raised. If the "as" option given is unknown
|
71
|
+
## (the given type has not been previously defined via {.define_type}), an
|
72
|
+
## {EnvParser::UnknownTypeError} is raised.
|
81
73
|
##
|
82
74
|
## @option options if_unset
|
83
75
|
## Specifies the default value to return if the given "value" is either unset (`nil`) or blank
|
@@ -85,43 +77,45 @@ class EnvParser
|
|
85
77
|
## change having been made. If unspecified, the "default" value for `nil`/`''` input will
|
86
78
|
## depend on the "as" type.
|
87
79
|
##
|
88
|
-
## @option options
|
80
|
+
## @option options [Array, Range] from_set
|
89
81
|
## Gives a limited set of allowed values (after type conversion). If, after parsing, the final
|
90
|
-
## value is not included in the "from_set" list/range, an EnvParser::
|
91
|
-
##
|
82
|
+
## value is not included in the "from_set" list/range, an {EnvParser::ValueNotAllowedError} is
|
83
|
+
## raised.
|
92
84
|
##
|
93
85
|
## Note that if the "if_unset" option is given and the value to parse is `nil`/`''`, the
|
94
86
|
## "if_unset" value will be returned, even if it is not part of the "from_set" list/range.
|
95
87
|
##
|
96
88
|
## Also note that, due to the nature of the lookup, the "from_set" option is only available
|
97
89
|
## for scalar values (i.e. not arrays, hashes, or other enumerables). An attempt to use the
|
98
|
-
## "from_set" option with a non-scalar value will raise an ArgumentError
|
90
|
+
## "from_set" option with a non-scalar value will raise an ArgumentError.
|
99
91
|
##
|
100
|
-
## @option options
|
101
|
-
## If given, the "validated_by"
|
92
|
+
## @option options [Proc] validated_by
|
93
|
+
## If given, the "validated_by" Proc is called with the parsed value (after type conversion)
|
102
94
|
## as its sole argument. This allows for user-defined validation of the parsed value beyond
|
103
|
-
## what can be enforced by use of the "from_set" option alone. If the
|
104
|
-
## `#blank?`, an EnvParser::
|
105
|
-
## choice, this validation
|
95
|
+
## what can be enforced by use of the "from_set" option alone. If the Proc's return value is
|
96
|
+
## `#blank?`, an {EnvParser::ValueNotAllowedError} is raised. To accomodate your syntax of
|
97
|
+
## choice, this validation Proc may be given as a block instead.
|
106
98
|
##
|
107
99
|
## Note that this option is intended to provide an inspection mechanism only -- no mutation
|
108
|
-
## of the parsed value should occur within the given
|
100
|
+
## of the parsed value should occur within the given Proc. To that end, the argument passed is
|
109
101
|
## a *frozen* duplicate of the parsed value.
|
110
102
|
##
|
111
103
|
## @yield [value]
|
112
|
-
## A block (if given) is treated exactly as the "validated_by" Proc would.
|
113
|
-
## no compelling reason to provide both a "validated_by" proc *and* a validation block, there
|
114
|
-
## is no technical limitation preventing this. **If both are given, both validation checks
|
115
|
-
## must pass.**
|
104
|
+
## A block (if given) is treated exactly as the "validated_by" Proc would.
|
116
105
|
##
|
117
|
-
##
|
106
|
+
## Although there is no compelling reason to provide both a "validated_by" Proc *and* a
|
107
|
+
## validation block, there is no technical limitation preventing this. **If both are given,
|
108
|
+
## both validation checks must pass.**
|
109
|
+
##
|
110
|
+
## @raise [ArgumentError, EnvParser::UnknownTypeError, EnvParser::ValueNotAllowedError]
|
118
111
|
##
|
119
112
|
def parse(value, options = {}, &validation_block)
|
120
113
|
value = ENV[value.to_s] if value.is_a? Symbol
|
121
114
|
value = value.to_s
|
122
115
|
|
123
116
|
type = known_types[options[:as]]
|
124
|
-
raise(ArgumentError,
|
117
|
+
raise(ArgumentError, 'missing `as` parameter') unless options.key?(:as)
|
118
|
+
raise(UnknownTypeError, "invalid `as` parameter: #{options[:as].inspect}") unless type
|
125
119
|
|
126
120
|
return (options.key?(:if_unset) ? options[:if_unset] : type[:if_unset]) if value.blank?
|
127
121
|
|
@@ -134,9 +128,8 @@ class EnvParser
|
|
134
128
|
|
135
129
|
## Parses the referenced value and creates a matching constant in the requested context.
|
136
130
|
##
|
137
|
-
## Multiple calls to
|
138
|
-
##
|
139
|
-
## "register" call.
|
131
|
+
## Multiple calls to {.register} may be shortcutted by passing in a Hash whose keys are the
|
132
|
+
## variable names and whose values are the options set for each variable's {.register} call.
|
140
133
|
##
|
141
134
|
## <pre>
|
142
135
|
## ## Example shortcut usage:
|
@@ -153,40 +146,39 @@ class EnvParser
|
|
153
146
|
## </pre>
|
154
147
|
##
|
155
148
|
## @param name
|
156
|
-
## The name of the value to parse/interpret from the "from" Hash. If the "from" value is
|
157
|
-
## you may give a Symbol and the corresponding String key will be used instead.
|
149
|
+
## The name of the value to parse/interpret from the "from" Hash. If the "from" value is
|
150
|
+
## `ENV`, you may give a Symbol and the corresponding String key will be used instead.
|
158
151
|
##
|
159
|
-
## @option options
|
160
|
-
## The source Hash from which to pull the value referenced by the "name" key.
|
152
|
+
## @option options [Hash] from (ENV)
|
153
|
+
## The source Hash from which to pull the value referenced by the "name" key.
|
161
154
|
##
|
162
|
-
## @option options
|
163
|
-
## The module or class in which the constant should be created.
|
164
|
-
##
|
155
|
+
## @option options [Module, Class] within (Kernel)
|
156
|
+
## The module or class in which the constant should be created. Creates global constants by
|
157
|
+
## default.
|
165
158
|
##
|
166
|
-
## @option options
|
167
|
-
## See
|
159
|
+
## @option options [Symbol] as
|
160
|
+
## See {.parse}.
|
168
161
|
##
|
169
162
|
## @option options if_unset
|
170
|
-
## See
|
163
|
+
## See {.parse}.
|
171
164
|
##
|
172
|
-
## @option options
|
173
|
-
## See
|
165
|
+
## @option options [Array, Range] from_set
|
166
|
+
## See {.parse}.
|
174
167
|
##
|
175
|
-
## @option options
|
176
|
-
## See
|
168
|
+
## @option options [Proc] validated_by
|
169
|
+
## See {.parse}.
|
177
170
|
##
|
178
171
|
## @yield [value]
|
179
|
-
## A block (if given) is treated exactly as in
|
180
|
-
##
|
181
|
-
## validation must give its own "validated_by"
|
172
|
+
## A block (if given) is treated exactly as in {.parse}. Note, however, that a single block
|
173
|
+
## cannot be used to register multiple constants simultaneously -- each value needing
|
174
|
+
## validation must give its own "validated_by" Proc.
|
182
175
|
##
|
183
176
|
## @raise [ArgumentError]
|
184
177
|
##
|
185
178
|
def register(name, options = {}, &validation_block)
|
186
|
-
##
|
187
|
-
## method call.
|
179
|
+
## Allow for registering multiple variables simultaneously via a single call.
|
188
180
|
if name.is_a? Hash
|
189
|
-
raise
|
181
|
+
raise(ArgumentError, 'cannot register multiple values with one block') if block_given?
|
190
182
|
return register_all(name)
|
191
183
|
end
|
192
184
|
|
@@ -202,9 +194,7 @@ class EnvParser
|
|
202
194
|
name = name.to_s
|
203
195
|
end
|
204
196
|
|
205
|
-
unless from.is_a?
|
206
|
-
raise ArgumentError, "invalid `from` parameter: #{from.class}"
|
207
|
-
end
|
197
|
+
raise ArgumentError, "invalid `from` parameter: #{from.class}" unless from.is_a? Hash
|
208
198
|
|
209
199
|
unless within.is_a?(Module) || within.is_a?(Class)
|
210
200
|
raise ArgumentError, "invalid `within` parameter: #{within.inspect}"
|
@@ -217,14 +207,14 @@ class EnvParser
|
|
217
207
|
value
|
218
208
|
end
|
219
209
|
|
220
|
-
## Creates ENV bindings for
|
210
|
+
## Creates ENV bindings for {.parse} and {.register} proxy methods.
|
221
211
|
##
|
222
212
|
## The sole difference between these proxy methods and their EnvParser counterparts is that
|
223
213
|
## ENV.parse will interpret any value given as an ENV key (as a String), not the given value
|
224
214
|
## itself. i.e. ENV.parse('XYZ', ...) is equivalent to EnvParser.parse(ENV['XYZ'], ...)
|
225
215
|
##
|
226
216
|
## @return [ENV]
|
227
|
-
## This generates no usable value
|
217
|
+
## This generates no usable value.
|
228
218
|
##
|
229
219
|
def add_env_bindings
|
230
220
|
ENV.instance_eval do
|
@@ -240,6 +230,47 @@ class EnvParser
|
|
240
230
|
ENV
|
241
231
|
end
|
242
232
|
|
233
|
+
## Reads an "autoregister" file and registers the ENV constants defined therein.
|
234
|
+
##
|
235
|
+
## The "autoregister" file is read, parsed as YAML, sanitized for use as a parameter to
|
236
|
+
## {.register_all}, and then passed along for processing. The return value from that
|
237
|
+
## {.register_all} call is passed through.
|
238
|
+
##
|
239
|
+
## @param filename [String]
|
240
|
+
## A path for the autoregister file to parse and process. Defaults to
|
241
|
+
## {EnvParser::AUTOREGISTER_FILE} if unset.
|
242
|
+
##
|
243
|
+
## @return [Hash]
|
244
|
+
## The return value from the {.register_all} call that handles the actual registration.
|
245
|
+
##
|
246
|
+
## @raise [EnvParser::AutoregisterFileNotFound, EnvParser::UnparseableAutoregisterSpec]
|
247
|
+
##
|
248
|
+
def autoregister(filename = nil)
|
249
|
+
filename ||= AUTOREGISTER_FILE
|
250
|
+
autoregister_spec = Psych.load_file(filename)
|
251
|
+
|
252
|
+
autoregister_spec.deep_symbolize_keys!
|
253
|
+
autoregister_spec.transform_values! do |spec|
|
254
|
+
sanitized = spec.slice(:as, :within, :if_unset, :from_set)
|
255
|
+
sanitized[:as] = sanitized[:as].to_sym if sanitized.key? :as
|
256
|
+
sanitized[:within] = sanitized[:within].constantize if sanitized.key? :within
|
257
|
+
|
258
|
+
sanitized
|
259
|
+
end
|
260
|
+
|
261
|
+
register_all autoregister_spec
|
262
|
+
|
263
|
+
## Psych raises an Errno::ENOENT on file-not-found.
|
264
|
+
##
|
265
|
+
rescue Errno::ENOENT
|
266
|
+
raise EnvParser::AutoregisterFileNotFound, %(file not found: "#{filename}")
|
267
|
+
|
268
|
+
## Psych raises a Psych::SyntaxError on unparseable YAML.
|
269
|
+
##
|
270
|
+
rescue Psych::SyntaxError => e
|
271
|
+
raise EnvParser::UnparseableAutoregisterSpec, "malformed YAML in spec file: #{e.message}"
|
272
|
+
end
|
273
|
+
|
243
274
|
private
|
244
275
|
|
245
276
|
## Class instance variable for storing known type data.
|
@@ -256,7 +287,7 @@ class EnvParser
|
|
256
287
|
## @return [nil]
|
257
288
|
## This generates no usable value.
|
258
289
|
##
|
259
|
-
## @raise [ArgumentError, EnvParser::
|
290
|
+
## @raise [ArgumentError, EnvParser::ValueNotAllowedError]
|
260
291
|
##
|
261
292
|
def check_for_set_inclusion(value, set: nil)
|
262
293
|
if value.respond_to?(:each)
|
@@ -267,9 +298,7 @@ class EnvParser
|
|
267
298
|
raise ArgumentError, "invalid `from_set` parameter type: #{set.class}"
|
268
299
|
end
|
269
300
|
|
270
|
-
raise
|
271
|
-
|
272
|
-
nil
|
301
|
+
raise(ValueNotAllowedError, 'parsed value not in allowed set') unless set.include?(value)
|
273
302
|
end
|
274
303
|
|
275
304
|
## Verifies that the given "value" passes both the "proc" and "block" validations.
|
@@ -281,18 +310,17 @@ class EnvParser
|
|
281
310
|
## @return [nil]
|
282
311
|
## This generates no usable value.
|
283
312
|
##
|
284
|
-
## @raise [EnvParser::
|
313
|
+
## @raise [EnvParser::ValueNotAllowedError]
|
285
314
|
##
|
286
315
|
def check_user_defined_validations(value, proc: nil, block: nil)
|
287
316
|
immutable_value = value.dup.freeze
|
288
|
-
|
289
|
-
raise ValueNotAllowed, error unless [proc, block].compact.all? { |i| i.call(immutable_value) }
|
317
|
+
all_tests_passed = [proc, block].compact.all? { |i| i.call(immutable_value) }
|
290
318
|
|
291
|
-
|
319
|
+
raise(ValueNotAllowedError, 'parsed value failed user validation') unless all_tests_passed
|
292
320
|
end
|
293
321
|
|
294
|
-
## Receives a list of
|
295
|
-
## values being each
|
322
|
+
## Receives a list of {.register} calls to make, as a Hash keyed with variable names and the
|
323
|
+
## values being each {.register} call's option set.
|
296
324
|
##
|
297
325
|
## @param list [Hash]
|
298
326
|
##
|
@@ -301,7 +329,7 @@ class EnvParser
|
|
301
329
|
## @raise [ArgumentError]
|
302
330
|
##
|
303
331
|
def register_all(list)
|
304
|
-
raise
|
332
|
+
raise(ArgumentError, "invalid 'list' parameter type: #{list.class}") unless list.is_a? Hash
|
305
333
|
|
306
334
|
list.to_a.each_with_object({}) do |tuple, output|
|
307
335
|
output[tuple.first] = register(tuple.first, tuple.second)
|
@@ -310,6 +338,6 @@ class EnvParser
|
|
310
338
|
end
|
311
339
|
end
|
312
340
|
|
313
|
-
## Load
|
341
|
+
## Load predefined types.
|
314
342
|
##
|
315
|
-
|
343
|
+
require 'env_parser/types'
|