dry-system 0.19.2 → 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 +472 -1
- data/LICENSE +1 -1
- data/README.md +4 -3
- data/dry-system.gemspec +16 -15
- data/lib/dry/system/auto_registrar.rb +1 -13
- data/lib/dry/system/component.rb +104 -47
- data/lib/dry/system/component_dir.rb +88 -47
- data/lib/dry/system/components.rb +8 -4
- data/lib/dry/system/config/component_dir.rb +141 -53
- data/lib/dry/system/config/component_dirs.rb +176 -70
- data/lib/dry/system/config/namespace.rb +76 -0
- data/lib/dry/system/config/namespaces.rb +208 -0
- data/lib/dry/system/constants.rb +2 -2
- data/lib/dry/system/container.rb +279 -201
- data/lib/dry/system/errors.rb +72 -61
- data/lib/dry/system/identifier.rb +99 -79
- data/lib/dry/system/importer.rb +83 -12
- data/lib/dry/system/indirect_component.rb +65 -0
- data/lib/dry/system/loader.rb +8 -4
- data/lib/dry/system/{manual_registrar.rb → manifest_registrar.rb} +12 -13
- 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 +3 -2
- data/lib/dry/system/plugins/logging.rb +9 -5
- 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 +8 -7
- 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 +264 -24
- 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/stubs.rb +1 -1
- data/lib/dry/system/version.rb +1 -1
- data/lib/dry/system.rb +45 -13
- metadata +25 -22
- 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 -289
- 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 -67
- 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/stubs.rb
CHANGED
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[identifier].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
|
20
|
-
def self.
|
21
|
-
|
22
|
-
|
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
|
+
|
46
|
+
def self.register_component(name, provider:, &block)
|
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.23.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:
|
11
|
+
date: 2022-02-08 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.9'
|
68
68
|
- - ">="
|
69
69
|
- !ruby/object:Gem::Version
|
70
|
-
version: 0.
|
70
|
+
version: 0.9.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.9'
|
78
78
|
- - ">="
|
79
79
|
- !ruby/object:Gem::Version
|
80
|
-
version: 0.
|
80
|
+
version: 0.9.0
|
81
81
|
- !ruby/object:Gem::Dependency
|
82
82
|
name: dry-core
|
83
83
|
requirement: !ruby/object:Gem::Requirement
|
@@ -188,25 +188,23 @@ files:
|
|
188
188
|
- lib/dry-system.rb
|
189
189
|
- lib/dry/system.rb
|
190
190
|
- lib/dry/system/auto_registrar.rb
|
191
|
-
- lib/dry/system/booter.rb
|
192
|
-
- lib/dry/system/booter/component_registry.rb
|
193
191
|
- lib/dry/system/component.rb
|
194
192
|
- lib/dry/system/component_dir.rb
|
195
193
|
- lib/dry/system/components.rb
|
196
|
-
- lib/dry/system/components/bootable.rb
|
197
|
-
- lib/dry/system/components/config.rb
|
198
194
|
- lib/dry/system/config/component_dir.rb
|
199
195
|
- lib/dry/system/config/component_dirs.rb
|
196
|
+
- lib/dry/system/config/namespace.rb
|
197
|
+
- lib/dry/system/config/namespaces.rb
|
200
198
|
- lib/dry/system/constants.rb
|
201
199
|
- lib/dry/system/container.rb
|
202
200
|
- lib/dry/system/errors.rb
|
203
201
|
- lib/dry/system/identifier.rb
|
204
202
|
- lib/dry/system/importer.rb
|
205
|
-
- lib/dry/system/
|
203
|
+
- lib/dry/system/indirect_component.rb
|
206
204
|
- lib/dry/system/loader.rb
|
207
205
|
- lib/dry/system/loader/autoloading.rb
|
208
206
|
- lib/dry/system/magic_comments_parser.rb
|
209
|
-
- lib/dry/system/
|
207
|
+
- lib/dry/system/manifest_registrar.rb
|
210
208
|
- lib/dry/system/plugins.rb
|
211
209
|
- lib/dry/system/plugins/bootsnap.rb
|
212
210
|
- lib/dry/system/plugins/dependency_graph.rb
|
@@ -216,13 +214,18 @@ files:
|
|
216
214
|
- lib/dry/system/plugins/monitoring.rb
|
217
215
|
- lib/dry/system/plugins/monitoring/proxy.rb
|
218
216
|
- lib/dry/system/plugins/notifications.rb
|
217
|
+
- lib/dry/system/plugins/zeitwerk.rb
|
218
|
+
- lib/dry/system/plugins/zeitwerk/compat_inflector.rb
|
219
219
|
- lib/dry/system/provider.rb
|
220
|
-
- lib/dry/system/
|
221
|
-
- lib/dry/system/
|
222
|
-
- lib/dry/system/
|
223
|
-
- lib/dry/system/
|
220
|
+
- lib/dry/system/provider/source.rb
|
221
|
+
- lib/dry/system/provider/source_dsl.rb
|
222
|
+
- lib/dry/system/provider_registrar.rb
|
223
|
+
- lib/dry/system/provider_source_registry.rb
|
224
|
+
- lib/dry/system/provider_sources.rb
|
225
|
+
- lib/dry/system/provider_sources/settings.rb
|
226
|
+
- lib/dry/system/provider_sources/settings/config.rb
|
227
|
+
- lib/dry/system/provider_sources/settings/loader.rb
|
224
228
|
- lib/dry/system/stubs.rb
|
225
|
-
- lib/dry/system/system_components/settings.rb
|
226
229
|
- lib/dry/system/version.rb
|
227
230
|
homepage: https://dry-rb.org/gems/dry-system
|
228
231
|
licenses:
|
@@ -240,7 +243,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
240
243
|
requirements:
|
241
244
|
- - ">="
|
242
245
|
- !ruby/object:Gem::Version
|
243
|
-
version: 2.
|
246
|
+
version: 2.7.0
|
244
247
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
245
248
|
requirements:
|
246
249
|
- - ">="
|
@@ -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.identifier == name }
|
25
|
-
end
|
26
|
-
|
27
|
-
def [](name)
|
28
|
-
component = components.detect { |component| component.identifier == name }
|
29
|
-
|
30
|
-
component || raise(InvalidComponentIdentifierError, 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
|
-
identifier = Pathname(path).basename(RB_EXT).to_s.to_sym
|
183
|
-
|
184
|
-
Kernel.require path unless components.exists?(identifier)
|
185
|
-
|
186
|
-
self
|
187
|
-
end
|
188
|
-
|
189
|
-
def require_boot_file(identifier)
|
190
|
-
boot_file = find_boot_file(identifier)
|
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
|