anyway_config 2.1.0 → 2.2.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/CHANGELOG.md +34 -0
- data/README.md +162 -4
- data/lib/.rbnext/1995.next/anyway/config.rb +48 -1
- data/lib/.rbnext/1995.next/anyway/dynamic_config.rb +6 -2
- data/lib/.rbnext/1995.next/anyway/tracing.rb +2 -2
- data/lib/.rbnext/2.7/anyway/auto_cast.rb +39 -19
- data/lib/.rbnext/2.7/anyway/config.rb +48 -1
- data/lib/.rbnext/2.7/anyway/rbs.rb +92 -0
- data/lib/.rbnext/2.7/anyway/tracing.rb +5 -7
- data/lib/.rbnext/2.7/anyway/type_casting.rb +130 -0
- data/lib/.rbnext/3.0/anyway/auto_cast.rb +53 -0
- data/lib/.rbnext/3.0/anyway/config.rb +48 -1
- data/lib/.rbnext/3.0/anyway/tracing.rb +5 -7
- data/lib/anyway/auto_cast.rb +39 -19
- data/lib/anyway/config.rb +48 -1
- data/lib/anyway/dynamic_config.rb +6 -2
- data/lib/anyway/ext/deep_dup.rb +6 -0
- data/lib/anyway/ext/hash.rb +10 -0
- data/lib/anyway/loaders/env.rb +3 -1
- data/lib/anyway/loaders/yaml.rb +6 -2
- data/lib/anyway/option_parser_builder.rb +1 -3
- data/lib/anyway/optparse_config.rb +5 -7
- data/lib/anyway/rails/loaders/credentials.rb +2 -2
- data/lib/anyway/rails/loaders/secrets.rb +5 -7
- data/lib/anyway/rails/settings.rb +3 -2
- data/lib/anyway/rbs.rb +92 -0
- data/lib/anyway/tracing.rb +2 -2
- data/lib/anyway/type_casting.rb +121 -0
- data/lib/anyway/version.rb +1 -1
- data/lib/anyway_config.rb +2 -0
- data/sig/anyway_config.rbs +123 -0
- metadata +28 -9
- data/lib/.rbnext/2.7/anyway/option_parser_builder.rb +0 -31
data/lib/anyway/rbs.rb
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Anyway
|
4
|
+
module RBSGenerator
|
5
|
+
TYPE_TO_CLASS = {
|
6
|
+
string: "String",
|
7
|
+
integer: "Integer",
|
8
|
+
float: "Float",
|
9
|
+
date: "Date",
|
10
|
+
datetime: "DateTime",
|
11
|
+
uri: "URI",
|
12
|
+
boolean: "bool"
|
13
|
+
}.freeze
|
14
|
+
|
15
|
+
# Generate RBS signature from a config class
|
16
|
+
def to_rbs
|
17
|
+
*namespace, class_name = name.split("::")
|
18
|
+
|
19
|
+
buf = []
|
20
|
+
indent = 0
|
21
|
+
interface_name = "_Config"
|
22
|
+
|
23
|
+
if namespace.empty?
|
24
|
+
interface_name = "_#{class_name}"
|
25
|
+
else
|
26
|
+
buf << "module #{namespace.join("::")}"
|
27
|
+
indent += 1
|
28
|
+
end
|
29
|
+
|
30
|
+
# Using interface emulates a module we include to provide getters and setters
|
31
|
+
# (thus making `super` possible)
|
32
|
+
buf << "#{" " * indent}interface #{interface_name}"
|
33
|
+
indent += 1
|
34
|
+
|
35
|
+
# Generating setters and getters for config attributes
|
36
|
+
config_attributes.each do |param|
|
37
|
+
type = coercion_mapping[param] || defaults[param.to_s]
|
38
|
+
|
39
|
+
type =
|
40
|
+
case type
|
41
|
+
in NilClass
|
42
|
+
"untyped"
|
43
|
+
in Symbol
|
44
|
+
TYPE_TO_CLASS.fetch(type) { defaults[param] ? "Symbol" : "untyped" }
|
45
|
+
in Array
|
46
|
+
"Array[untyped]"
|
47
|
+
in array:, type:, **nil
|
48
|
+
"Array[#{TYPE_TO_CLASS.fetch(type, "untyped")}]"
|
49
|
+
in Hash
|
50
|
+
"Hash[string,untyped]"
|
51
|
+
in TrueClass | FalseClass
|
52
|
+
"bool"
|
53
|
+
else
|
54
|
+
type.class.to_s
|
55
|
+
end
|
56
|
+
|
57
|
+
getter_type = type
|
58
|
+
getter_type = "#{type}?" unless required_attributes.include?(param)
|
59
|
+
|
60
|
+
buf << "#{" " * indent}def #{param}: () -> #{getter_type}"
|
61
|
+
buf << "#{" " * indent}def #{param}=: (#{type}) -> void"
|
62
|
+
|
63
|
+
if type == "bool" || type == "bool?"
|
64
|
+
buf << "#{" " * indent}def #{param}?: () -> #{getter_type}"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
indent -= 1
|
69
|
+
buf << "#{" " * indent}end"
|
70
|
+
|
71
|
+
buf << ""
|
72
|
+
|
73
|
+
buf << "#{" " * indent}class #{class_name} < #{superclass.name}"
|
74
|
+
indent += 1
|
75
|
+
|
76
|
+
buf << "#{" " * indent}include #{interface_name}"
|
77
|
+
|
78
|
+
indent -= 1
|
79
|
+
buf << "#{" " * indent}end"
|
80
|
+
|
81
|
+
unless namespace.empty?
|
82
|
+
buf << "end"
|
83
|
+
end
|
84
|
+
|
85
|
+
buf << ""
|
86
|
+
|
87
|
+
buf.join("\n")
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
Config.extend RBSGenerator
|
92
|
+
end
|
data/lib/anyway/tracing.rb
CHANGED
@@ -34,11 +34,11 @@ module Anyway
|
|
34
34
|
|
35
35
|
def record_value(val, *path, **opts)
|
36
36
|
key = path.pop
|
37
|
-
if val.is_a?(Hash)
|
37
|
+
trace = if val.is_a?(Hash)
|
38
38
|
Trace.new.tap { _1.merge_values(val, **opts) }
|
39
39
|
else
|
40
40
|
Trace.new(:value, val, **opts)
|
41
|
-
end
|
41
|
+
end
|
42
42
|
|
43
43
|
target_trace = path.empty? ? self : value.dig(*path)
|
44
44
|
target_trace.value[key.to_s] = trace
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Anyway
|
4
|
+
# Contains a mapping between type IDs/names and deserializers
|
5
|
+
class TypeRegistry
|
6
|
+
class << self
|
7
|
+
def default
|
8
|
+
@default ||= TypeRegistry.new
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@registry = {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def accept(name_or_object, &block)
|
17
|
+
if !block && !name_or_object.respond_to?(:call)
|
18
|
+
raise ArgumentError, "Please, provide a type casting block or an object implementing #call(val) method"
|
19
|
+
end
|
20
|
+
|
21
|
+
registry[name_or_object] = block || name_or_object
|
22
|
+
end
|
23
|
+
|
24
|
+
def deserialize(raw, type_id, array: false)
|
25
|
+
caster =
|
26
|
+
if type_id.is_a?(Symbol)
|
27
|
+
registry.fetch(type_id) { raise ArgumentError, "Unknown type: #{type_id}" }
|
28
|
+
else
|
29
|
+
raise ArgumentError, "Type must implement #call(val): #{type_id}" unless type_id.respond_to?(:call)
|
30
|
+
type_id
|
31
|
+
end
|
32
|
+
|
33
|
+
if array
|
34
|
+
raw_arr = raw.is_a?(Array) ? raw : raw.split(/\s*,\s*/)
|
35
|
+
raw_arr.map { caster.call(_1) }
|
36
|
+
else
|
37
|
+
caster.call(raw)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def dup
|
42
|
+
new_obj = self.class.allocate
|
43
|
+
new_obj.instance_variable_set(:@registry, registry.dup)
|
44
|
+
new_obj
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
attr_reader :registry
|
50
|
+
end
|
51
|
+
|
52
|
+
TypeRegistry.default.tap do |obj|
|
53
|
+
obj.accept(:string, &:to_s)
|
54
|
+
obj.accept(:integer, &:to_i)
|
55
|
+
obj.accept(:float, &:to_f)
|
56
|
+
|
57
|
+
obj.accept(:date) do
|
58
|
+
require "date" unless defined?(::Date)
|
59
|
+
|
60
|
+
Date.parse(_1)
|
61
|
+
end
|
62
|
+
|
63
|
+
obj.accept(:datetime) do
|
64
|
+
require "date" unless defined?(::Date)
|
65
|
+
|
66
|
+
DateTime.parse(_1)
|
67
|
+
end
|
68
|
+
|
69
|
+
obj.accept(:uri) do
|
70
|
+
require "uri" unless defined?(::URI)
|
71
|
+
|
72
|
+
URI.parse(_1)
|
73
|
+
end
|
74
|
+
|
75
|
+
obj.accept(:boolean) do
|
76
|
+
_1.match?(/\A(true|t|yes|y|1)\z/i)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# TypeCaster is an object responsible for type-casting.
|
81
|
+
# It uses a provided types registry and mapping, and also
|
82
|
+
# accepts a fallback typecaster.
|
83
|
+
class TypeCaster
|
84
|
+
using Ext::DeepDup
|
85
|
+
using Ext::Hash
|
86
|
+
|
87
|
+
def initialize(mapping, registry: TypeRegistry.default, fallback: ::Anyway::AutoCast)
|
88
|
+
@mapping = mapping.deep_dup
|
89
|
+
@registry = registry
|
90
|
+
@fallback = fallback
|
91
|
+
end
|
92
|
+
|
93
|
+
def coerce(key, val, config: mapping)
|
94
|
+
caster_config = config[key.to_sym]
|
95
|
+
|
96
|
+
return fallback.coerce(key, val) unless caster_config
|
97
|
+
|
98
|
+
case caster_config
|
99
|
+
in array:, type:, **nil
|
100
|
+
registry.deserialize(val, type, array: array)
|
101
|
+
in Hash
|
102
|
+
return val unless val.is_a?(Hash)
|
103
|
+
|
104
|
+
caster_config.each do |k, v|
|
105
|
+
ks = k.to_s
|
106
|
+
next unless val.key?(ks)
|
107
|
+
|
108
|
+
val[ks] = coerce(k, val[ks], config: caster_config)
|
109
|
+
end
|
110
|
+
|
111
|
+
val
|
112
|
+
else
|
113
|
+
registry.deserialize(val, caster_config)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
private
|
118
|
+
|
119
|
+
attr_reader :mapping, :registry, :fallback
|
120
|
+
end
|
121
|
+
end
|
data/lib/anyway/version.rb
CHANGED
data/lib/anyway_config.rb
CHANGED
@@ -17,8 +17,10 @@ require "anyway/settings"
|
|
17
17
|
require "anyway/tracing"
|
18
18
|
require "anyway/config"
|
19
19
|
require "anyway/auto_cast"
|
20
|
+
require "anyway/type_casting"
|
20
21
|
require "anyway/env"
|
21
22
|
require "anyway/loaders"
|
23
|
+
require "anyway/rbs"
|
22
24
|
|
23
25
|
module Anyway # :nodoc:
|
24
26
|
class << self
|
@@ -0,0 +1,123 @@
|
|
1
|
+
module Anyway
|
2
|
+
def self.env: -> Env
|
3
|
+
def self.loaders: -> Loaders::Registry
|
4
|
+
|
5
|
+
class Settings
|
6
|
+
def self.default_config_path=: (^(untyped) -> String val) -> ^(untyped) -> String?
|
7
|
+
def self.future: -> Future
|
8
|
+
|
9
|
+
class Future
|
10
|
+
def self.setting: (untyped name, untyped default_value) -> untyped
|
11
|
+
def self.settings: -> Hash[untyped, untyped]
|
12
|
+
def use: (*untyped names) -> untyped
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module Tracing
|
17
|
+
class Trace
|
18
|
+
def merge!: (Trace another_trace) -> void
|
19
|
+
end
|
20
|
+
|
21
|
+
def inspect: -> String
|
22
|
+
def self.capture: ?{ -> Hash[untyped, untyped] } -> nil
|
23
|
+
def self.trace_stack: -> Array[untyped]
|
24
|
+
def self.current_trace: -> Trace?
|
25
|
+
def self.source_stack: -> Array[untyped]
|
26
|
+
def self.current_trace_source: -> {type: :accessor, called_from: untyped}
|
27
|
+
def self.with_trace_source: (untyped src) -> untyped
|
28
|
+
def trace!: (Symbol, *Array[String] paths, **untyped) ?{ -> Hash[untyped, untyped]} -> Hash[untyped, untyped]
|
29
|
+
def self.trace!: (Symbol, *Array[String] paths, **untyped) ?{ -> Hash[untyped, untyped]} -> Hash[untyped, untyped]
|
30
|
+
end
|
31
|
+
|
32
|
+
module RBSGenerator
|
33
|
+
def to_rbs: -> String
|
34
|
+
end
|
35
|
+
|
36
|
+
module OptparseConfig
|
37
|
+
def option_parser: -> OptionParser
|
38
|
+
def parse_options!: (Array[String]) -> void
|
39
|
+
|
40
|
+
module ClassMethods
|
41
|
+
def ignore_options: (*Symbol args) -> void
|
42
|
+
def describe_options: (**(String | {desc: String, type: Module})) -> void
|
43
|
+
def flag_options: (*Symbol args) -> void
|
44
|
+
def extend_options: { (OptionParser, Config) -> void } -> void
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
module DynamicConfig
|
49
|
+
module ClassMethods
|
50
|
+
def for: (String | Symbol name, ?auto_cast: bool, **untyped) -> Hash[untyped, untyped]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class Config
|
55
|
+
extend RBSGenerator
|
56
|
+
extend DynamicConfig::ClassMethods
|
57
|
+
extend OptparseConfig::ClassMethods
|
58
|
+
include DynamicConfig
|
59
|
+
include OptparseConfig
|
60
|
+
|
61
|
+
def self.attr_config: (*Symbol args, **untyped) -> void
|
62
|
+
def self.defaults: -> Hash[String, untyped]
|
63
|
+
def self.config_attributes: -> Array[Symbol]?
|
64
|
+
def self.required: (*Symbol names) -> void
|
65
|
+
def self.required_attributes: -> Array[Symbol]
|
66
|
+
def self.on_load: (*Symbol callbacks) ?{ () -> void } -> void
|
67
|
+
def self.config_name: (?(Symbol | String) val) -> String?
|
68
|
+
def self.env_prefix: (?(Symbol | String) val) -> String
|
69
|
+
def self.coerce_types: (untyped mapping) -> untyped
|
70
|
+
def self.coercion_mapping: -> Hash[untyped, untyped]?
|
71
|
+
def self.disable_auto_cast!: -> void
|
72
|
+
|
73
|
+
attr_reader config_name: String
|
74
|
+
attr_reader env_prefix: String
|
75
|
+
|
76
|
+
def initialize: (?Hash[Symbol | String, untyped] overrides) -> void
|
77
|
+
def reload: (?Hash[Symbol | String, untyped] overrides) -> Config
|
78
|
+
def clear: -> void
|
79
|
+
def load: (Hash[Symbol | String, untyped] overrides) -> Config
|
80
|
+
def dig: (*(Symbol | String) keys) -> untyped
|
81
|
+
def to_h: -> Hash[untyped, untyped]
|
82
|
+
def dup: -> Config
|
83
|
+
def deconstruct_keys: (untyped keys) -> Hash[untyped, untyped]
|
84
|
+
def to_source_trace: -> Hash[String, untyped]
|
85
|
+
def inspect: -> String
|
86
|
+
def pretty_print: (untyped q) -> untyped
|
87
|
+
|
88
|
+
private
|
89
|
+
attr_reader values: Hash[untyped, untyped]
|
90
|
+
def raise_validation_error: (String msg) -> void
|
91
|
+
|
92
|
+
class Error < StandardError
|
93
|
+
end
|
94
|
+
|
95
|
+
class ValidationError < Error
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
class Env
|
100
|
+
def clear: -> void
|
101
|
+
def fetch: (String prefix) -> untyped
|
102
|
+
def fetch_with_trace: (String prefix) -> [untyped, Tracing::Trace?]
|
103
|
+
end
|
104
|
+
|
105
|
+
module Loaders
|
106
|
+
class Base
|
107
|
+
include Tracing
|
108
|
+
|
109
|
+
def self.call: (?local: bool, **untyped) -> untyped
|
110
|
+
def initialize: (local: bool) -> void
|
111
|
+
def use_local?: -> bool
|
112
|
+
end
|
113
|
+
|
114
|
+
class Registry
|
115
|
+
def prepend: (Symbol id, Base loader) -> void
|
116
|
+
def append: (Symbol id, Base loader) -> void
|
117
|
+
def insert_before: (Symbol another_id, Symbol id, Base loader) -> void
|
118
|
+
def insert_after: (Symbol another_id, Symbol id, Base loader) -> void
|
119
|
+
def override: (Symbol id, Base loader) -> void
|
120
|
+
def delete: (Symbol id) -> void
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: anyway_config
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vladimir Dementyev
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-09-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby-next-core
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.13.1
|
20
20
|
type: :runtime
|
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: 0.
|
26
|
+
version: 0.13.1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: ammeter
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,6 +94,20 @@ dependencies:
|
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0.8'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: steep
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
97
111
|
description: "\n Configuration DSL for Ruby libraries and applications.\n Allows
|
98
112
|
you to easily follow the twelve-factor application principles (https://12factor.net/config).\n
|
99
113
|
\ "
|
@@ -113,10 +127,12 @@ files:
|
|
113
127
|
- lib/.rbnext/1995.next/anyway/tracing.rb
|
114
128
|
- lib/.rbnext/2.7/anyway/auto_cast.rb
|
115
129
|
- lib/.rbnext/2.7/anyway/config.rb
|
116
|
-
- lib/.rbnext/2.7/anyway/option_parser_builder.rb
|
117
130
|
- lib/.rbnext/2.7/anyway/rails/loaders/yaml.rb
|
131
|
+
- lib/.rbnext/2.7/anyway/rbs.rb
|
118
132
|
- lib/.rbnext/2.7/anyway/settings.rb
|
119
133
|
- lib/.rbnext/2.7/anyway/tracing.rb
|
134
|
+
- lib/.rbnext/2.7/anyway/type_casting.rb
|
135
|
+
- lib/.rbnext/3.0/anyway/auto_cast.rb
|
120
136
|
- lib/.rbnext/3.0/anyway/config.rb
|
121
137
|
- lib/.rbnext/3.0/anyway/loaders.rb
|
122
138
|
- lib/.rbnext/3.0/anyway/loaders/base.rb
|
@@ -143,10 +159,12 @@ files:
|
|
143
159
|
- lib/anyway/rails/loaders/yaml.rb
|
144
160
|
- lib/anyway/rails/settings.rb
|
145
161
|
- lib/anyway/railtie.rb
|
162
|
+
- lib/anyway/rbs.rb
|
146
163
|
- lib/anyway/settings.rb
|
147
164
|
- lib/anyway/testing.rb
|
148
165
|
- lib/anyway/testing/helpers.rb
|
149
166
|
- lib/anyway/tracing.rb
|
167
|
+
- lib/anyway/type_casting.rb
|
150
168
|
- lib/anyway/utils/deep_merge.rb
|
151
169
|
- lib/anyway/version.rb
|
152
170
|
- lib/anyway_config.rb
|
@@ -159,6 +177,7 @@ files:
|
|
159
177
|
- lib/generators/anyway/install/USAGE
|
160
178
|
- lib/generators/anyway/install/install_generator.rb
|
161
179
|
- lib/generators/anyway/install/templates/application_config.rb.tt
|
180
|
+
- sig/anyway_config.rbs
|
162
181
|
homepage: http://github.com/palkan/anyway_config
|
163
182
|
licenses:
|
164
183
|
- MIT
|
@@ -168,7 +187,7 @@ metadata:
|
|
168
187
|
documentation_uri: http://github.com/palkan/anyway_config
|
169
188
|
homepage_uri: http://github.com/palkan/anyway_config
|
170
189
|
source_code_uri: http://github.com/palkan/anyway_config
|
171
|
-
post_install_message:
|
190
|
+
post_install_message:
|
172
191
|
rdoc_options: []
|
173
192
|
require_paths:
|
174
193
|
- lib
|
@@ -183,8 +202,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
183
202
|
- !ruby/object:Gem::Version
|
184
203
|
version: '0'
|
185
204
|
requirements: []
|
186
|
-
rubygems_version: 3.
|
187
|
-
signing_key:
|
205
|
+
rubygems_version: 3.2.22
|
206
|
+
signing_key:
|
188
207
|
specification_version: 4
|
189
208
|
summary: Configuration DSL for Ruby libraries and applications
|
190
209
|
test_files: []
|
@@ -1,31 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "optparse"
|
4
|
-
|
5
|
-
module Anyway # :nodoc:
|
6
|
-
# Initializes the OptionParser instance using the given configuration
|
7
|
-
class OptionParserBuilder
|
8
|
-
class << self
|
9
|
-
def call(options)
|
10
|
-
OptionParser.new do |opts|
|
11
|
-
opts.accept(AutoCast) { |_1| AutoCast.call(_1) }
|
12
|
-
|
13
|
-
options.each do |key, descriptor|
|
14
|
-
opts.on(*option_parser_on_args(key, **descriptor)) do |val|
|
15
|
-
yield [key, val]
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def option_parser_on_args(key, flag: false, desc: nil, type: AutoCast)
|
24
|
-
on_args = ["--#{key.to_s.tr("_", "-")}#{flag ? "" : " VALUE"}"]
|
25
|
-
on_args << type unless flag
|
26
|
-
on_args << desc unless desc.nil?
|
27
|
-
on_args
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|