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.
- checksums.yaml +7 -0
- data/dry-system-1.2.5/CHANGELOG.md +1311 -0
- data/dry-system-1.2.5/LICENSE +21 -0
- data/dry-system-1.2.5/README.md +17 -0
- data/dry-system-1.2.5/dry-system.gemspec +42 -0
- data/dry-system-1.2.5/lib/dry/system/auto_registrar.rb +45 -0
- data/dry-system-1.2.5/lib/dry/system/component.rb +190 -0
- data/dry-system-1.2.5/lib/dry/system/component_dir.rb +171 -0
- data/dry-system-1.2.5/lib/dry/system/config/component_dir.rb +228 -0
- data/dry-system-1.2.5/lib/dry/system/config/component_dirs.rb +285 -0
- data/dry-system-1.2.5/lib/dry/system/config/namespace.rb +75 -0
- data/dry-system-1.2.5/lib/dry/system/config/namespaces.rb +192 -0
- data/dry-system-1.2.5/lib/dry/system/constants.rb +13 -0
- data/dry-system-1.2.5/lib/dry/system/container.rb +685 -0
- data/dry-system-1.2.5/lib/dry/system/errors.rb +132 -0
- data/dry-system-1.2.5/lib/dry/system/identifier.rb +176 -0
- data/dry-system-1.2.5/lib/dry/system/importer.rb +144 -0
- data/dry-system-1.2.5/lib/dry/system/indirect_component.rb +63 -0
- data/dry-system-1.2.5/lib/dry/system/loader/autoloading.rb +24 -0
- data/dry-system-1.2.5/lib/dry/system/loader.rb +84 -0
- data/dry-system-1.2.5/lib/dry/system/magic_comments_parser.rb +31 -0
- data/dry-system-1.2.5/lib/dry/system/manifest_registrar.rb +57 -0
- data/dry-system-1.2.5/lib/dry/system/plugins/bootsnap.rb +47 -0
- data/dry-system-1.2.5/lib/dry/system/plugins/dependency_graph/strategies.rb +66 -0
- data/dry-system-1.2.5/lib/dry/system/plugins/dependency_graph.rb +53 -0
- data/dry-system-1.2.5/lib/dry/system/plugins/env.rb +30 -0
- data/dry-system-1.2.5/lib/dry/system/plugins/logging.rb +73 -0
- data/dry-system-1.2.5/lib/dry/system/plugins/monitoring/proxy.rb +51 -0
- data/dry-system-1.2.5/lib/dry/system/plugins/monitoring.rb +45 -0
- data/dry-system-1.2.5/lib/dry/system/plugins/notifications.rb +27 -0
- data/dry-system-1.2.5/lib/dry/system/plugins/plugin.rb +61 -0
- data/dry-system-1.2.5/lib/dry/system/plugins/zeitwerk/compat_inflector.rb +22 -0
- data/dry-system-1.2.5/lib/dry/system/plugins/zeitwerk.rb +109 -0
- data/dry-system-1.2.5/lib/dry/system/plugins.rb +70 -0
- data/dry-system-1.2.5/lib/dry/system/provider/source.rb +281 -0
- data/dry-system-1.2.5/lib/dry/system/provider/source_dsl.rb +55 -0
- data/dry-system-1.2.5/lib/dry/system/provider.rb +291 -0
- data/dry-system-1.2.5/lib/dry/system/provider_registrar.rb +289 -0
- data/dry-system-1.2.5/lib/dry/system/provider_source_registry.rb +67 -0
- data/dry-system-1.2.5/lib/dry/system/provider_sources/settings/config.rb +73 -0
- data/dry-system-1.2.5/lib/dry/system/provider_sources/settings/loader.rb +44 -0
- data/dry-system-1.2.5/lib/dry/system/provider_sources/settings.rb +40 -0
- data/dry-system-1.2.5/lib/dry/system/provider_sources.rb +6 -0
- data/dry-system-1.2.5/lib/dry/system/stubs.rb +39 -0
- data/dry-system-1.2.5/lib/dry/system/version.rb +7 -0
- data/dry-system-1.2.5/lib/dry/system.rb +62 -0
- data/dry-system-1.2.5/lib/dry-system.rb +3 -0
- data/piko-quick-lib.gemspec +11 -0
- metadata +87 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "dry/system/constants"
|
|
4
|
+
|
|
5
|
+
module Dry
|
|
6
|
+
module System
|
|
7
|
+
# Default manifest registration implementation
|
|
8
|
+
#
|
|
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
|
|
11
|
+
# certain objects with the container.
|
|
12
|
+
#
|
|
13
|
+
# @api private
|
|
14
|
+
class ManifestRegistrar
|
|
15
|
+
# @api private
|
|
16
|
+
attr_reader :container
|
|
17
|
+
|
|
18
|
+
# @api private
|
|
19
|
+
attr_reader :config
|
|
20
|
+
|
|
21
|
+
# @api private
|
|
22
|
+
def initialize(container)
|
|
23
|
+
@container = container
|
|
24
|
+
@config = container.config
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# @api private
|
|
28
|
+
def finalize!
|
|
29
|
+
::Dir[registrations_dir.join(RB_GLOB)].each do |file|
|
|
30
|
+
call(Identifier.new(File.basename(file, RB_EXT)))
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# @api private
|
|
35
|
+
def call(component)
|
|
36
|
+
load(root.join(config.registrations_dir, "#{component.root_key}#{RB_EXT}"))
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# @api private
|
|
40
|
+
def file_exists?(component)
|
|
41
|
+
::File.exist?(::File.join(registrations_dir, "#{component.root_key}#{RB_EXT}"))
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
# @api private
|
|
47
|
+
def registrations_dir
|
|
48
|
+
root.join(config.registrations_dir)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# @api private
|
|
52
|
+
def root
|
|
53
|
+
container.root
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Dry
|
|
4
|
+
module System
|
|
5
|
+
module Plugins
|
|
6
|
+
module Bootsnap
|
|
7
|
+
DEFAULT_OPTIONS = {
|
|
8
|
+
load_path_cache: true,
|
|
9
|
+
compile_cache_iseq: true,
|
|
10
|
+
compile_cache_yaml: true
|
|
11
|
+
}.freeze
|
|
12
|
+
|
|
13
|
+
# @api private
|
|
14
|
+
def self.extended(system)
|
|
15
|
+
super
|
|
16
|
+
|
|
17
|
+
system.use(:env)
|
|
18
|
+
system.setting :bootsnap, default: DEFAULT_OPTIONS
|
|
19
|
+
system.after(:configure, &:setup_bootsnap)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @api private
|
|
23
|
+
def self.dependencies
|
|
24
|
+
{bootsnap: "bootsnap"}
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Set up bootsnap for faster booting
|
|
28
|
+
#
|
|
29
|
+
# @api public
|
|
30
|
+
def setup_bootsnap
|
|
31
|
+
return unless bootsnap_available?
|
|
32
|
+
|
|
33
|
+
::Bootsnap.setup(**config.bootsnap, cache_dir: root.join("tmp/cache").to_s)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# @api private
|
|
37
|
+
def bootsnap_available?
|
|
38
|
+
spec = Gem.loaded_specs["bootsnap"] or return false
|
|
39
|
+
|
|
40
|
+
RUBY_ENGINE == "ruby" &&
|
|
41
|
+
spec.match_platform(RUBY_PLATFORM) &&
|
|
42
|
+
spec.required_ruby_version.satisfied_by?(Gem::Version.new(RUBY_VERSION))
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Dry
|
|
4
|
+
module System
|
|
5
|
+
module Plugins
|
|
6
|
+
module DependencyGraph
|
|
7
|
+
# @api private
|
|
8
|
+
class Strategies
|
|
9
|
+
extend Core::Container::Mixin
|
|
10
|
+
|
|
11
|
+
# @api private
|
|
12
|
+
class Kwargs < Dry::AutoInject::Strategies::Kwargs
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
# @api private
|
|
16
|
+
def define_initialize(klass)
|
|
17
|
+
@container["notifications"].instrument(
|
|
18
|
+
:resolved_dependency,
|
|
19
|
+
dependency_map: dependency_map.to_h,
|
|
20
|
+
target_class: klass
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
super
|
|
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
|
|
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
|
+
|
|
54
|
+
super
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
register :kwargs, Kwargs
|
|
59
|
+
register :args, Args
|
|
60
|
+
register :hash, Hash
|
|
61
|
+
register :default, Kwargs
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Dry
|
|
4
|
+
module System
|
|
5
|
+
module Plugins
|
|
6
|
+
# @api public
|
|
7
|
+
module DependencyGraph
|
|
8
|
+
# @api private
|
|
9
|
+
def self.extended(system)
|
|
10
|
+
super
|
|
11
|
+
|
|
12
|
+
system.instance_eval do
|
|
13
|
+
use(:notifications)
|
|
14
|
+
|
|
15
|
+
setting :dependency_graph do
|
|
16
|
+
setting :ignored_dependencies, default: []
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
after(:configure) do
|
|
20
|
+
self[:notifications].register_event(:resolved_dependency)
|
|
21
|
+
self[:notifications].register_event(:registered_dependency)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# @api private
|
|
27
|
+
def self.dependencies
|
|
28
|
+
{"dry-events" => "dry/events/publisher"}
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# @api private
|
|
32
|
+
def injector(**options)
|
|
33
|
+
super(**options, strategies: DependencyGraph::Strategies)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# @api private
|
|
37
|
+
def register(key, contents = nil, options = {}, &)
|
|
38
|
+
super.tap do
|
|
39
|
+
key = key.to_s
|
|
40
|
+
|
|
41
|
+
unless config.dependency_graph.ignored_dependencies.include?(key)
|
|
42
|
+
self[:notifications].instrument(
|
|
43
|
+
:registered_dependency,
|
|
44
|
+
key: key,
|
|
45
|
+
class: self[key].class
|
|
46
|
+
)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Dry
|
|
4
|
+
module System
|
|
5
|
+
module Plugins
|
|
6
|
+
# @api public
|
|
7
|
+
class Env < Module
|
|
8
|
+
DEFAULT_INFERRER = -> { :development }
|
|
9
|
+
|
|
10
|
+
attr_reader :options
|
|
11
|
+
|
|
12
|
+
# @api private
|
|
13
|
+
def initialize(**options)
|
|
14
|
+
@options = options
|
|
15
|
+
super()
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def inferrer
|
|
19
|
+
options.fetch(:inferrer, DEFAULT_INFERRER)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @api private
|
|
23
|
+
def extended(system)
|
|
24
|
+
system.setting :env, default: inferrer.(), reader: true
|
|
25
|
+
super
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "logger"
|
|
4
|
+
|
|
5
|
+
module Dry
|
|
6
|
+
module System
|
|
7
|
+
module Plugins
|
|
8
|
+
module Logging
|
|
9
|
+
# @api private
|
|
10
|
+
def self.extended(system)
|
|
11
|
+
system.instance_eval do
|
|
12
|
+
setting :logger, reader: true
|
|
13
|
+
|
|
14
|
+
setting :log_dir, default: "log"
|
|
15
|
+
|
|
16
|
+
setting :log_levels, default: {
|
|
17
|
+
development: Logger::DEBUG,
|
|
18
|
+
test: Logger::DEBUG,
|
|
19
|
+
production: Logger::ERROR
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
setting :logger_class, default: ::Logger, reader: true
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
system.after(:configure, &:register_logger)
|
|
26
|
+
|
|
27
|
+
super
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Set a logger
|
|
31
|
+
#
|
|
32
|
+
# This is invoked automatically when a container is being configured
|
|
33
|
+
#
|
|
34
|
+
# @return [self]
|
|
35
|
+
#
|
|
36
|
+
# @api private
|
|
37
|
+
def register_logger
|
|
38
|
+
if registered?(:logger)
|
|
39
|
+
self
|
|
40
|
+
elsif config.logger
|
|
41
|
+
register(:logger, config.logger)
|
|
42
|
+
else
|
|
43
|
+
config.logger = config.logger_class.new(log_file_path)
|
|
44
|
+
config.logger.level = log_level
|
|
45
|
+
|
|
46
|
+
register(:logger, config.logger)
|
|
47
|
+
self
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# @api private
|
|
52
|
+
def log_level
|
|
53
|
+
config.log_levels.fetch(config.env, Logger::ERROR)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# @api private
|
|
57
|
+
def log_dir_path
|
|
58
|
+
root.join(config.log_dir).realpath
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# @api private
|
|
62
|
+
def log_file_path
|
|
63
|
+
log_dir_path.join(log_file_name)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# @api private
|
|
67
|
+
def log_file_name
|
|
68
|
+
"#{config.env}.log"
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "delegate"
|
|
4
|
+
|
|
5
|
+
module Dry
|
|
6
|
+
module System
|
|
7
|
+
module Plugins
|
|
8
|
+
module Monitoring
|
|
9
|
+
# @api private
|
|
10
|
+
class Proxy < SimpleDelegator
|
|
11
|
+
# @api private
|
|
12
|
+
def self.for(target, key:, methods: [])
|
|
13
|
+
monitored_methods =
|
|
14
|
+
if methods.empty?
|
|
15
|
+
target.public_methods - Object.public_instance_methods
|
|
16
|
+
else
|
|
17
|
+
methods
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
Class.new(self) do
|
|
21
|
+
extend Dry::Core::ClassAttributes
|
|
22
|
+
include Dry::Events::Publisher[target.class.name]
|
|
23
|
+
|
|
24
|
+
defines :monitored_methods
|
|
25
|
+
|
|
26
|
+
attr_reader :__notifications__
|
|
27
|
+
|
|
28
|
+
monitored_methods(monitored_methods)
|
|
29
|
+
|
|
30
|
+
monitored_methods.each do |meth|
|
|
31
|
+
define_method(meth) do |*args, **kwargs, &block|
|
|
32
|
+
object = __getobj__
|
|
33
|
+
opts = {target: key, object: object, method: meth, args: args, kwargs: kwargs}
|
|
34
|
+
|
|
35
|
+
__notifications__.instrument(:monitoring, opts) do
|
|
36
|
+
object.public_send(meth, *args, **kwargs, &block)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def initialize(target, notifications)
|
|
44
|
+
super(target)
|
|
45
|
+
@__notifications__ = notifications
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "dry/system/constants"
|
|
4
|
+
|
|
5
|
+
module Dry
|
|
6
|
+
module System
|
|
7
|
+
module Plugins
|
|
8
|
+
# @api public
|
|
9
|
+
module Monitoring
|
|
10
|
+
# @api private
|
|
11
|
+
def self.extended(system)
|
|
12
|
+
super
|
|
13
|
+
|
|
14
|
+
system.use(:notifications)
|
|
15
|
+
|
|
16
|
+
system.after(:configure) do
|
|
17
|
+
self[:notifications].register_event(:monitoring)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# @api private
|
|
22
|
+
def self.dependencies
|
|
23
|
+
{"dry-events": "dry/events/publisher"}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# @api private
|
|
27
|
+
def monitor(key, **options, &block)
|
|
28
|
+
notifications = self[:notifications]
|
|
29
|
+
|
|
30
|
+
resolve(key).tap do |target|
|
|
31
|
+
proxy = Proxy.for(target, **options, key: key)
|
|
32
|
+
|
|
33
|
+
if block_given?
|
|
34
|
+
proxy.monitored_methods.each do |meth|
|
|
35
|
+
notifications.subscribe(:monitoring, target: key, method: meth, &block)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
decorate(key, with: -> tgt { proxy.new(tgt, notifications) })
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Dry
|
|
4
|
+
module System
|
|
5
|
+
module Plugins
|
|
6
|
+
# @api public
|
|
7
|
+
module Notifications
|
|
8
|
+
# @api private
|
|
9
|
+
def self.extended(system)
|
|
10
|
+
system.after(:configure, &:register_notifications)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# @api private
|
|
14
|
+
def self.dependencies
|
|
15
|
+
{"dry-monitor": "dry/monitor"}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# @api private
|
|
19
|
+
def register_notifications
|
|
20
|
+
return self if registered?(:notifications)
|
|
21
|
+
|
|
22
|
+
register(:notifications, Monitor::Notifications.new(config.name))
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Dry
|
|
4
|
+
module System
|
|
5
|
+
module Plugins
|
|
6
|
+
# @api private
|
|
7
|
+
class Plugin
|
|
8
|
+
attr_reader :name
|
|
9
|
+
|
|
10
|
+
attr_reader :mod
|
|
11
|
+
|
|
12
|
+
attr_reader :block
|
|
13
|
+
|
|
14
|
+
# @api private
|
|
15
|
+
def initialize(name, mod, &block)
|
|
16
|
+
@name = name
|
|
17
|
+
@mod = mod
|
|
18
|
+
@block = block
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# @api private
|
|
22
|
+
def apply_to(system, **options)
|
|
23
|
+
system.extend(stateful? ? mod.new(**options) : mod)
|
|
24
|
+
system.instance_eval(&block) if block
|
|
25
|
+
system
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# @api private
|
|
29
|
+
def load_dependencies(dependencies = mod_dependencies, gem = nil)
|
|
30
|
+
Array(dependencies).each do |dependency|
|
|
31
|
+
if dependency.is_a?(Array) || dependency.is_a?(Hash)
|
|
32
|
+
dependency.each { |value| load_dependencies(*Array(value).reverse) }
|
|
33
|
+
elsif !Plugins.loaded_dependencies.include?(dependency.to_s)
|
|
34
|
+
load_dependency(dependency, gem)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# @api private
|
|
40
|
+
def load_dependency(dependency, gem)
|
|
41
|
+
Kernel.require dependency
|
|
42
|
+
Plugins.loaded_dependencies << dependency.to_s
|
|
43
|
+
rescue LoadError => exception
|
|
44
|
+
raise PluginDependencyMissing.new(name, exception.message, gem)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# @api private
|
|
48
|
+
def stateful?
|
|
49
|
+
mod < Module
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# @api private
|
|
53
|
+
def mod_dependencies
|
|
54
|
+
return EMPTY_ARRAY unless mod.respond_to?(:dependencies)
|
|
55
|
+
|
|
56
|
+
mod.dependencies.is_a?(Array) ? mod.dependencies : [mod.dependencies]
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -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
|