dry-system 0.22.0 → 0.23.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 +400 -0
- data/LICENSE +1 -1
- data/README.md +2 -2
- data/dry-system.gemspec +2 -2
- data/lib/dry/system/component.rb +2 -3
- data/lib/dry/system/component_dir.rb +8 -34
- data/lib/dry/system/components.rb +8 -4
- data/lib/dry/system/config/component_dir.rb +60 -16
- data/lib/dry/system/config/component_dirs.rb +23 -10
- data/lib/dry/system/config/namespace.rb +4 -6
- data/lib/dry/system/constants.rb +1 -1
- data/lib/dry/system/container.rb +264 -182
- data/lib/dry/system/errors.rb +73 -53
- data/lib/dry/system/identifier.rb +62 -20
- data/lib/dry/system/importer.rb +83 -12
- data/lib/dry/system/indirect_component.rb +1 -1
- data/lib/dry/system/loader.rb +6 -1
- data/lib/dry/system/{manual_registrar.rb → manifest_registrar.rb} +8 -5
- data/lib/dry/system/plugins/bootsnap.rb +2 -1
- data/lib/dry/system/plugins/dependency_graph/strategies.rb +37 -1
- data/lib/dry/system/plugins/dependency_graph.rb +26 -20
- data/lib/dry/system/plugins/env.rb +2 -1
- data/lib/dry/system/plugins/logging.rb +2 -2
- data/lib/dry/system/plugins/monitoring.rb +1 -1
- data/lib/dry/system/plugins/notifications.rb +1 -1
- data/lib/dry/system/plugins/zeitwerk/compat_inflector.rb +22 -0
- data/lib/dry/system/plugins/zeitwerk.rb +109 -0
- data/lib/dry/system/plugins.rb +7 -4
- data/lib/dry/system/provider/source.rb +324 -0
- data/lib/dry/system/provider/source_dsl.rb +94 -0
- data/lib/dry/system/provider.rb +262 -22
- data/lib/dry/system/provider_registrar.rb +276 -0
- data/lib/dry/system/provider_source_registry.rb +70 -0
- data/lib/dry/system/provider_sources/settings/config.rb +86 -0
- data/lib/dry/system/provider_sources/settings/loader.rb +53 -0
- data/lib/dry/system/provider_sources/settings.rb +40 -0
- data/lib/dry/system/provider_sources.rb +5 -0
- data/lib/dry/system/version.rb +1 -1
- data/lib/dry/system.rb +44 -12
- metadata +18 -18
- data/lib/dry/system/booter/component_registry.rb +0 -35
- data/lib/dry/system/booter.rb +0 -200
- data/lib/dry/system/components/bootable.rb +0 -280
- data/lib/dry/system/components/config.rb +0 -35
- data/lib/dry/system/lifecycle.rb +0 -135
- data/lib/dry/system/provider_registry.rb +0 -27
- data/lib/dry/system/settings/file_loader.rb +0 -30
- data/lib/dry/system/settings/file_parser.rb +0 -51
- data/lib/dry/system/settings.rb +0 -64
- data/lib/dry/system/system_components/settings.rb +0 -11
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dry
|
4
|
+
module System
|
5
|
+
module Plugins
|
6
|
+
class Zeitwerk < Module
|
7
|
+
# @api private
|
8
|
+
class CompatInflector
|
9
|
+
attr_reader :config
|
10
|
+
|
11
|
+
def initialize(config)
|
12
|
+
@config = config
|
13
|
+
end
|
14
|
+
|
15
|
+
def camelize(string, _)
|
16
|
+
config.inflector.camelize(string)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/system/constants"
|
4
|
+
|
5
|
+
module Dry
|
6
|
+
module System
|
7
|
+
module Plugins
|
8
|
+
# @api private
|
9
|
+
class Zeitwerk < Module
|
10
|
+
# @api private
|
11
|
+
def self.dependencies
|
12
|
+
[
|
13
|
+
"dry/system/loader/autoloading",
|
14
|
+
"dry/system/plugins/zeitwerk/compat_inflector",
|
15
|
+
{"zeitwerk" => "zeitwerk"}
|
16
|
+
]
|
17
|
+
end
|
18
|
+
|
19
|
+
# @api private
|
20
|
+
attr_reader :loader, :run_setup, :eager_load, :debug
|
21
|
+
|
22
|
+
# @api private
|
23
|
+
def initialize(loader: nil, run_setup: true, eager_load: nil, debug: false)
|
24
|
+
@loader = loader || ::Zeitwerk::Loader.new
|
25
|
+
@run_setup = run_setup
|
26
|
+
@eager_load = eager_load
|
27
|
+
@debug = debug
|
28
|
+
super()
|
29
|
+
end
|
30
|
+
|
31
|
+
# @api private
|
32
|
+
def extended(system)
|
33
|
+
system.setting :autoloader, reader: true
|
34
|
+
|
35
|
+
system.config.autoloader = loader
|
36
|
+
system.config.component_dirs.loader = Dry::System::Loader::Autoloading
|
37
|
+
system.config.component_dirs.add_to_load_path = false
|
38
|
+
|
39
|
+
system.after(:configure, &method(:setup_autoloader))
|
40
|
+
|
41
|
+
super
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def setup_autoloader(system)
|
47
|
+
configure_loader(system.autoloader, system)
|
48
|
+
|
49
|
+
push_component_dirs_to_loader(system, system.autoloader)
|
50
|
+
|
51
|
+
system.autoloader.setup if run_setup
|
52
|
+
|
53
|
+
system.after(:finalize) { system.autoloader.eager_load } if eager_load?(system)
|
54
|
+
|
55
|
+
system
|
56
|
+
end
|
57
|
+
|
58
|
+
# Build a zeitwerk loader with the configured component directories
|
59
|
+
#
|
60
|
+
# @return [Zeitwerk::Loader]
|
61
|
+
def configure_loader(loader, system)
|
62
|
+
loader.tag = system.config.name || system.name unless loader.tag
|
63
|
+
loader.inflector = CompatInflector.new(system.config)
|
64
|
+
loader.logger = method(:puts) if debug
|
65
|
+
end
|
66
|
+
|
67
|
+
# Add component dirs to the zeitwerk loader
|
68
|
+
#
|
69
|
+
# @return [Zeitwerk::Loader]
|
70
|
+
def push_component_dirs_to_loader(system, loader)
|
71
|
+
system.config.component_dirs.each do |dir|
|
72
|
+
dir.namespaces.each do |ns|
|
73
|
+
loader.push_dir(
|
74
|
+
system.root.join(dir.path, ns.path.to_s),
|
75
|
+
namespace: module_for_namespace(ns, system.config.inflector)
|
76
|
+
)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
loader
|
81
|
+
end
|
82
|
+
|
83
|
+
def module_for_namespace(namespace, inflector)
|
84
|
+
return Object unless namespace.const
|
85
|
+
|
86
|
+
begin
|
87
|
+
inflector.constantize(inflector.camelize(namespace.const))
|
88
|
+
rescue NameError
|
89
|
+
namespace.const.split(PATH_SEPARATOR).reduce(Object) { |parent_mod, mod_path|
|
90
|
+
get_or_define_module(parent_mod, inflector.camelize(mod_path))
|
91
|
+
}
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def get_or_define_module(parent_mod, name)
|
96
|
+
parent_mod.const_get(name)
|
97
|
+
rescue NameError
|
98
|
+
parent_mod.const_set(name, Module.new)
|
99
|
+
end
|
100
|
+
|
101
|
+
def eager_load?(system)
|
102
|
+
return eager_load unless eager_load.nil?
|
103
|
+
|
104
|
+
system.config.respond_to?(:env) && system.config.env == :production
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
data/lib/dry/system/plugins.rb
CHANGED
@@ -21,8 +21,8 @@ module Dry
|
|
21
21
|
end
|
22
22
|
|
23
23
|
# @api private
|
24
|
-
def apply_to(system, options)
|
25
|
-
system.extend(stateful? ? mod.new(options) : mod)
|
24
|
+
def apply_to(system, **options)
|
25
|
+
system.extend(stateful? ? mod.new(**options) : mod)
|
26
26
|
system.instance_eval(&block) if block
|
27
27
|
system
|
28
28
|
end
|
@@ -90,13 +90,13 @@ module Dry
|
|
90
90
|
# @return [self]
|
91
91
|
#
|
92
92
|
# @api public
|
93
|
-
def use(name, options
|
93
|
+
def use(name, **options)
|
94
94
|
return self if enabled_plugins.include?(name)
|
95
95
|
|
96
96
|
raise PluginNotFoundError, name unless (plugin = Plugins.registry[name])
|
97
97
|
|
98
98
|
plugin.load_dependencies
|
99
|
-
plugin.apply_to(self, options)
|
99
|
+
plugin.apply_to(self, **options)
|
100
100
|
|
101
101
|
enabled_plugins << name
|
102
102
|
|
@@ -131,6 +131,9 @@ module Dry
|
|
131
131
|
|
132
132
|
require "dry/system/plugins/dependency_graph"
|
133
133
|
register(:dependency_graph, Plugins::DependencyGraph)
|
134
|
+
|
135
|
+
require "dry/system/plugins/zeitwerk"
|
136
|
+
register(:zeitwerk, Plugins::Zeitwerk)
|
134
137
|
end
|
135
138
|
end
|
136
139
|
end
|
@@ -0,0 +1,324 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/configurable"
|
4
|
+
require "dry/core/class_attributes"
|
5
|
+
require "dry/core/deprecations"
|
6
|
+
require_relative "source_dsl"
|
7
|
+
|
8
|
+
module Dry
|
9
|
+
module System
|
10
|
+
class Provider
|
11
|
+
# A provider's source provides the specific behavior for a given provider to serve
|
12
|
+
# its purpose.
|
13
|
+
#
|
14
|
+
# Sources should be subclasses of `Dry::System::Source::Provider`, with instance
|
15
|
+
# methods for each lifecycle step providing their behavior: {#prepare}, {#start},
|
16
|
+
# and {#stop}.
|
17
|
+
#
|
18
|
+
# Inside each of these methods, you should create and configure your provider's
|
19
|
+
# objects as required, and then {#register} them with the {#provider_container}.
|
20
|
+
# When the provider's lifecycle steps are run (via {Dry::System::Provider}), these
|
21
|
+
# registered components will be merged into the target container.
|
22
|
+
#
|
23
|
+
# You can prepare a provider's source in two ways:
|
24
|
+
#
|
25
|
+
# 1. Passing a bock when registering the provider, which is then evaluated via
|
26
|
+
# {Dry::System::Provider::SourceDSL} to prepare the provider subclass. This
|
27
|
+
# approach is easiest for simple providers.
|
28
|
+
# 2. Manually creare your own subclass of {Dry::System::Provider} and implement your
|
29
|
+
# own instance methods for the lifecycle steps (you should not implement your own
|
30
|
+
# `#initialize`). This approach may be useful for more complex providers.
|
31
|
+
#
|
32
|
+
# @see Dry::System::Container.register_provider
|
33
|
+
# @see Dry::System.register_provider_source
|
34
|
+
# @see Dry::System::Source::ProviderDSL
|
35
|
+
#
|
36
|
+
# @api public
|
37
|
+
class Source
|
38
|
+
class << self
|
39
|
+
# Returns a new Dry::System::Provider::Source subclass with its behavior supplied by the
|
40
|
+
# given block, which is evaluated using Dry::System::Provider::SourceDSL.
|
41
|
+
#
|
42
|
+
# @see Dry::System::Provider::SourceDSL
|
43
|
+
#
|
44
|
+
# @api private
|
45
|
+
def for(name:, group: nil, target_container:, &block) # rubocop:disable Style/KeywordParametersOrder
|
46
|
+
Class.new(self) { |klass|
|
47
|
+
klass.source_name name
|
48
|
+
klass.source_group group
|
49
|
+
SourceDSL.evaluate(klass, target_container, &block) if block
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
def inherited(subclass)
|
54
|
+
super
|
55
|
+
|
56
|
+
# FIXME: This shouldn't _need_ to be in an inherited hook but right now it's
|
57
|
+
# the only way to prevent individual Source instances from sharing settings
|
58
|
+
subclass.include Dry::Configurable
|
59
|
+
end
|
60
|
+
|
61
|
+
# @api private
|
62
|
+
def name
|
63
|
+
source_str = source_name
|
64
|
+
source_str = "#{source_group}->#{source_str}" if source_group
|
65
|
+
|
66
|
+
"Dry::System::Provider::Source[#{source_str}]"
|
67
|
+
end
|
68
|
+
|
69
|
+
# @api private
|
70
|
+
def to_s
|
71
|
+
"#<#{name}>"
|
72
|
+
end
|
73
|
+
|
74
|
+
# @api private
|
75
|
+
def inspect
|
76
|
+
to_s
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
CALLBACK_MAP = Hash.new { |h, k| h[k] = [] }.freeze
|
81
|
+
|
82
|
+
extend Dry::Core::ClassAttributes
|
83
|
+
|
84
|
+
defines :source_name, :source_group
|
85
|
+
|
86
|
+
# @api private
|
87
|
+
attr_reader :callbacks
|
88
|
+
|
89
|
+
# Returns the provider's own container for the provider.
|
90
|
+
#
|
91
|
+
# This container is namespaced based on the provider's `namespace:` configuration.
|
92
|
+
#
|
93
|
+
# Registered components in this container will be merged into the target container
|
94
|
+
# after the `prepare` and `start` lifecycle steps.
|
95
|
+
#
|
96
|
+
# @return [Dry::Container]
|
97
|
+
#
|
98
|
+
# @see #target_container
|
99
|
+
# @see Dry::System::Provider
|
100
|
+
#
|
101
|
+
# @api public
|
102
|
+
attr_reader :provider_container
|
103
|
+
alias_method :container, :provider_container
|
104
|
+
|
105
|
+
# Returns the target container for the provider.
|
106
|
+
#
|
107
|
+
# This is the container with which the provider is registered (via
|
108
|
+
# {Dry::System::Container.register_provider}).
|
109
|
+
#
|
110
|
+
# Registered components from the provider's container will be merged into this
|
111
|
+
# container after the `prepare` and `start` lifecycle steps.
|
112
|
+
#
|
113
|
+
# @return [Dry::System::Container]
|
114
|
+
#
|
115
|
+
# @see #provider_container
|
116
|
+
# @see Dry::System::Provider
|
117
|
+
#
|
118
|
+
# @api public
|
119
|
+
attr_reader :target_container
|
120
|
+
alias_method :target, :target_container
|
121
|
+
|
122
|
+
# @api private
|
123
|
+
def initialize(provider_container:, target_container:, &block)
|
124
|
+
super()
|
125
|
+
@callbacks = {before: CALLBACK_MAP.dup, after: CALLBACK_MAP.dup}
|
126
|
+
@provider_container = provider_container
|
127
|
+
@target_container = target_container
|
128
|
+
instance_exec(&block) if block
|
129
|
+
end
|
130
|
+
|
131
|
+
# Returns a string containing a human-readable representation of the provider.
|
132
|
+
#
|
133
|
+
# @return [String]
|
134
|
+
#
|
135
|
+
# @api private
|
136
|
+
def inspect
|
137
|
+
ivars = instance_variables.map { |ivar|
|
138
|
+
"#{ivar}=#{instance_variable_get(ivar).inspect}"
|
139
|
+
}.join(" ")
|
140
|
+
|
141
|
+
"#<#{self.class.name} #{ivars}>"
|
142
|
+
end
|
143
|
+
|
144
|
+
# Runs the behavior for the "prepare" lifecycle step.
|
145
|
+
#
|
146
|
+
# This should be implemented by your source subclass or specified by
|
147
|
+
# `SourceDSL#prepare` when registering a provider using a block.
|
148
|
+
#
|
149
|
+
# @return [void]
|
150
|
+
#
|
151
|
+
# @see SourceDSL#prepare
|
152
|
+
#
|
153
|
+
# @api public
|
154
|
+
def prepare; end
|
155
|
+
|
156
|
+
# Runs the behavior for the "start" lifecycle step.
|
157
|
+
#
|
158
|
+
# This should be implemented by your source subclass or specified by
|
159
|
+
# `SourceDSL#start` when registering a provider using a block.
|
160
|
+
#
|
161
|
+
# You can presume that {#prepare} has already run by the time this method is
|
162
|
+
# called.
|
163
|
+
#
|
164
|
+
# @return [void]
|
165
|
+
#
|
166
|
+
# @see SourceDSL#start
|
167
|
+
#
|
168
|
+
# @api public
|
169
|
+
def start; end
|
170
|
+
|
171
|
+
# Runs the behavior for the "stop" lifecycle step.
|
172
|
+
#
|
173
|
+
# This should be implemented by your source subclass or specified by
|
174
|
+
# `SourceDSL#stop` when registering a provider using a block.
|
175
|
+
#
|
176
|
+
# You can presume that {#prepare} and {#start} have already run by the time this
|
177
|
+
# method is called.
|
178
|
+
#
|
179
|
+
# @return [void]
|
180
|
+
#
|
181
|
+
# @see SourceDSL#stop
|
182
|
+
#
|
183
|
+
# @api public
|
184
|
+
def stop; end
|
185
|
+
|
186
|
+
def use(*provider_names)
|
187
|
+
Dry::Core::Deprecations.announce(
|
188
|
+
"Dry::System::Provider#use",
|
189
|
+
"Use `target_container.start` instead, e.g. `target_container.start(:another_provider)`", # rubocop:disable Layout/LineLength
|
190
|
+
tag: "dry-system",
|
191
|
+
uplevel: 1
|
192
|
+
)
|
193
|
+
|
194
|
+
provider_names.each do |name|
|
195
|
+
target_container.start(name)
|
196
|
+
end
|
197
|
+
|
198
|
+
self
|
199
|
+
end
|
200
|
+
|
201
|
+
# Registers a "before" callback for the given lifecycle step.
|
202
|
+
#
|
203
|
+
# The given block will be run before the lifecycle step method is run. The block
|
204
|
+
# will be evaluated in the context of the instance of this source.
|
205
|
+
#
|
206
|
+
# @param step_name [Symbol]
|
207
|
+
# @param block [Proc] the callback block
|
208
|
+
#
|
209
|
+
# @return [self]
|
210
|
+
#
|
211
|
+
# @see #after
|
212
|
+
#
|
213
|
+
# @api public
|
214
|
+
def before(step_name, &block)
|
215
|
+
if step_name.to_sym == :init
|
216
|
+
Dry::Core::Deprecations.announce(
|
217
|
+
"Dry::System::Provider before(:init) callback",
|
218
|
+
"Use `before(:prepare)` callback instead",
|
219
|
+
tag: "dry-system",
|
220
|
+
uplevel: 1
|
221
|
+
)
|
222
|
+
|
223
|
+
step_name = :prepare
|
224
|
+
end
|
225
|
+
|
226
|
+
callbacks[:before][step_name] << block
|
227
|
+
self
|
228
|
+
end
|
229
|
+
|
230
|
+
# Registers an "after" callback for the given lifecycle step.
|
231
|
+
#
|
232
|
+
# The given block will be run after the lifecycle step method is run. The block
|
233
|
+
# will be evaluated in the context of the instance of this source.
|
234
|
+
#
|
235
|
+
# @param step_name [Symbol]
|
236
|
+
# @param block [Proc] the callback block
|
237
|
+
#
|
238
|
+
# @return [self]
|
239
|
+
#
|
240
|
+
# @see #before
|
241
|
+
#
|
242
|
+
# @api public
|
243
|
+
def after(step_name, &block)
|
244
|
+
if step_name.to_sym == :init
|
245
|
+
Dry::Core::Deprecations.announce(
|
246
|
+
"Dry::System::Provider after(:init) callback",
|
247
|
+
"Use `after(:prepare)` callback instead",
|
248
|
+
tag: "dry-system",
|
249
|
+
uplevel: 1
|
250
|
+
)
|
251
|
+
|
252
|
+
step_name = :prepare
|
253
|
+
end
|
254
|
+
|
255
|
+
callbacks[:after][step_name] << block
|
256
|
+
self
|
257
|
+
end
|
258
|
+
|
259
|
+
# @api private
|
260
|
+
def run_callback(hook, step)
|
261
|
+
callbacks[hook][step].each do |callback|
|
262
|
+
if callback.parameters.any?
|
263
|
+
Dry::Core::Deprecations.announce(
|
264
|
+
"Dry::System::Provider::Source.before and .after callbacks with single block parameter", # rubocop:disable Layout/LineLength
|
265
|
+
"Use `provider_container` (or `container` for short) inside your block instead",
|
266
|
+
tag: "dry-system",
|
267
|
+
uplevel: 1
|
268
|
+
)
|
269
|
+
|
270
|
+
instance_exec(provider_container, &callback)
|
271
|
+
else
|
272
|
+
instance_eval(&callback)
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
private
|
278
|
+
|
279
|
+
# Registers a component in the provider container.
|
280
|
+
#
|
281
|
+
# When the provider's lifecycle steps are run (via {Dry::System::Provider}), these
|
282
|
+
# registered components will be merged into the target container.
|
283
|
+
#
|
284
|
+
# @return [Dry::Container] the provider container
|
285
|
+
#
|
286
|
+
# @api public
|
287
|
+
def register(...)
|
288
|
+
provider_container.register(...)
|
289
|
+
end
|
290
|
+
|
291
|
+
# Resolves a previously registered component from the provider container.
|
292
|
+
#
|
293
|
+
# @param key [String] the key for the component to resolve
|
294
|
+
#
|
295
|
+
# @return [Object] the previously registered component
|
296
|
+
#
|
297
|
+
# @api public
|
298
|
+
def resolve(key)
|
299
|
+
provider_container.resolve(key)
|
300
|
+
end
|
301
|
+
|
302
|
+
# @api private
|
303
|
+
def run_step_block(step_name)
|
304
|
+
step_block = self.class.step_blocks[step_name]
|
305
|
+
instance_eval(&step_block) if step_block
|
306
|
+
end
|
307
|
+
|
308
|
+
# @api private
|
309
|
+
def method_missing(name, *args, &block)
|
310
|
+
if container.key?(name)
|
311
|
+
container[name]
|
312
|
+
else
|
313
|
+
super
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
# @api private
|
318
|
+
def respond_to_missing?(name, include_all = false)
|
319
|
+
container.key?(name) || super
|
320
|
+
end
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
324
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/core/deprecations"
|
4
|
+
|
5
|
+
module Dry
|
6
|
+
module System
|
7
|
+
class Provider
|
8
|
+
# Configures a Dry::System::Provider::Source subclass using a DSL that makes it
|
9
|
+
# nicer to define source behaviour via a single block.
|
10
|
+
#
|
11
|
+
# @see Dry::System::Container.register_provider
|
12
|
+
#
|
13
|
+
# @api private
|
14
|
+
class SourceDSL
|
15
|
+
extend Dry::Core::Deprecations["Dry::System::Provider::SourceDSL"]
|
16
|
+
|
17
|
+
def self.evaluate(source_class, target_container, &block)
|
18
|
+
if block.parameters.any?
|
19
|
+
Dry::Core::Deprecations.announce(
|
20
|
+
"Dry::System.register_provider with single block parameter",
|
21
|
+
"Use `target_container` (or `target` for short) inside your block instead",
|
22
|
+
tag: "dry-system"
|
23
|
+
)
|
24
|
+
new(source_class).instance_exec(target_container, &block)
|
25
|
+
else
|
26
|
+
new(source_class).instance_eval(&block)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
attr_reader :source_class
|
31
|
+
|
32
|
+
def initialize(source_class)
|
33
|
+
@source_class = source_class
|
34
|
+
end
|
35
|
+
|
36
|
+
def setting(...)
|
37
|
+
source_class.setting(...)
|
38
|
+
end
|
39
|
+
|
40
|
+
# rubocop:disable Layout/LineLength
|
41
|
+
|
42
|
+
def settings(&block)
|
43
|
+
Dry::Core::Deprecations.announce(
|
44
|
+
"Dry::System.register_provider with nested settings block",
|
45
|
+
"Use individual top-level `setting` declarations instead (see dry-configurable docs for details)",
|
46
|
+
tag: "dry-system",
|
47
|
+
uplevel: 1
|
48
|
+
)
|
49
|
+
|
50
|
+
DeprecatedSettingsDSL.new(self).instance_eval(&block)
|
51
|
+
end
|
52
|
+
|
53
|
+
# rubocop:enable Layout/LineLength
|
54
|
+
|
55
|
+
class DeprecatedSettingsDSL
|
56
|
+
def initialize(base_dsl)
|
57
|
+
@base_dsl = base_dsl
|
58
|
+
end
|
59
|
+
|
60
|
+
def key(name, type)
|
61
|
+
@base_dsl.setting(name, constructor: type)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def prepare(&block)
|
66
|
+
source_class.define_method(:prepare, &block)
|
67
|
+
end
|
68
|
+
deprecate :init, :prepare
|
69
|
+
|
70
|
+
def start(&block)
|
71
|
+
source_class.define_method(:start, &block)
|
72
|
+
end
|
73
|
+
|
74
|
+
def stop(&block)
|
75
|
+
source_class.define_method(:stop, &block)
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def method_missing(name, *args, &block)
|
81
|
+
if source_class.respond_to?(name)
|
82
|
+
source_class.public_send(name, *args, &block)
|
83
|
+
else
|
84
|
+
super
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def respond_to_missing?(name, include_all = false)
|
89
|
+
source_class.respond_to?(name, include_all) || super
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|