dry-system 0.22.0 → 0.25.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +424 -0
- data/LICENSE +1 -1
- data/README.md +3 -3
- data/dry-system.gemspec +4 -5
- data/lib/dry/system/component.rb +10 -5
- data/lib/dry/system/component_dir.rb +14 -35
- 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 +275 -192
- data/lib/dry/system/errors.rb +73 -53
- data/lib/dry/system/identifier.rb +62 -20
- data/lib/dry/system/importer.rb +90 -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} +9 -6
- 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 +329 -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.25.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Solnica
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-07-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -44,40 +44,40 @@ 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
|
64
64
|
requirements:
|
65
65
|
- - "~>"
|
66
66
|
- !ruby/object:Gem::Version
|
67
|
-
version: '0.
|
67
|
+
version: '0.10'
|
68
68
|
- - ">="
|
69
69
|
- !ruby/object:Gem::Version
|
70
|
-
version: 0.
|
70
|
+
version: 0.10.0
|
71
71
|
type: :runtime
|
72
72
|
prerelease: false
|
73
73
|
version_requirements: !ruby/object:Gem::Requirement
|
74
74
|
requirements:
|
75
75
|
- - "~>"
|
76
76
|
- !ruby/object:Gem::Version
|
77
|
-
version: '0.
|
77
|
+
version: '0.10'
|
78
78
|
- - ">="
|
79
79
|
- !ruby/object:Gem::Version
|
80
|
-
version: 0.
|
80
|
+
version: 0.10.0
|
81
81
|
- !ruby/object:Gem::Dependency
|
82
82
|
name: dry-core
|
83
83
|
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,20 +200,25 @@ 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
224
|
post_install_message:
|
@@ -243,7 +229,7 @@ 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
|
- - ">="
|
@@ -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
|