piko-quick-lib 0.0.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 (49) hide show
  1. checksums.yaml +7 -0
  2. data/dry-system-1.2.5/CHANGELOG.md +1311 -0
  3. data/dry-system-1.2.5/LICENSE +21 -0
  4. data/dry-system-1.2.5/README.md +17 -0
  5. data/dry-system-1.2.5/dry-system.gemspec +42 -0
  6. data/dry-system-1.2.5/lib/dry/system/auto_registrar.rb +45 -0
  7. data/dry-system-1.2.5/lib/dry/system/component.rb +190 -0
  8. data/dry-system-1.2.5/lib/dry/system/component_dir.rb +171 -0
  9. data/dry-system-1.2.5/lib/dry/system/config/component_dir.rb +228 -0
  10. data/dry-system-1.2.5/lib/dry/system/config/component_dirs.rb +285 -0
  11. data/dry-system-1.2.5/lib/dry/system/config/namespace.rb +75 -0
  12. data/dry-system-1.2.5/lib/dry/system/config/namespaces.rb +192 -0
  13. data/dry-system-1.2.5/lib/dry/system/constants.rb +13 -0
  14. data/dry-system-1.2.5/lib/dry/system/container.rb +685 -0
  15. data/dry-system-1.2.5/lib/dry/system/errors.rb +132 -0
  16. data/dry-system-1.2.5/lib/dry/system/identifier.rb +176 -0
  17. data/dry-system-1.2.5/lib/dry/system/importer.rb +144 -0
  18. data/dry-system-1.2.5/lib/dry/system/indirect_component.rb +63 -0
  19. data/dry-system-1.2.5/lib/dry/system/loader/autoloading.rb +24 -0
  20. data/dry-system-1.2.5/lib/dry/system/loader.rb +84 -0
  21. data/dry-system-1.2.5/lib/dry/system/magic_comments_parser.rb +31 -0
  22. data/dry-system-1.2.5/lib/dry/system/manifest_registrar.rb +57 -0
  23. data/dry-system-1.2.5/lib/dry/system/plugins/bootsnap.rb +47 -0
  24. data/dry-system-1.2.5/lib/dry/system/plugins/dependency_graph/strategies.rb +66 -0
  25. data/dry-system-1.2.5/lib/dry/system/plugins/dependency_graph.rb +53 -0
  26. data/dry-system-1.2.5/lib/dry/system/plugins/env.rb +30 -0
  27. data/dry-system-1.2.5/lib/dry/system/plugins/logging.rb +73 -0
  28. data/dry-system-1.2.5/lib/dry/system/plugins/monitoring/proxy.rb +51 -0
  29. data/dry-system-1.2.5/lib/dry/system/plugins/monitoring.rb +45 -0
  30. data/dry-system-1.2.5/lib/dry/system/plugins/notifications.rb +27 -0
  31. data/dry-system-1.2.5/lib/dry/system/plugins/plugin.rb +61 -0
  32. data/dry-system-1.2.5/lib/dry/system/plugins/zeitwerk/compat_inflector.rb +22 -0
  33. data/dry-system-1.2.5/lib/dry/system/plugins/zeitwerk.rb +109 -0
  34. data/dry-system-1.2.5/lib/dry/system/plugins.rb +70 -0
  35. data/dry-system-1.2.5/lib/dry/system/provider/source.rb +281 -0
  36. data/dry-system-1.2.5/lib/dry/system/provider/source_dsl.rb +55 -0
  37. data/dry-system-1.2.5/lib/dry/system/provider.rb +291 -0
  38. data/dry-system-1.2.5/lib/dry/system/provider_registrar.rb +289 -0
  39. data/dry-system-1.2.5/lib/dry/system/provider_source_registry.rb +67 -0
  40. data/dry-system-1.2.5/lib/dry/system/provider_sources/settings/config.rb +73 -0
  41. data/dry-system-1.2.5/lib/dry/system/provider_sources/settings/loader.rb +44 -0
  42. data/dry-system-1.2.5/lib/dry/system/provider_sources/settings.rb +40 -0
  43. data/dry-system-1.2.5/lib/dry/system/provider_sources.rb +6 -0
  44. data/dry-system-1.2.5/lib/dry/system/stubs.rb +39 -0
  45. data/dry-system-1.2.5/lib/dry/system/version.rb +7 -0
  46. data/dry-system-1.2.5/lib/dry/system.rb +62 -0
  47. data/dry-system-1.2.5/lib/dry-system.rb +3 -0
  48. data/piko-quick-lib.gemspec +11 -0
  49. metadata +87 -0
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dry
4
+ module System
5
+ module Plugins
6
+ # Register a plugin
7
+ #
8
+ # @param [Symbol] name The name of a plugin
9
+ # @param [Class] plugin Plugin module
10
+ #
11
+ # @return [Plugins]
12
+ #
13
+ # @api public
14
+ def self.register(name, plugin, &)
15
+ registry[name] = Plugin.new(name, plugin, &)
16
+ end
17
+
18
+ # @api private
19
+ def self.registry
20
+ @registry ||= {}
21
+ end
22
+
23
+ # @api private
24
+ def self.loaded_dependencies
25
+ @loaded_dependencies ||= []
26
+ end
27
+
28
+ # Enables a plugin if not already enabled.
29
+ # Raises error if plugin cannot be found in the plugin registry.
30
+ #
31
+ # @param [Symbol] name The plugin name
32
+ # @param [Hash] options Plugin options
33
+ #
34
+ # @return [self]
35
+ #
36
+ # @api public
37
+ def use(name, **options)
38
+ return self if enabled_plugins.include?(name)
39
+
40
+ raise PluginNotFoundError, name unless (plugin = Dry::System::Plugins.registry[name])
41
+
42
+ plugin.load_dependencies
43
+ plugin.apply_to(self, **options)
44
+
45
+ enabled_plugins << name
46
+
47
+ self
48
+ end
49
+
50
+ # @api private
51
+ def inherited(klass)
52
+ klass.instance_variable_set(:@enabled_plugins, enabled_plugins.dup)
53
+ super
54
+ end
55
+
56
+ # @api private
57
+ def enabled_plugins
58
+ @enabled_plugins ||= []
59
+ end
60
+
61
+ register(:bootsnap, Plugins::Bootsnap)
62
+ register(:logging, Plugins::Logging)
63
+ register(:env, Plugins::Env)
64
+ register(:notifications, Plugins::Notifications)
65
+ register(:monitoring, Plugins::Monitoring)
66
+ register(:dependency_graph, Plugins::DependencyGraph)
67
+ register(:zeitwerk, Plugins::Zeitwerk)
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,281 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dry
4
+ module System
5
+ class Provider
6
+ # A provider's source provides the specific behavior for a given provider to serve
7
+ # its purpose.
8
+ #
9
+ # Sources should be subclasses of `Dry::System::Source::Provider`, with instance
10
+ # methods for each lifecycle step providing their behavior: {#prepare}, {#start},
11
+ # and {#stop}.
12
+ #
13
+ # Inside each of these methods, you should create and configure your provider's
14
+ # objects as required, and then {#register} them with the {#provider_container}.
15
+ # When the provider's lifecycle steps are run (via {Dry::System::Provider}), these
16
+ # registered components will be merged into the target container.
17
+ #
18
+ # You can prepare a provider's source in two ways:
19
+ #
20
+ # 1. Passing a bock when registering the provider, which is then evaluated via
21
+ # {Dry::System::Provider::SourceDSL} to prepare the provider subclass. This
22
+ # approach is easiest for simple providers.
23
+ # 2. Manually creare your own subclass of {Dry::System::Provider} and implement your
24
+ # own instance methods for the lifecycle steps (you should not implement your own
25
+ # `#initialize`). This approach may be useful for more complex providers.
26
+ #
27
+ # @see Dry::System::Container.register_provider
28
+ # @see Dry::System.register_provider_source
29
+ # @see Dry::System::Source::ProviderDSL
30
+ #
31
+ # @api public
32
+ class Source
33
+ class << self
34
+ # Returns a new Dry::System::Provider::Source subclass with its behavior supplied by the
35
+ # given block, which is evaluated using Dry::System::Provider::SourceDSL.
36
+ #
37
+ # @see Dry::System::Provider::SourceDSL
38
+ #
39
+ # @api private
40
+ def for(name:, group: nil, superclass: nil, &block)
41
+ superclass ||= self
42
+
43
+ ::Class.new(superclass) { |klass|
44
+ klass.source_name name
45
+ klass.source_group group
46
+
47
+ name_with_group = group ? "#{group}->#{name}" : name
48
+ klass.instance_eval(<<~RUBY, __FILE__, __LINE__ + 1)
49
+ def name # def name
50
+ "#{superclass.name}[#{name_with_group}]" # "CustomSource[custom]"
51
+ end # end
52
+ RUBY
53
+
54
+ SourceDSL.evaluate(klass, &block) if block_given?
55
+ }
56
+ end
57
+
58
+ def inherited(subclass)
59
+ super
60
+
61
+ # Include Dry::Configurable only when first subclassing to ensure that
62
+ # distinct Source subclasses do not share settings.
63
+ #
64
+ # The superclass check here allows deeper Source class hierarchies to be
65
+ # created without running into a Dry::Configurable::AlreadyIncluded error.
66
+ if subclass.superclass == Source
67
+ subclass.include Dry::Configurable
68
+ end
69
+ end
70
+
71
+ # @api private
72
+ def to_s
73
+ "#<#{name}>"
74
+ end
75
+
76
+ # @api private
77
+ def inspect
78
+ to_s
79
+ end
80
+ end
81
+
82
+ CALLBACK_MAP = Hash.new { |h, k| h[k] = [] }.freeze
83
+
84
+ extend Dry::Core::ClassAttributes
85
+
86
+ defines :source_name, :source_group
87
+
88
+ # @api private
89
+ attr_reader :callbacks
90
+
91
+ # Returns the provider's own container for the provider.
92
+ #
93
+ # This container is namespaced based on the provider's `namespace:` configuration.
94
+ #
95
+ # Registered components in this container will be merged into the target container
96
+ # after the `prepare` and `start` lifecycle steps.
97
+ #
98
+ # @return [Dry::Container]
99
+ #
100
+ # @see #target_container
101
+ # @see Dry::System::Provider
102
+ #
103
+ # @api public
104
+ attr_reader :provider_container
105
+ alias_method :container, :provider_container
106
+
107
+ # Returns the target container for the provider.
108
+ #
109
+ # This is the container with which the provider is registered (via
110
+ # {Dry::System::Container.register_provider}).
111
+ #
112
+ # Registered components from the provider's container will be merged into this
113
+ # container after the `prepare` and `start` lifecycle steps.
114
+ #
115
+ # @return [Dry::System::Container]
116
+ #
117
+ # @see #provider_container
118
+ # @see Dry::System::Provider
119
+ #
120
+ # @api public
121
+ attr_reader :target_container
122
+
123
+ # @see #target_container
124
+ # @api public
125
+ def target = target_container
126
+
127
+ # @api private
128
+ def initialize(provider_container:, target_container:, &)
129
+ super()
130
+ @callbacks = {before: CALLBACK_MAP.dup, after: CALLBACK_MAP.dup}
131
+ @provider_container = provider_container
132
+ @target_container = target_container
133
+ instance_exec(&) if block_given?
134
+ end
135
+
136
+ # Returns a string containing a human-readable representation of the provider.
137
+ #
138
+ # @return [String]
139
+ #
140
+ # @api private
141
+ def inspect
142
+ ivars = instance_variables.map { |ivar|
143
+ "#{ivar}=#{instance_variable_get(ivar).inspect}"
144
+ }.join(" ")
145
+
146
+ "#<#{self.class.name} #{ivars}>"
147
+ end
148
+
149
+ # Runs the behavior for the "prepare" lifecycle step.
150
+ #
151
+ # This should be implemented by your source subclass or specified by
152
+ # `SourceDSL#prepare` when registering a provider using a block.
153
+ #
154
+ # @return [void]
155
+ #
156
+ # @see SourceDSL#prepare
157
+ #
158
+ # @api public
159
+ def prepare; end
160
+
161
+ # Runs the behavior for the "start" lifecycle step.
162
+ #
163
+ # This should be implemented by your source subclass or specified by
164
+ # `SourceDSL#start` when registering a provider using a block.
165
+ #
166
+ # You can presume that {#prepare} has already run by the time this method is
167
+ # called.
168
+ #
169
+ # @return [void]
170
+ #
171
+ # @see SourceDSL#start
172
+ #
173
+ # @api public
174
+ def start; end
175
+
176
+ # Runs the behavior for the "stop" lifecycle step.
177
+ #
178
+ # This should be implemented by your source subclass or specified by
179
+ # `SourceDSL#stop` when registering a provider using a block.
180
+ #
181
+ # You can presume that {#prepare} and {#start} have already run by the time this
182
+ # method is called.
183
+ #
184
+ # @return [void]
185
+ #
186
+ # @see SourceDSL#stop
187
+ #
188
+ # @api public
189
+ def stop; end
190
+
191
+ # Registers a "before" callback for the given lifecycle step.
192
+ #
193
+ # The given block will be run before the lifecycle step method is run. The block
194
+ # will be evaluated in the context of the instance of this source.
195
+ #
196
+ # @param step_name [Symbol]
197
+ # @param block [Proc] the callback block
198
+ #
199
+ # @return [self]
200
+ #
201
+ # @see #after
202
+ #
203
+ # @api public
204
+ def before(step_name, &block)
205
+ callbacks[:before][step_name] << block
206
+ self
207
+ end
208
+
209
+ # Registers an "after" callback for the given lifecycle step.
210
+ #
211
+ # The given block will be run after the lifecycle step method is run. The block
212
+ # will be evaluated in the context of the instance of this source.
213
+ #
214
+ # @param step_name [Symbol]
215
+ # @param block [Proc] the callback block
216
+ #
217
+ # @return [self]
218
+ #
219
+ # @see #before
220
+ #
221
+ # @api public
222
+ def after(step_name, &block)
223
+ callbacks[:after][step_name] << block
224
+ self
225
+ end
226
+
227
+ # @api private
228
+ def run_callback(hook, step)
229
+ callbacks[hook][step].each do |callback|
230
+ instance_eval(&callback)
231
+ end
232
+ end
233
+
234
+ private
235
+
236
+ # Registers a component in the provider container.
237
+ #
238
+ # When the provider's lifecycle steps are run (via {Dry::System::Provider}), these
239
+ # registered components will be merged into the target container.
240
+ #
241
+ # @return [Dry::Container] the provider container
242
+ #
243
+ # @api public
244
+ def register(...)
245
+ provider_container.register(...)
246
+ end
247
+
248
+ # Resolves a previously registered component from the provider container.
249
+ #
250
+ # @param key [String] the key for the component to resolve
251
+ #
252
+ # @return [Object] the previously registered component
253
+ #
254
+ # @api public
255
+ def resolve(key)
256
+ provider_container.resolve(key)
257
+ end
258
+
259
+ # @api private
260
+ def run_step_block(step_name)
261
+ step_block = self.class.step_blocks[step_name]
262
+ instance_eval(&step_block) if step_block
263
+ end
264
+
265
+ # @api private
266
+ def method_missing(name, *args, &)
267
+ if container.key?(name)
268
+ container[name]
269
+ else
270
+ super
271
+ end
272
+ end
273
+
274
+ # @api private
275
+ def respond_to_missing?(name, include_all = false)
276
+ container.key?(name) || super
277
+ end
278
+ end
279
+ end
280
+ end
281
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dry
4
+ module System
5
+ class Provider
6
+ # Configures a Dry::System::Provider::Source subclass using a DSL that makes it
7
+ # nicer to define source behaviour via a single block.
8
+ #
9
+ # @see Dry::System::Container.register_provider
10
+ #
11
+ # @api private
12
+ class SourceDSL
13
+ def self.evaluate(source_class, &)
14
+ new(source_class).instance_eval(&)
15
+ end
16
+
17
+ attr_reader :source_class
18
+
19
+ def initialize(source_class)
20
+ @source_class = source_class
21
+ end
22
+
23
+ def setting(...)
24
+ source_class.setting(...)
25
+ end
26
+
27
+ def prepare(&)
28
+ source_class.define_method(:prepare, &)
29
+ end
30
+
31
+ def start(&)
32
+ source_class.define_method(:start, &)
33
+ end
34
+
35
+ def stop(&)
36
+ source_class.define_method(:stop, &)
37
+ end
38
+
39
+ private
40
+
41
+ def method_missing(name, ...)
42
+ if source_class.respond_to?(name)
43
+ source_class.public_send(name, ...)
44
+ else
45
+ super
46
+ end
47
+ end
48
+
49
+ def respond_to_missing?(name, include_all = false)
50
+ source_class.respond_to?(name, include_all) || super
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,291 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/system/constants"
4
+
5
+ module Dry
6
+ module System
7
+ # Providers can prepare and register one or more objects and typically work with third
8
+ # party code. A typical provider might be for a database library, or an API client.
9
+ #
10
+ # The particular behavior for any provider is defined in a {Provider::Source}, which
11
+ # is a subclass created when you run {Container.register_provider} or
12
+ # {Dry::System.register_provider_source}. The Source provides this behavior through
13
+ # methods for each of the steps in the provider lifecycle: `prepare`, `start`, and
14
+ # `run`. These methods typically create and configure various objects, then register
15
+ # them with the {#provider_container}.
16
+ #
17
+ # The Provider manages this lifecycle by implementing common behavior around the
18
+ # lifecycle steps, such as running step callbacks, and only running steps when
19
+ # appropriate for the current status of the lifecycle.
20
+ #
21
+ # Providers can be registered via {Container.register_provider}.
22
+ #
23
+ # @example Simple provider
24
+ # class App < Dry::System::Container
25
+ # register_provider(:logger) do
26
+ # prepare do
27
+ # require "logger"
28
+ # end
29
+ #
30
+ # start do
31
+ # register(:logger, Logger.new($stdout))
32
+ # end
33
+ # end
34
+ # end
35
+ #
36
+ # App[:logger] # returns configured logger
37
+ #
38
+ # @example Using an external Provider Source
39
+ # class App < Dry::System::Container
40
+ # register_provider(:logger, from: :some_external_provider_source) do
41
+ # configure do |config|
42
+ # config.log_level = :debug
43
+ # end
44
+ #
45
+ # after :start do
46
+ # register(:my_extra_logger, resolve(:logger))
47
+ # end
48
+ # end
49
+ # end
50
+ #
51
+ # App[:my_extra_logger] # returns the extra logger registered in the callback
52
+ #
53
+ # @api public
54
+ class Provider
55
+ # Returns the provider's unique name.
56
+ #
57
+ # @return [Symbol]
58
+ #
59
+ # @api public
60
+ attr_reader :name
61
+
62
+ # Returns the default namespace for the provider's container keys.
63
+ #
64
+ # @return [Symbol,String]
65
+ #
66
+ # @api public
67
+ attr_reader :namespace
68
+
69
+ # Returns an array of lifecycle steps that have been run.
70
+ #
71
+ # @return [Array<Symbol>]
72
+ #
73
+ # @example
74
+ # provider.statuses # => [:prepare, :start]
75
+ #
76
+ # @api public
77
+ attr_reader :statuses
78
+
79
+ # Returns the name of the currently running step, if any.
80
+ #
81
+ # @return [Symbol, nil]
82
+ #
83
+ # @api private
84
+ attr_reader :step_running
85
+ private :step_running
86
+
87
+ # Returns the container for the provider.
88
+ #
89
+ # This is where the provider's source will register its components, which are then
90
+ # later marged into the target container after the `prepare` and `start` lifecycle
91
+ # steps.
92
+ #
93
+ # @return [Dry::Core::Container]
94
+ #
95
+ # @api public
96
+ attr_reader :provider_container
97
+ alias_method :container, :provider_container
98
+
99
+ # Returns the target container for the provider.
100
+ #
101
+ # This is the container with which the provider is registered (via
102
+ # {Dry::System::Container.register_provider}).
103
+ #
104
+ # Registered components from the provider's container will be merged into this
105
+ # container after the `prepare` and `start` lifecycle steps.
106
+ #
107
+ # @return [Dry::System::Container]
108
+ #
109
+ # @api public
110
+ attr_reader :target_container
111
+ alias_method :target, :target_container
112
+
113
+ # Returns the provider's source
114
+ #
115
+ # The source provides the specific behavior for the provider via methods
116
+ # implementing the lifecycle steps.
117
+ #
118
+ # The provider's source is defined when registering a provider with the container,
119
+ # or an external provider source.
120
+ #
121
+ # @see Dry::System::Container.register_provider
122
+ # @see Dry::System.register_provider_source
123
+ #
124
+ # @return [Dry::System::Provider::Source]
125
+ #
126
+ # @api private
127
+ attr_reader :source
128
+
129
+ # @api private
130
+ # rubocop:disable Style/KeywordParametersOrder
131
+ def initialize(name:, namespace: nil, target_container:, source_class:, source_options: {}, &)
132
+ @name = name
133
+ @namespace = namespace
134
+ @target_container = target_container
135
+
136
+ @provider_container = build_provider_container
137
+ @statuses = []
138
+ @step_running = nil
139
+
140
+ @source = source_class.new(
141
+ **source_options,
142
+ provider_container: provider_container,
143
+ target_container: target_container,
144
+ &
145
+ )
146
+ end
147
+ # rubocop:enable Style/KeywordParametersOrder
148
+
149
+ # Runs the `prepare` lifecycle step.
150
+ #
151
+ # Also runs any callbacks for the step, and then merges any registered components
152
+ # from the provider container into the target container.
153
+ #
154
+ # @return [self]
155
+ #
156
+ # @api public
157
+ def prepare
158
+ run_step(:prepare)
159
+ end
160
+
161
+ # Runs the `start` lifecycle step.
162
+ #
163
+ # Also runs any callbacks for the step, and then merges any registered components
164
+ # from the provider container into the target container.
165
+ #
166
+ # @return [self]
167
+ #
168
+ # @api public
169
+ def start
170
+ run_step(:prepare)
171
+ run_step(:start)
172
+ end
173
+
174
+ # Runs the `stop` lifecycle step.
175
+ #
176
+ # Also runs any callbacks for the step.
177
+ #
178
+ # @return [self]
179
+ #
180
+ # @api public
181
+ def stop
182
+ return self unless started?
183
+
184
+ run_step(:stop)
185
+ end
186
+
187
+ # Returns true if the provider's `prepare` lifecycle step has run
188
+ #
189
+ # @api public
190
+ def prepared?
191
+ statuses.include?(:prepare)
192
+ end
193
+
194
+ # Returns true if the provider's `start` lifecycle step has run
195
+ #
196
+ # @api public
197
+ def started?
198
+ statuses.include?(:start)
199
+ end
200
+
201
+ # Returns true if the provider's `stop` lifecycle step has run
202
+ #
203
+ # @api public
204
+ def stopped?
205
+ statuses.include?(:stop)
206
+ end
207
+
208
+ private
209
+
210
+ # @api private
211
+ def build_provider_container
212
+ container = Core::Container.new
213
+
214
+ case namespace
215
+ when String, Symbol
216
+ container.namespace(namespace) { |c| return c }
217
+ when true
218
+ container.namespace(name) { |c| return c }
219
+ when nil
220
+ container
221
+ else
222
+ raise ArgumentError,
223
+ "+namespace:+ must be true, string or symbol: #{namespace.inspect} given."
224
+ end
225
+ end
226
+
227
+ # @api private
228
+ def run_step(step_name)
229
+ return self if step_running? || statuses.include?(step_name)
230
+
231
+ @step_running = step_name
232
+
233
+ source.run_callback(:before, step_name)
234
+ source.public_send(step_name)
235
+ source.run_callback(:after, step_name)
236
+
237
+ statuses << step_name
238
+
239
+ apply
240
+
241
+ @step_running = nil
242
+
243
+ self
244
+ end
245
+
246
+ # Returns true if a step is currenly running.
247
+ #
248
+ # This is important for short-circuiting the invocation of {#run_step} and avoiding
249
+ # infinite loops if a provider step happens to result in resolution of a component
250
+ # with the same root key as the provider's own name (which ordinarily results in
251
+ # that provider being started).
252
+ #
253
+ # @return [Boolean]
254
+ #
255
+ # @see {#run_step}
256
+ #
257
+ # @api private
258
+ def step_running?
259
+ !!step_running
260
+ end
261
+
262
+ # Registers any components from the provider's container in the main container.
263
+ #
264
+ # Called after each lifecycle step runs.
265
+ #
266
+ # @return [self]
267
+ #
268
+ # @api private
269
+ def apply
270
+ provider_container.each_key do |key|
271
+ next if target_container.registered?(key)
272
+
273
+ # Access the provider's container items directly so that we can preserve all
274
+ # their options when we merge them with the target container (e.g. if a
275
+ # component in the provider container was registered with a block, we want block
276
+ # registration behavior to be exhibited when later resolving that component from
277
+ # the target container). TODO: Make this part of dry-system's public API.
278
+ item = provider_container._container[key]
279
+
280
+ if item.callable?
281
+ target_container.register(key, **item.options, &item.item)
282
+ else
283
+ target_container.register(key, item.item, **item.options)
284
+ end
285
+ end
286
+
287
+ self
288
+ end
289
+ end
290
+ end
291
+ end