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
@@ -4,19 +4,21 @@ require "dry/system/constants"
|
|
4
4
|
|
5
5
|
module Dry
|
6
6
|
module System
|
7
|
-
# Default
|
7
|
+
# Default manifest registration implementation
|
8
8
|
#
|
9
|
-
# This is
|
10
|
-
#
|
11
|
-
# manual registration paths, which should hold code to explicitly register
|
9
|
+
# This is configured by default for every System::Container. The manifest registrar is
|
10
|
+
# responsible for loading manifest files that contain code to manually register
|
12
11
|
# certain objects with the container.
|
13
12
|
#
|
14
13
|
# @api private
|
15
|
-
class
|
14
|
+
class ManifestRegistrar
|
15
|
+
# @api private
|
16
16
|
attr_reader :container
|
17
17
|
|
18
|
+
# @api private
|
18
19
|
attr_reader :config
|
19
20
|
|
21
|
+
# @api private
|
20
22
|
def initialize(container)
|
21
23
|
@container = container
|
22
24
|
@config = container.config
|
@@ -30,16 +32,13 @@ module Dry
|
|
30
32
|
end
|
31
33
|
|
32
34
|
# @api private
|
33
|
-
def call(
|
34
|
-
|
35
|
-
|
36
|
-
require(root.join(config.registrations_dir, name))
|
35
|
+
def call(component)
|
36
|
+
require(root.join(config.registrations_dir, component.root_key.to_s))
|
37
37
|
end
|
38
38
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
File.exist?(File.join(registrations_dir, "#{name}#{RB_EXT}"))
|
39
|
+
# @api private
|
40
|
+
def file_exists?(component)
|
41
|
+
File.exist?(File.join(registrations_dir, "#{component.root_key}#{RB_EXT}"))
|
43
42
|
end
|
44
43
|
|
45
44
|
private
|
@@ -15,8 +15,9 @@ module Dry
|
|
15
15
|
# @api private
|
16
16
|
def self.extended(system)
|
17
17
|
super
|
18
|
+
|
18
19
|
system.use(:env)
|
19
|
-
system.
|
20
|
+
system.setting :bootsnap, default: DEFAULT_OPTIONS
|
20
21
|
system.after(:configure, &:setup_bootsnap)
|
21
22
|
end
|
22
23
|
|
@@ -36,7 +37,7 @@ module Dry
|
|
36
37
|
|
37
38
|
# @api private
|
38
39
|
def bootsnap_available?
|
39
|
-
RUBY_ENGINE == "ruby" && RUBY_VERSION >= "2.3.0" && RUBY_VERSION < "
|
40
|
+
RUBY_ENGINE == "ruby" && RUBY_VERSION >= "2.3.0" && RUBY_VERSION < "3.1.0"
|
40
41
|
end
|
41
42
|
end
|
42
43
|
end
|
@@ -15,13 +15,49 @@ module Dry
|
|
15
15
|
# @api private
|
16
16
|
def define_initialize(klass)
|
17
17
|
@container["notifications"].instrument(
|
18
|
-
:resolved_dependency,
|
18
|
+
:resolved_dependency,
|
19
|
+
dependency_map: dependency_map.to_h,
|
20
|
+
target_class: klass
|
19
21
|
)
|
22
|
+
|
23
|
+
super(klass)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# @api private
|
28
|
+
class Args < Dry::AutoInject::Strategies::Args
|
29
|
+
private
|
30
|
+
|
31
|
+
# @api private
|
32
|
+
def define_initialize(klass)
|
33
|
+
@container["notifications"].instrument(
|
34
|
+
:resolved_dependency,
|
35
|
+
dependency_map: dependency_map.to_h,
|
36
|
+
target_class: klass
|
37
|
+
)
|
38
|
+
|
39
|
+
super(klass)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class Hash < Dry::AutoInject::Strategies::Hash
|
44
|
+
private
|
45
|
+
|
46
|
+
# @api private
|
47
|
+
def define_initialize(klass)
|
48
|
+
@container["notifications"].instrument(
|
49
|
+
:resolved_dependency,
|
50
|
+
dependency_map: dependency_map.to_h,
|
51
|
+
target_class: klass
|
52
|
+
)
|
53
|
+
|
20
54
|
super(klass)
|
21
55
|
end
|
22
56
|
end
|
23
57
|
|
24
58
|
register :kwargs, Kwargs
|
59
|
+
register :args, Args
|
60
|
+
register :hash, Hash
|
25
61
|
register :default, Kwargs
|
26
62
|
end
|
27
63
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
require "dry/system/plugins/dependency_graph/strategies"
|
3
|
+
require_relative "dependency_graph/strategies"
|
5
4
|
|
6
5
|
module Dry
|
7
6
|
module System
|
@@ -12,36 +11,43 @@ module Dry
|
|
12
11
|
def self.extended(system)
|
13
12
|
super
|
14
13
|
|
15
|
-
system.
|
14
|
+
system.instance_eval do
|
15
|
+
use(:notifications)
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
system.after(:configure) do
|
22
|
-
self[:notifications].register_event(:resolved_dependency)
|
23
|
-
self[:notifications].register_event(:registered_dependency)
|
17
|
+
setting :dependency_graph do
|
18
|
+
setting :ignored_dependencies, default: []
|
19
|
+
end
|
24
20
|
|
25
|
-
|
21
|
+
after(:configure) do
|
22
|
+
self[:notifications].register_event(:resolved_dependency)
|
23
|
+
self[:notifications].register_event(:registered_dependency)
|
24
|
+
end
|
26
25
|
end
|
27
26
|
end
|
28
27
|
|
29
28
|
# @api private
|
30
29
|
def self.dependencies
|
31
|
-
{
|
30
|
+
{"dry-events" => "dry/events/publisher"}
|
32
31
|
end
|
33
32
|
|
34
33
|
# @api private
|
35
|
-
def
|
36
|
-
super
|
34
|
+
def injector(**options)
|
35
|
+
super(**options, strategies: DependencyGraph::Strategies)
|
36
|
+
end
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
38
|
+
# @api private
|
39
|
+
def register(key, contents = nil, options = {}, &block)
|
40
|
+
super.tap do
|
41
|
+
key = key.to_s
|
42
|
+
|
43
|
+
unless config.dependency_graph.ignored_dependencies.include?(key)
|
44
|
+
self[:notifications].instrument(
|
45
|
+
:registered_dependency,
|
46
|
+
key: key,
|
47
|
+
class: self[key].class
|
48
|
+
)
|
49
|
+
end
|
42
50
|
end
|
43
|
-
|
44
|
-
self
|
45
51
|
end
|
46
52
|
end
|
47
53
|
end
|
@@ -10,8 +10,9 @@ module Dry
|
|
10
10
|
attr_reader :options
|
11
11
|
|
12
12
|
# @api private
|
13
|
-
def initialize(options)
|
13
|
+
def initialize(**options)
|
14
14
|
@options = options
|
15
|
+
super()
|
15
16
|
end
|
16
17
|
|
17
18
|
def inferrer
|
@@ -20,7 +21,7 @@ module Dry
|
|
20
21
|
|
21
22
|
# @api private
|
22
23
|
def extended(system)
|
23
|
-
system.setting :env, inferrer.(), reader: true
|
24
|
+
system.setting :env, default: inferrer.(), reader: true
|
24
25
|
super
|
25
26
|
end
|
26
27
|
end
|
@@ -8,14 +8,18 @@ module Dry
|
|
8
8
|
module Logging
|
9
9
|
# @api private
|
10
10
|
def self.extended(system)
|
11
|
-
system.
|
11
|
+
system.instance_eval do
|
12
12
|
setting :logger, reader: true
|
13
13
|
|
14
|
-
setting :log_dir, "log"
|
14
|
+
setting :log_dir, default: "log"
|
15
15
|
|
16
|
-
setting :log_levels,
|
16
|
+
setting :log_levels, default: {
|
17
|
+
development: Logger::DEBUG,
|
18
|
+
test: Logger::DEBUG,
|
19
|
+
production: Logger::ERROR
|
20
|
+
}
|
17
21
|
|
18
|
-
setting :logger_class, ::Logger, reader: true
|
22
|
+
setting :logger_class, default: ::Logger, reader: true
|
19
23
|
end
|
20
24
|
|
21
25
|
system.after(:configure, &:register_logger)
|
@@ -36,7 +40,7 @@ module Dry
|
|
36
40
|
elsif config.logger
|
37
41
|
register(:logger, config.logger)
|
38
42
|
else
|
39
|
-
config.logger =
|
43
|
+
config.logger = config.logger_class.new(log_file_path)
|
40
44
|
config.logger.level = log_level
|
41
45
|
|
42
46
|
register(:logger, config.logger)
|
@@ -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
|
@@ -84,21 +84,19 @@ module Dry
|
|
84
84
|
# Enables a plugin if not already enabled.
|
85
85
|
# Raises error if plugin cannot be found in the plugin registry.
|
86
86
|
#
|
87
|
-
#
|
88
|
-
#
|
89
|
-
# @param [Symbol] name The plugin identifier
|
87
|
+
# @param [Symbol] name The plugin name
|
90
88
|
# @param [Hash] options Plugin options
|
91
89
|
#
|
92
90
|
# @return [self]
|
93
91
|
#
|
94
92
|
# @api public
|
95
|
-
def use(name, options
|
93
|
+
def use(name, **options)
|
96
94
|
return self if enabled_plugins.include?(name)
|
97
95
|
|
98
96
|
raise PluginNotFoundError, name unless (plugin = Plugins.registry[name])
|
99
97
|
|
100
98
|
plugin.load_dependencies
|
101
|
-
plugin.apply_to(self, options)
|
99
|
+
plugin.apply_to(self, **options)
|
102
100
|
|
103
101
|
enabled_plugins << name
|
104
102
|
|
@@ -133,6 +131,9 @@ module Dry
|
|
133
131
|
|
134
132
|
require "dry/system/plugins/dependency_graph"
|
135
133
|
register(:dependency_graph, Plugins::DependencyGraph)
|
134
|
+
|
135
|
+
require "dry/system/plugins/zeitwerk"
|
136
|
+
register(:zeitwerk, Plugins::Zeitwerk)
|
136
137
|
end
|
137
138
|
end
|
138
139
|
end
|