anyway_config 2.0.5 → 2.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +241 -181
  3. data/README.md +238 -13
  4. data/lib/.rbnext/1995.next/anyway/config.rb +438 -0
  5. data/lib/.rbnext/1995.next/anyway/dynamic_config.rb +31 -0
  6. data/lib/.rbnext/1995.next/anyway/env.rb +56 -0
  7. data/lib/.rbnext/1995.next/anyway/loaders/base.rb +21 -0
  8. data/lib/.rbnext/1995.next/anyway/tracing.rb +181 -0
  9. data/lib/.rbnext/2.7/anyway/auto_cast.rb +39 -19
  10. data/lib/.rbnext/2.7/anyway/config.rb +61 -16
  11. data/lib/.rbnext/2.7/anyway/rails/loaders/yaml.rb +30 -0
  12. data/lib/.rbnext/2.7/anyway/rbs.rb +92 -0
  13. data/lib/.rbnext/2.7/anyway/settings.rb +79 -0
  14. data/lib/.rbnext/2.7/anyway/tracing.rb +6 -6
  15. data/lib/.rbnext/2.7/anyway/type_casting.rb +143 -0
  16. data/lib/.rbnext/3.0/anyway/auto_cast.rb +53 -0
  17. data/lib/.rbnext/{2.8 → 3.0}/anyway/config.rb +61 -16
  18. data/lib/.rbnext/{2.8 → 3.0}/anyway/loaders/base.rb +0 -0
  19. data/lib/.rbnext/{2.8 → 3.0}/anyway/loaders.rb +0 -0
  20. data/lib/.rbnext/{2.8 → 3.0}/anyway/tracing.rb +6 -6
  21. data/lib/anyway/auto_cast.rb +39 -19
  22. data/lib/anyway/config.rb +75 -30
  23. data/lib/anyway/dynamic_config.rb +6 -2
  24. data/lib/anyway/env.rb +1 -1
  25. data/lib/anyway/ext/deep_dup.rb +12 -0
  26. data/lib/anyway/ext/hash.rb +10 -12
  27. data/lib/anyway/loaders/base.rb +1 -1
  28. data/lib/anyway/loaders/env.rb +3 -1
  29. data/lib/anyway/loaders/yaml.rb +9 -5
  30. data/lib/anyway/option_parser_builder.rb +1 -3
  31. data/lib/anyway/optparse_config.rb +5 -7
  32. data/lib/anyway/rails/loaders/credentials.rb +4 -4
  33. data/lib/anyway/rails/loaders/secrets.rb +6 -8
  34. data/lib/anyway/rails/loaders/yaml.rb +11 -0
  35. data/lib/anyway/rails/settings.rb +9 -2
  36. data/lib/anyway/rbs.rb +92 -0
  37. data/lib/anyway/settings.rb +52 -2
  38. data/lib/anyway/tracing.rb +9 -9
  39. data/lib/anyway/type_casting.rb +134 -0
  40. data/lib/anyway/utils/deep_merge.rb +21 -0
  41. data/lib/anyway/version.rb +1 -1
  42. data/lib/anyway_config.rb +4 -0
  43. data/sig/anyway_config.rbs +129 -0
  44. metadata +42 -15
  45. data/lib/.rbnext/2.7/anyway/option_parser_builder.rb +0 -31
@@ -5,16 +5,66 @@ module Anyway
5
5
  #
6
6
  # Settings contain the library-wide configuration.
7
7
  class Settings
8
+ # Future encapsulates settings that will be introduced in the upcoming version
9
+ # with the default values, which could break compatibility
10
+ class Future
11
+ class << self
12
+ def setting(name, default_value)
13
+ settings[name] = default_value
14
+
15
+ define_method(name) do
16
+ store[name]
17
+ end
18
+
19
+ define_method(:"#{name}=") do |val|
20
+ store[name] = val
21
+ end
22
+ end
23
+
24
+ def settings
25
+ @settings ||= {}
26
+ end
27
+ end
28
+
29
+ def initialize
30
+ @store = {}
31
+ end
32
+
33
+ def use(*names)
34
+ store.clear
35
+ names.each { store[_1] = self.class.settings[_1] }
36
+ end
37
+
38
+ private
39
+
40
+ attr_reader :store
41
+ end
42
+
8
43
  class << self
9
44
  # Define whether to load data from
10
45
  # *.yml.local (or credentials/local.yml.enc)
11
46
  attr_accessor :use_local_files
12
47
 
13
- # Return a path to YML config file given the config name
14
- attr_accessor :default_config_path
48
+ # A proc returning a path to YML config file given the config name
49
+ attr_reader :default_config_path
50
+
51
+ def default_config_path=(val)
52
+ if val.is_a?(Proc)
53
+ @default_config_path = val
54
+ return
55
+ end
56
+
57
+ val = val.to_s
58
+
59
+ @default_config_path = ->(name) { File.join(val, "#{name}.yml") }
60
+ end
15
61
 
16
62
  # Enable source tracing
17
63
  attr_accessor :tracing_enabled
64
+
65
+ def future
66
+ @future ||= Future.new
67
+ end
18
68
  end
19
69
 
20
70
  # By default, use local files only in development (that's the purpose if the local files)
@@ -32,12 +32,13 @@ module Anyway
32
32
  value.dig(...)
33
33
  end
34
34
 
35
- def record_value(val, *path, key, **opts)
36
- if val.is_a?(Hash)
35
+ def record_value(val, *path, **opts)
36
+ key = path.pop
37
+ trace = if val.is_a?(Hash)
37
38
  Trace.new.tap { _1.merge_values(val, **opts) }
38
39
  else
39
40
  Trace.new(:value, val, **opts)
40
- end => trace
41
+ end
41
42
 
42
43
  target_trace = path.empty? ? self : value.dig(*path)
43
44
  target_trace.value[key.to_s] = trace
@@ -85,11 +86,11 @@ module Anyway
85
86
  if trace?
86
87
  value.transform_values(&:to_h).tap { _1.default_proc = nil }
87
88
  else
88
- {value: value, source: source}
89
+ {value, source}
89
90
  end
90
91
  end
91
92
 
92
- def dup() = self.class.new(type, value.dup, source)
93
+ def dup() = self.class.new(type, value.dup, **source)
93
94
 
94
95
  def pretty_print(q)
95
96
  if trace?
@@ -140,7 +141,7 @@ module Anyway
140
141
 
141
142
  def current_trace() = trace_stack.last
142
143
 
143
- alias tracing? current_trace
144
+ alias_method :tracing?, :current_trace
144
145
 
145
146
  def source_stack
146
147
  (Thread.current[:__anyway__trace_source_stack__] ||= [])
@@ -168,12 +169,11 @@ module Anyway
168
169
 
169
170
  def trace!(type, *path, **opts)
170
171
  return yield unless Tracing.tracing?
171
- source = {type: type}.merge(opts)
172
172
  val = yield
173
173
  if val.is_a?(Hash)
174
- Tracing.current_trace.merge_values(val, **source)
174
+ Tracing.current_trace.merge_values(val, type:, **opts)
175
175
  else
176
- Tracing.current_trace.record_value(val, *path, **source)
176
+ Tracing.current_trace.record_value(val, *path, type:, **opts)
177
177
  end
178
178
  val
179
179
  end
@@ -0,0 +1,134 @@
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
+ return if raw.nil?
26
+
27
+ caster =
28
+ if type_id.is_a?(Symbol) || type_id.nil?
29
+ registry.fetch(type_id) { raise ArgumentError, "Unknown type: #{type_id}" }
30
+ else
31
+ raise ArgumentError, "Type must implement #call(val): #{type_id}" unless type_id.respond_to?(:call)
32
+ type_id
33
+ end
34
+
35
+ if array
36
+ raw_arr = raw.is_a?(String) ? raw.split(/\s*,\s*/) : Array(raw)
37
+ raw_arr.map { caster.call(_1) }
38
+ else
39
+ caster.call(raw)
40
+ end
41
+ end
42
+
43
+ def dup
44
+ new_obj = self.class.allocate
45
+ new_obj.instance_variable_set(:@registry, registry.dup)
46
+ new_obj
47
+ end
48
+
49
+ private
50
+
51
+ attr_reader :registry
52
+ end
53
+
54
+ TypeRegistry.default.tap do |obj|
55
+ obj.accept(nil, &:itself)
56
+ obj.accept(:string, &:to_s)
57
+ obj.accept(:integer, &:to_i)
58
+ obj.accept(:float, &:to_f)
59
+
60
+ obj.accept(:date) do
61
+ require "date" unless defined?(::Date)
62
+
63
+ next _1 if _1.is_a?(::Date)
64
+
65
+ next _1.to_date if _1.respond_to?(:to_date)
66
+
67
+ ::Date.parse(_1)
68
+ end
69
+
70
+ obj.accept(:datetime) do
71
+ require "date" unless defined?(::Date)
72
+
73
+ next _1 if _1.is_a?(::DateTime)
74
+
75
+ next _1.to_datetime if _1.respond_to?(:to_datetime)
76
+
77
+ ::DateTime.parse(_1)
78
+ end
79
+
80
+ obj.accept(:uri) do
81
+ require "uri" unless defined?(::URI)
82
+
83
+ next _1 if _1.is_a?(::URI)
84
+
85
+ ::URI.parse(_1)
86
+ end
87
+
88
+ obj.accept(:boolean) do
89
+ _1.to_s.match?(/\A(true|t|yes|y|1)\z/i)
90
+ end
91
+ end
92
+
93
+ # TypeCaster is an object responsible for type-casting.
94
+ # It uses a provided types registry and mapping, and also
95
+ # accepts a fallback typecaster.
96
+ class TypeCaster
97
+ using Ext::DeepDup
98
+ using Ext::Hash
99
+
100
+ def initialize(mapping, registry: TypeRegistry.default, fallback: ::Anyway::AutoCast)
101
+ @mapping = mapping.deep_dup
102
+ @registry = registry
103
+ @fallback = fallback
104
+ end
105
+
106
+ def coerce(key, val, config: mapping)
107
+ caster_config = config[key.to_sym]
108
+
109
+ return fallback.coerce(key, val) unless caster_config
110
+
111
+ case caster_config
112
+ in array:, type:, **nil
113
+ registry.deserialize(val, type, array: array)
114
+ in Hash
115
+ return val unless val.is_a?(Hash)
116
+
117
+ caster_config.each do |k, v|
118
+ ks = k.to_s
119
+ next unless val.key?(ks)
120
+
121
+ val[ks] = coerce(k, val[ks], config: caster_config)
122
+ end
123
+
124
+ val
125
+ else
126
+ registry.deserialize(val, caster_config)
127
+ end
128
+ end
129
+
130
+ private
131
+
132
+ attr_reader :mapping, :registry, :fallback
133
+ end
134
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Anyway
4
+ using Anyway::Ext::DeepDup
5
+
6
+ module Utils
7
+ def self.deep_merge!(source, other)
8
+ other.each do |key, other_value|
9
+ this_value = source[key]
10
+
11
+ if this_value.is_a?(::Hash) && other_value.is_a?(::Hash)
12
+ deep_merge!(this_value, other_value)
13
+ else
14
+ source[key] = other_value.deep_dup
15
+ end
16
+ end
17
+
18
+ source
19
+ end
20
+ end
21
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Anyway # :nodoc:
4
- VERSION = "2.0.5"
4
+ VERSION = "2.2.1"
5
5
  end
data/lib/anyway_config.rb CHANGED
@@ -11,12 +11,16 @@ require "anyway/ext/deep_dup"
11
11
  require "anyway/ext/deep_freeze"
12
12
  require "anyway/ext/hash"
13
13
 
14
+ require "anyway/utils/deep_merge"
15
+
14
16
  require "anyway/settings"
15
17
  require "anyway/tracing"
16
18
  require "anyway/config"
17
19
  require "anyway/auto_cast"
20
+ require "anyway/type_casting"
18
21
  require "anyway/env"
19
22
  require "anyway/loaders"
23
+ require "anyway/rbs"
20
24
 
21
25
  module Anyway # :nodoc:
22
26
  class << self
@@ -0,0 +1,129 @@
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
+ type valueType = Symbol | nil
55
+ type arrayType = {array: bool, type: valueType}
56
+ type hashType = Hash[Symbol, valueType | arrayType | hashType]
57
+
58
+ type mappingType = valueType | arrayType | hashType
59
+
60
+ class Config
61
+ extend RBSGenerator
62
+ extend DynamicConfig::ClassMethods
63
+ extend OptparseConfig::ClassMethods
64
+ include DynamicConfig
65
+ include OptparseConfig
66
+
67
+ def self.attr_config: (*Symbol args, **untyped) -> void
68
+ def self.defaults: -> Hash[String, untyped]
69
+ def self.config_attributes: -> Array[Symbol]?
70
+ def self.required: (*Symbol names) -> void
71
+ def self.required_attributes: -> Array[Symbol]
72
+ def self.on_load: (*Symbol callbacks) ?{ () -> void } -> void
73
+ def self.config_name: (?(Symbol | String) val) -> String?
74
+ def self.env_prefix: (?(Symbol | String) val) -> String
75
+ def self.coerce_types: (**mappingType) -> void
76
+ def self.coercion_mapping: -> Hash[untyped, untyped]?
77
+ def self.disable_auto_cast!: -> void
78
+
79
+ attr_reader config_name: String
80
+ attr_reader env_prefix: String
81
+
82
+ def initialize: (?Hash[Symbol | String, untyped] overrides) -> void
83
+ def reload: (?Hash[Symbol | String, untyped] overrides) -> Config
84
+ def clear: -> void
85
+ def load: (Hash[Symbol | String, untyped] overrides) -> Config
86
+ def dig: (*(Symbol | String) keys) -> untyped
87
+ def to_h: -> Hash[untyped, untyped]
88
+ def dup: -> Config
89
+ def deconstruct_keys: (untyped keys) -> Hash[untyped, untyped]
90
+ def to_source_trace: -> Hash[String, untyped]
91
+ def inspect: -> String
92
+ def pretty_print: (untyped q) -> untyped
93
+
94
+ private
95
+ attr_reader values: Hash[untyped, untyped]
96
+ def raise_validation_error: (String msg) -> void
97
+
98
+ class Error < StandardError
99
+ end
100
+
101
+ class ValidationError < Error
102
+ end
103
+ end
104
+
105
+ class Env
106
+ def clear: -> void
107
+ def fetch: (String prefix) -> untyped
108
+ def fetch_with_trace: (String prefix) -> [untyped, Tracing::Trace?]
109
+ end
110
+
111
+ module Loaders
112
+ class Base
113
+ include Tracing
114
+
115
+ def self.call: (?local: bool, **untyped) -> untyped
116
+ def initialize: (local: bool) -> void
117
+ def use_local?: -> bool
118
+ end
119
+
120
+ class Registry
121
+ def prepend: (Symbol id, Base loader) -> void
122
+ def append: (Symbol id, Base loader) -> void
123
+ def insert_before: (Symbol another_id, Symbol id, Base loader) -> void
124
+ def insert_after: (Symbol another_id, Symbol id, Base loader) -> void
125
+ def override: (Symbol id, Base loader) -> void
126
+ def delete: (Symbol id) -> void
127
+ end
128
+ end
129
+ 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.0.5
4
+ version: 2.2.1
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: 2020-05-15 00:00:00.000000000 Z
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.8.0
19
+ version: 0.11.0
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.8.0
26
+ version: 0.11.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: ammeter
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -70,14 +70,14 @@ dependencies:
70
70
  name: rspec
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - "~>"
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: '3.8'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - "~>"
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '3.8'
83
83
  - !ruby/object:Gem::Dependency
@@ -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
  \ "
@@ -106,14 +120,23 @@ files:
106
120
  - CHANGELOG.md
107
121
  - LICENSE.txt
108
122
  - README.md
123
+ - lib/.rbnext/1995.next/anyway/config.rb
124
+ - lib/.rbnext/1995.next/anyway/dynamic_config.rb
125
+ - lib/.rbnext/1995.next/anyway/env.rb
126
+ - lib/.rbnext/1995.next/anyway/loaders/base.rb
127
+ - lib/.rbnext/1995.next/anyway/tracing.rb
109
128
  - lib/.rbnext/2.7/anyway/auto_cast.rb
110
129
  - lib/.rbnext/2.7/anyway/config.rb
111
- - lib/.rbnext/2.7/anyway/option_parser_builder.rb
130
+ - lib/.rbnext/2.7/anyway/rails/loaders/yaml.rb
131
+ - lib/.rbnext/2.7/anyway/rbs.rb
132
+ - lib/.rbnext/2.7/anyway/settings.rb
112
133
  - lib/.rbnext/2.7/anyway/tracing.rb
113
- - lib/.rbnext/2.8/anyway/config.rb
114
- - lib/.rbnext/2.8/anyway/loaders.rb
115
- - lib/.rbnext/2.8/anyway/loaders/base.rb
116
- - lib/.rbnext/2.8/anyway/tracing.rb
134
+ - lib/.rbnext/2.7/anyway/type_casting.rb
135
+ - lib/.rbnext/3.0/anyway/auto_cast.rb
136
+ - lib/.rbnext/3.0/anyway/config.rb
137
+ - lib/.rbnext/3.0/anyway/loaders.rb
138
+ - lib/.rbnext/3.0/anyway/loaders/base.rb
139
+ - lib/.rbnext/3.0/anyway/tracing.rb
117
140
  - lib/anyway.rb
118
141
  - lib/anyway/auto_cast.rb
119
142
  - lib/anyway/config.rb
@@ -136,10 +159,13 @@ files:
136
159
  - lib/anyway/rails/loaders/yaml.rb
137
160
  - lib/anyway/rails/settings.rb
138
161
  - lib/anyway/railtie.rb
162
+ - lib/anyway/rbs.rb
139
163
  - lib/anyway/settings.rb
140
164
  - lib/anyway/testing.rb
141
165
  - lib/anyway/testing/helpers.rb
142
166
  - lib/anyway/tracing.rb
167
+ - lib/anyway/type_casting.rb
168
+ - lib/anyway/utils/deep_merge.rb
143
169
  - lib/anyway/version.rb
144
170
  - lib/anyway_config.rb
145
171
  - lib/generators/anyway/app_config/USAGE
@@ -151,6 +177,7 @@ files:
151
177
  - lib/generators/anyway/install/USAGE
152
178
  - lib/generators/anyway/install/install_generator.rb
153
179
  - lib/generators/anyway/install/templates/application_config.rb.tt
180
+ - sig/anyway_config.rbs
154
181
  homepage: http://github.com/palkan/anyway_config
155
182
  licenses:
156
183
  - MIT
@@ -160,7 +187,7 @@ metadata:
160
187
  documentation_uri: http://github.com/palkan/anyway_config
161
188
  homepage_uri: http://github.com/palkan/anyway_config
162
189
  source_code_uri: http://github.com/palkan/anyway_config
163
- post_install_message:
190
+ post_install_message:
164
191
  rdoc_options: []
165
192
  require_paths:
166
193
  - lib
@@ -175,8 +202,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
175
202
  - !ruby/object:Gem::Version
176
203
  version: '0'
177
204
  requirements: []
178
- rubygems_version: 3.0.6
179
- signing_key:
205
+ rubygems_version: 3.2.22
206
+ signing_key:
180
207
  specification_version: 4
181
208
  summary: Configuration DSL for Ruby libraries and applications
182
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