dry-system 0.21.0 → 0.24.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 +424 -0
- data/LICENSE +1 -1
- data/README.md +4 -4
- data/dry-system.gemspec +3 -4
- 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 +75 -19
- data/lib/dry/system/config/component_dirs.rb +151 -32
- data/lib/dry/system/config/namespace.rb +11 -6
- data/lib/dry/system/config/namespaces.rb +96 -9
- 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 +3 -2
- 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 +23 -37
- 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,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/configurable"
|
4
|
+
require "dry/core/deprecations"
|
5
|
+
require_relative "loader"
|
6
|
+
|
7
|
+
module Dry
|
8
|
+
module System
|
9
|
+
module ProviderSources
|
10
|
+
# @api private
|
11
|
+
module Settings
|
12
|
+
InvalidSettingsError = Class.new(ArgumentError) do
|
13
|
+
# @api private
|
14
|
+
def initialize(errors)
|
15
|
+
message = <<~STR
|
16
|
+
Could not load settings. The following settings were invalid:
|
17
|
+
|
18
|
+
#{setting_errors(errors).join("\n")}
|
19
|
+
STR
|
20
|
+
|
21
|
+
super(message)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def setting_errors(errors)
|
27
|
+
errors.sort_by { |k, _| k }.map { |key, error| "#{key}: #{error}" }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# @api private
|
32
|
+
class Config
|
33
|
+
# @api private
|
34
|
+
def self.load(root:, env:, loader: Loader)
|
35
|
+
loader = loader.new(root: root, env: env)
|
36
|
+
|
37
|
+
new.tap do |settings_obj|
|
38
|
+
errors = {}
|
39
|
+
|
40
|
+
settings.to_a.each do |setting_name|
|
41
|
+
value = loader[setting_name.to_s.upcase]
|
42
|
+
|
43
|
+
begin
|
44
|
+
settings_obj.config.public_send(:"#{setting_name}=", value) if value
|
45
|
+
rescue => e # rubocop:disable Style/RescueStandardError
|
46
|
+
errors[setting_name] = e
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
raise InvalidSettingsError, errors unless errors.empty?
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# rubocop:disable Layout/LineLength
|
55
|
+
def self.key(name, type)
|
56
|
+
Dry::Core::Deprecations.announce(
|
57
|
+
"Dry::System :settings provider source setting definition using `key`",
|
58
|
+
"Use `setting` instead, with dry-configurable `setting` options, e.g. `setting :my_setting, default: \"hello\", constructor: Types::String.constrained(min_length: 3)`",
|
59
|
+
tag: "dry-system",
|
60
|
+
uplevel: 1
|
61
|
+
)
|
62
|
+
|
63
|
+
setting(name, constructor: type)
|
64
|
+
end
|
65
|
+
# rubocop:enable Layout/LineLength
|
66
|
+
|
67
|
+
include Dry::Configurable
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def method_missing(name, *args, &block)
|
72
|
+
if config.respond_to?(name)
|
73
|
+
config.public_send(name, *args, &block)
|
74
|
+
else
|
75
|
+
super
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def respond_to_missing?(name, include_all = false)
|
80
|
+
config.respond_to?(name, include_all) || super
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry/configurable"
|
4
|
+
require "dry/core/deprecations"
|
5
|
+
|
6
|
+
module Dry
|
7
|
+
module System
|
8
|
+
module ProviderSources
|
9
|
+
module Settings
|
10
|
+
# @api private
|
11
|
+
class Loader
|
12
|
+
# @api private
|
13
|
+
attr_reader :store
|
14
|
+
|
15
|
+
# @api private
|
16
|
+
def initialize(root:, env:, store: ENV)
|
17
|
+
@store = store
|
18
|
+
load_dotenv(root, env.to_sym)
|
19
|
+
end
|
20
|
+
|
21
|
+
# @api private
|
22
|
+
def [](key)
|
23
|
+
store[key]
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def load_dotenv(root, env)
|
29
|
+
require "dotenv"
|
30
|
+
Dotenv.load(*dotenv_files(root, env)) if defined?(Dotenv)
|
31
|
+
rescue LoadError
|
32
|
+
Dry::Core::Deprecations.announce(
|
33
|
+
"Dry::System :settings provider now requires dotenv to to load settings from .env files`", # rubocop:disable Layout/LineLength
|
34
|
+
"Add `gem \"dotenv\"` to your application's `Gemfile`",
|
35
|
+
tag: "dry-system",
|
36
|
+
uplevel: 3
|
37
|
+
)
|
38
|
+
# Do nothing if dotenv is unavailable
|
39
|
+
end
|
40
|
+
|
41
|
+
def dotenv_files(root, env)
|
42
|
+
[
|
43
|
+
File.join(root, ".env.#{env}.local"),
|
44
|
+
(File.join(root, ".env.local") unless env == :test),
|
45
|
+
File.join(root, ".env.#{env}"),
|
46
|
+
File.join(root, ".env")
|
47
|
+
].compact
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dry
|
4
|
+
module System
|
5
|
+
module ProviderSources
|
6
|
+
module Settings
|
7
|
+
class Source < Dry::System::Provider::Source
|
8
|
+
setting :store
|
9
|
+
|
10
|
+
def prepare
|
11
|
+
require "dry/system/provider_sources/settings/config"
|
12
|
+
end
|
13
|
+
|
14
|
+
def start
|
15
|
+
register(:settings, settings.load(root: target.root, env: target.config.env))
|
16
|
+
end
|
17
|
+
|
18
|
+
def settings(&block)
|
19
|
+
# Save the block and evaluate it lazily to allow a provider with this source
|
20
|
+
# to `require` any necessary files for the block to evaluate correctly (e.g.
|
21
|
+
# requiring an app-specific types module for setting constructors)
|
22
|
+
if block
|
23
|
+
@settings_block = block
|
24
|
+
elsif @settings_class
|
25
|
+
@settings_class
|
26
|
+
elsif @settings_block
|
27
|
+
@settings_class = Class.new(Settings::Config, &@settings_block)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
Dry::System.register_provider_source(
|
37
|
+
:settings,
|
38
|
+
group: :dry_system,
|
39
|
+
source: Dry::System::ProviderSources::Settings::Source
|
40
|
+
)
|
data/lib/dry/system/version.rb
CHANGED
data/lib/dry/system.rb
CHANGED
@@ -1,30 +1,62 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "dry/
|
4
|
-
|
3
|
+
require "dry/core/deprecations"
|
4
|
+
require_relative "system/provider_source_registry"
|
5
5
|
|
6
6
|
module Dry
|
7
7
|
module System
|
8
|
-
#
|
8
|
+
# Registers the provider sources in the files under the given path
|
9
9
|
#
|
10
10
|
# @api public
|
11
|
-
def self.
|
12
|
-
|
13
|
-
providers[name].load_components
|
14
|
-
self
|
11
|
+
def self.register_provider_sources(path)
|
12
|
+
provider_sources.load_sources(path)
|
15
13
|
end
|
16
14
|
|
17
|
-
|
15
|
+
def self.register_provider(_name, options)
|
16
|
+
Dry::Core::Deprecations.announce(
|
17
|
+
"Dry::System.register_provider",
|
18
|
+
"Use `Dry::System.register_provider_sources` instead",
|
19
|
+
tag: "dry-system",
|
20
|
+
uplevel: 1
|
21
|
+
)
|
22
|
+
|
23
|
+
register_provider_sources(options.fetch(:path))
|
24
|
+
end
|
25
|
+
|
26
|
+
# Registers a provider source, which can be used as the basis for other providers
|
18
27
|
#
|
19
28
|
# @api public
|
29
|
+
def self.register_provider_source(name, group:, source: nil, &block)
|
30
|
+
if source && block
|
31
|
+
raise ArgumentError, "You must supply only a `source:` option or a block, not both"
|
32
|
+
end
|
33
|
+
|
34
|
+
if source
|
35
|
+
provider_sources.register(name: name, group: group, source: source)
|
36
|
+
else
|
37
|
+
provider_sources.register_from_block(
|
38
|
+
name: name,
|
39
|
+
group: group,
|
40
|
+
target_container: self,
|
41
|
+
&block
|
42
|
+
)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
20
46
|
def self.register_component(name, provider:, &block)
|
21
|
-
|
22
|
-
|
47
|
+
Dry::Core::Deprecations.announce(
|
48
|
+
"Dry::System.register_component",
|
49
|
+
"Use `Dry::System.register_provider_source` instead",
|
50
|
+
tag: "dry-system",
|
51
|
+
uplevel: 1
|
52
|
+
)
|
53
|
+
|
54
|
+
register_provider_source(name, group: provider, &block)
|
23
55
|
end
|
24
56
|
|
25
57
|
# @api private
|
26
|
-
def self.
|
27
|
-
@
|
58
|
+
def self.provider_sources
|
59
|
+
@provider_sources ||= ProviderSourceRegistry.new
|
28
60
|
end
|
29
61
|
end
|
30
62
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dry-system
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.24.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Solnica
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-05-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -44,20 +44,20 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '0.
|
47
|
+
version: '0.14'
|
48
48
|
- - ">="
|
49
49
|
- !ruby/object:Gem::Version
|
50
|
-
version: 0.
|
50
|
+
version: 0.14.0
|
51
51
|
type: :runtime
|
52
52
|
prerelease: false
|
53
53
|
version_requirements: !ruby/object:Gem::Requirement
|
54
54
|
requirements:
|
55
55
|
- - "~>"
|
56
56
|
- !ruby/object:Gem::Version
|
57
|
-
version: '0.
|
57
|
+
version: '0.14'
|
58
58
|
- - ">="
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version: 0.
|
60
|
+
version: 0.14.0
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
62
|
name: dry-container
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -118,20 +118,6 @@ dependencies:
|
|
118
118
|
- - ">="
|
119
119
|
- !ruby/object:Gem::Version
|
120
120
|
version: 0.1.2
|
121
|
-
- !ruby/object:Gem::Dependency
|
122
|
-
name: dry-struct
|
123
|
-
requirement: !ruby/object:Gem::Requirement
|
124
|
-
requirements:
|
125
|
-
- - "~>"
|
126
|
-
- !ruby/object:Gem::Version
|
127
|
-
version: '1.0'
|
128
|
-
type: :runtime
|
129
|
-
prerelease: false
|
130
|
-
version_requirements: !ruby/object:Gem::Requirement
|
131
|
-
requirements:
|
132
|
-
- - "~>"
|
133
|
-
- !ruby/object:Gem::Version
|
134
|
-
version: '1.0'
|
135
121
|
- !ruby/object:Gem::Dependency
|
136
122
|
name: bundler
|
137
123
|
requirement: !ruby/object:Gem::Requirement
|
@@ -188,13 +174,9 @@ files:
|
|
188
174
|
- lib/dry-system.rb
|
189
175
|
- lib/dry/system.rb
|
190
176
|
- lib/dry/system/auto_registrar.rb
|
191
|
-
- lib/dry/system/booter.rb
|
192
|
-
- lib/dry/system/booter/component_registry.rb
|
193
177
|
- lib/dry/system/component.rb
|
194
178
|
- lib/dry/system/component_dir.rb
|
195
179
|
- lib/dry/system/components.rb
|
196
|
-
- lib/dry/system/components/bootable.rb
|
197
|
-
- lib/dry/system/components/config.rb
|
198
180
|
- lib/dry/system/config/component_dir.rb
|
199
181
|
- lib/dry/system/config/component_dirs.rb
|
200
182
|
- lib/dry/system/config/namespace.rb
|
@@ -205,11 +187,10 @@ files:
|
|
205
187
|
- lib/dry/system/identifier.rb
|
206
188
|
- lib/dry/system/importer.rb
|
207
189
|
- lib/dry/system/indirect_component.rb
|
208
|
-
- lib/dry/system/lifecycle.rb
|
209
190
|
- lib/dry/system/loader.rb
|
210
191
|
- lib/dry/system/loader/autoloading.rb
|
211
192
|
- lib/dry/system/magic_comments_parser.rb
|
212
|
-
- lib/dry/system/
|
193
|
+
- lib/dry/system/manifest_registrar.rb
|
213
194
|
- lib/dry/system/plugins.rb
|
214
195
|
- lib/dry/system/plugins/bootsnap.rb
|
215
196
|
- lib/dry/system/plugins/dependency_graph.rb
|
@@ -219,23 +200,28 @@ files:
|
|
219
200
|
- lib/dry/system/plugins/monitoring.rb
|
220
201
|
- lib/dry/system/plugins/monitoring/proxy.rb
|
221
202
|
- lib/dry/system/plugins/notifications.rb
|
203
|
+
- lib/dry/system/plugins/zeitwerk.rb
|
204
|
+
- lib/dry/system/plugins/zeitwerk/compat_inflector.rb
|
222
205
|
- lib/dry/system/provider.rb
|
223
|
-
- lib/dry/system/
|
224
|
-
- lib/dry/system/
|
225
|
-
- lib/dry/system/
|
226
|
-
- lib/dry/system/
|
206
|
+
- lib/dry/system/provider/source.rb
|
207
|
+
- lib/dry/system/provider/source_dsl.rb
|
208
|
+
- lib/dry/system/provider_registrar.rb
|
209
|
+
- lib/dry/system/provider_source_registry.rb
|
210
|
+
- lib/dry/system/provider_sources.rb
|
211
|
+
- lib/dry/system/provider_sources/settings.rb
|
212
|
+
- lib/dry/system/provider_sources/settings/config.rb
|
213
|
+
- lib/dry/system/provider_sources/settings/loader.rb
|
227
214
|
- lib/dry/system/stubs.rb
|
228
|
-
- lib/dry/system/system_components/settings.rb
|
229
215
|
- lib/dry/system/version.rb
|
230
216
|
homepage: https://dry-rb.org/gems/dry-system
|
231
217
|
licenses:
|
232
218
|
- MIT
|
233
219
|
metadata:
|
234
220
|
allowed_push_host: https://rubygems.org
|
235
|
-
changelog_uri: https://github.com/dry-rb/dry-system/blob/
|
221
|
+
changelog_uri: https://github.com/dry-rb/dry-system/blob/main/CHANGELOG.md
|
236
222
|
source_code_uri: https://github.com/dry-rb/dry-system
|
237
223
|
bug_tracker_uri: https://github.com/dry-rb/dry-system/issues
|
238
|
-
post_install_message:
|
224
|
+
post_install_message:
|
239
225
|
rdoc_options: []
|
240
226
|
require_paths:
|
241
227
|
- lib
|
@@ -243,15 +229,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
243
229
|
requirements:
|
244
230
|
- - ">="
|
245
231
|
- !ruby/object:Gem::Version
|
246
|
-
version: 2.
|
232
|
+
version: 2.7.0
|
247
233
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
248
234
|
requirements:
|
249
235
|
- - ">="
|
250
236
|
- !ruby/object:Gem::Version
|
251
237
|
version: '0'
|
252
238
|
requirements: []
|
253
|
-
rubygems_version: 3.
|
254
|
-
signing_key:
|
239
|
+
rubygems_version: 3.2.32
|
240
|
+
signing_key:
|
255
241
|
specification_version: 4
|
256
242
|
summary: Organize your code into reusable components
|
257
243
|
test_files: []
|
@@ -1,35 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Dry
|
4
|
-
module System
|
5
|
-
class Booter
|
6
|
-
class ComponentRegistry
|
7
|
-
include Enumerable
|
8
|
-
|
9
|
-
attr_reader :components
|
10
|
-
|
11
|
-
def initialize
|
12
|
-
@components = []
|
13
|
-
end
|
14
|
-
|
15
|
-
def each(&block)
|
16
|
-
components.each(&block)
|
17
|
-
end
|
18
|
-
|
19
|
-
def register(component)
|
20
|
-
@components << component
|
21
|
-
end
|
22
|
-
|
23
|
-
def exists?(name)
|
24
|
-
components.any? { |component| component.name == name }
|
25
|
-
end
|
26
|
-
|
27
|
-
def [](name)
|
28
|
-
component = components.detect { |c| c.name == name }
|
29
|
-
|
30
|
-
component || raise(InvalidComponentNameError, name)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
data/lib/dry/system/booter.rb
DELETED
@@ -1,200 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "dry/system/components/bootable"
|
4
|
-
require "dry/system/errors"
|
5
|
-
require "dry/system/constants"
|
6
|
-
require "dry/system/lifecycle"
|
7
|
-
require "dry/system/booter/component_registry"
|
8
|
-
require "pathname"
|
9
|
-
|
10
|
-
module Dry
|
11
|
-
module System
|
12
|
-
# Default booter implementation
|
13
|
-
#
|
14
|
-
# This is currently configured by default for every System::Container.
|
15
|
-
# Booter objects are responsible for loading system/boot files and expose
|
16
|
-
# an API for calling lifecycle triggers.
|
17
|
-
#
|
18
|
-
# @api private
|
19
|
-
class Booter
|
20
|
-
attr_reader :paths
|
21
|
-
|
22
|
-
attr_reader :booted
|
23
|
-
|
24
|
-
attr_reader :components
|
25
|
-
|
26
|
-
# @api private
|
27
|
-
def initialize(paths)
|
28
|
-
@paths = paths
|
29
|
-
@booted = []
|
30
|
-
@components = ComponentRegistry.new
|
31
|
-
end
|
32
|
-
|
33
|
-
# @api private
|
34
|
-
def register_component(component)
|
35
|
-
components.register(component)
|
36
|
-
self
|
37
|
-
end
|
38
|
-
|
39
|
-
# Returns a bootable component if it can be found or loaded, otherwise nil
|
40
|
-
#
|
41
|
-
# @return [Dry::System::Components::Bootable, nil]
|
42
|
-
# @api private
|
43
|
-
def find_component(name)
|
44
|
-
name = name.to_sym
|
45
|
-
|
46
|
-
return components[name] if components.exists?(name)
|
47
|
-
|
48
|
-
return if finalized?
|
49
|
-
|
50
|
-
require_boot_file(name)
|
51
|
-
|
52
|
-
components[name] if components.exists?(name)
|
53
|
-
end
|
54
|
-
|
55
|
-
# @api private
|
56
|
-
def finalize!
|
57
|
-
boot_files.each do |path|
|
58
|
-
load_component(path)
|
59
|
-
end
|
60
|
-
|
61
|
-
components.each do |component|
|
62
|
-
start(component)
|
63
|
-
end
|
64
|
-
|
65
|
-
freeze
|
66
|
-
end
|
67
|
-
|
68
|
-
# @!method finalized?
|
69
|
-
# Returns true if the booter has been finalized
|
70
|
-
#
|
71
|
-
# @return [Boolean]
|
72
|
-
# @api private
|
73
|
-
alias_method :finalized?, :frozen?
|
74
|
-
|
75
|
-
# @api private
|
76
|
-
def shutdown
|
77
|
-
components.each do |component|
|
78
|
-
next unless booted.include?(component)
|
79
|
-
|
80
|
-
stop(component)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
# @api private
|
85
|
-
def init(name_or_component)
|
86
|
-
with_component(name_or_component) do |component|
|
87
|
-
call(component) do
|
88
|
-
component.init.finalize
|
89
|
-
yield if block_given?
|
90
|
-
end
|
91
|
-
|
92
|
-
self
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
# @api private
|
97
|
-
def start(name_or_component)
|
98
|
-
with_component(name_or_component) do |component|
|
99
|
-
return self if booted.include?(component)
|
100
|
-
|
101
|
-
init(name_or_component) do
|
102
|
-
component.start
|
103
|
-
end
|
104
|
-
|
105
|
-
booted << component.finalize
|
106
|
-
|
107
|
-
self
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
# @api private
|
112
|
-
def stop(name_or_component)
|
113
|
-
call(name_or_component) do |component|
|
114
|
-
raise ComponentNotStartedError, name_or_component unless booted.include?(component)
|
115
|
-
|
116
|
-
component.stop
|
117
|
-
booted.delete(component)
|
118
|
-
|
119
|
-
yield if block_given?
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
# @api private
|
124
|
-
def call(name_or_component)
|
125
|
-
with_component(name_or_component) do |component|
|
126
|
-
raise ComponentFileMismatchError, name unless component
|
127
|
-
|
128
|
-
yield(component) if block_given?
|
129
|
-
|
130
|
-
component
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
# @api private
|
135
|
-
def boot_dependency(component)
|
136
|
-
if (component = find_component(component.root_key))
|
137
|
-
start(component)
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
# Returns all boot files within the configured paths
|
142
|
-
#
|
143
|
-
# Searches for files in the order of the configured paths. In the case of multiple
|
144
|
-
# identically-named boot files within different paths, the file found first will be
|
145
|
-
# returned, and other matching files will be discarded.
|
146
|
-
#
|
147
|
-
# @return [Array<Pathname>]
|
148
|
-
# @api public
|
149
|
-
def boot_files
|
150
|
-
@boot_files ||= paths.each_with_object([[], []]) { |path, (boot_files, loaded)|
|
151
|
-
files = Dir["#{path}/#{RB_GLOB}"].sort
|
152
|
-
|
153
|
-
files.each do |file|
|
154
|
-
basename = File.basename(file)
|
155
|
-
|
156
|
-
unless loaded.include?(basename)
|
157
|
-
boot_files << Pathname(file)
|
158
|
-
loaded << basename
|
159
|
-
end
|
160
|
-
end
|
161
|
-
}.first
|
162
|
-
end
|
163
|
-
|
164
|
-
private
|
165
|
-
|
166
|
-
def with_component(id_or_component)
|
167
|
-
component =
|
168
|
-
case id_or_component
|
169
|
-
when Symbol
|
170
|
-
require_boot_file(id_or_component) unless components.exists?(id_or_component)
|
171
|
-
components[id_or_component]
|
172
|
-
when Components::Bootable
|
173
|
-
id_or_component
|
174
|
-
end
|
175
|
-
|
176
|
-
raise InvalidComponentError, id_or_component unless component
|
177
|
-
|
178
|
-
yield(component)
|
179
|
-
end
|
180
|
-
|
181
|
-
def load_component(path)
|
182
|
-
name = Pathname(path).basename(RB_EXT).to_s.to_sym
|
183
|
-
|
184
|
-
Kernel.require path unless components.exists?(name)
|
185
|
-
|
186
|
-
self
|
187
|
-
end
|
188
|
-
|
189
|
-
def require_boot_file(name)
|
190
|
-
boot_file = find_boot_file(name)
|
191
|
-
|
192
|
-
Kernel.require boot_file if boot_file
|
193
|
-
end
|
194
|
-
|
195
|
-
def find_boot_file(name)
|
196
|
-
boot_files.detect { |file| File.basename(file, RB_EXT) == name.to_s }
|
197
|
-
end
|
198
|
-
end
|
199
|
-
end
|
200
|
-
end
|