dry-system 0.15.0 → 0.19.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 +4 -4
- data/CHANGELOG.md +142 -2
- data/LICENSE +1 -1
- data/README.md +1 -1
- data/dry-system.gemspec +5 -4
- data/lib/dry-system.rb +1 -1
- data/lib/dry/system.rb +2 -2
- data/lib/dry/system/auto_registrar.rb +17 -59
- data/lib/dry/system/booter.rb +68 -41
- data/lib/dry/system/component.rb +62 -100
- data/lib/dry/system/component_dir.rb +128 -0
- data/lib/dry/system/components.rb +2 -2
- data/lib/dry/system/components/bootable.rb +6 -34
- data/lib/dry/system/components/config.rb +2 -2
- data/lib/dry/system/config/component_dir.rb +202 -0
- data/lib/dry/system/config/component_dirs.rb +184 -0
- data/lib/dry/system/constants.rb +5 -5
- data/lib/dry/system/container.rb +133 -184
- data/lib/dry/system/errors.rb +21 -16
- data/lib/dry/system/identifier.rb +157 -0
- data/lib/dry/system/lifecycle.rb +2 -2
- data/lib/dry/system/loader.rb +40 -41
- data/lib/dry/system/loader/autoloading.rb +26 -0
- data/lib/dry/system/magic_comments_parser.rb +2 -2
- data/lib/dry/system/manual_registrar.rb +1 -1
- data/lib/dry/system/plugins.rb +7 -7
- data/lib/dry/system/plugins/bootsnap.rb +3 -3
- data/lib/dry/system/plugins/dependency_graph.rb +3 -3
- data/lib/dry/system/plugins/dependency_graph/strategies.rb +1 -1
- data/lib/dry/system/plugins/logging.rb +5 -5
- data/lib/dry/system/plugins/monitoring.rb +3 -3
- data/lib/dry/system/plugins/monitoring/proxy.rb +3 -3
- data/lib/dry/system/plugins/notifications.rb +1 -1
- data/lib/dry/system/provider.rb +3 -3
- data/lib/dry/system/settings.rb +6 -6
- data/lib/dry/system/settings/file_loader.rb +2 -2
- data/lib/dry/system/settings/file_parser.rb +1 -1
- data/lib/dry/system/stubs.rb +1 -1
- data/lib/dry/system/system_components/settings.rb +1 -1
- data/lib/dry/system/version.rb +1 -1
- metadata +21 -25
- data/lib/dry/system/auto_registrar/configuration.rb +0 -43
data/lib/dry/system/component.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "concurrent/map"
|
4
4
|
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
5
|
+
require "dry/core/equalizer"
|
6
|
+
require "dry/inflector"
|
7
|
+
require "dry/system/loader"
|
8
|
+
require "dry/system/errors"
|
9
|
+
require "dry/system/constants"
|
10
|
+
require_relative "identifier"
|
10
11
|
|
11
12
|
module Dry
|
12
13
|
module System
|
@@ -14,157 +15,118 @@ module Dry
|
|
14
15
|
# They expose an API to query this information and use a configurable
|
15
16
|
# loader object to initialize class instances.
|
16
17
|
#
|
17
|
-
# Components are created automatically through auto-registration and can be
|
18
|
-
# accessed through `Container.auto_register!` which yields them.
|
19
|
-
#
|
20
18
|
# @api public
|
21
19
|
class Component
|
22
|
-
include Dry::Equalizer(:identifier, :
|
20
|
+
include Dry::Equalizer(:identifier, :file_path, :options)
|
23
21
|
|
24
22
|
DEFAULT_OPTIONS = {
|
25
23
|
separator: DEFAULT_SEPARATOR,
|
26
|
-
|
27
|
-
|
24
|
+
inflector: Dry::Inflector.new,
|
25
|
+
loader: Loader
|
28
26
|
}.freeze
|
29
27
|
|
30
28
|
# @!attribute [r] identifier
|
31
29
|
# @return [String] component's unique identifier
|
32
30
|
attr_reader :identifier
|
33
31
|
|
34
|
-
# @!attribute [r]
|
35
|
-
# @return [String] component's
|
36
|
-
attr_reader :
|
37
|
-
|
38
|
-
# @!attribute [r] file
|
39
|
-
# @return [String] component's file name
|
40
|
-
attr_reader :file
|
32
|
+
# @!attribute [r] file_path
|
33
|
+
# @return [String, nil] full path to the component's file, if found
|
34
|
+
attr_reader :file_path
|
41
35
|
|
42
36
|
# @!attribute [r] options
|
43
37
|
# @return [Hash] component's options
|
44
38
|
attr_reader :options
|
45
39
|
|
46
|
-
# @!attribute [r] loader
|
47
|
-
# @return [Object#call] component's loader object
|
48
|
-
attr_reader :loader
|
49
|
-
|
50
40
|
# @api private
|
51
|
-
def self.new(
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
identifier = ns ? remove_namespace_from_name(name_s, ns) : name_s
|
70
|
-
|
71
|
-
identifier.scan(WORD_REGEX).join(sep)
|
72
|
-
end
|
73
|
-
|
74
|
-
# @api private
|
75
|
-
def self.remove_namespace_from_name(name, ns)
|
76
|
-
match_value = name.match(/^(?<remove_namespace>#{ns})(?<separator>\W)(?<identifier>.*)/)
|
77
|
-
|
78
|
-
match_value ? match_value[:identifier] : name
|
41
|
+
def self.new(identifier, options = EMPTY_HASH)
|
42
|
+
options = DEFAULT_OPTIONS.merge(options)
|
43
|
+
|
44
|
+
namespace = options.delete(:namespace)
|
45
|
+
separator = options.delete(:separator)
|
46
|
+
|
47
|
+
identifier =
|
48
|
+
if identifier.is_a?(Identifier)
|
49
|
+
identifier
|
50
|
+
else
|
51
|
+
Identifier.new(
|
52
|
+
identifier,
|
53
|
+
namespace: namespace,
|
54
|
+
separator: separator
|
55
|
+
)
|
56
|
+
end
|
57
|
+
|
58
|
+
super(identifier, **options)
|
79
59
|
end
|
80
60
|
|
81
61
|
# @api private
|
82
|
-
def
|
83
|
-
@cache ||= Concurrent::Map.new
|
84
|
-
end
|
85
|
-
|
86
|
-
# @api private
|
87
|
-
def initialize(identifier, path, options)
|
62
|
+
def initialize(identifier, file_path: nil, **options)
|
88
63
|
@identifier = identifier
|
89
|
-
@
|
64
|
+
@file_path = file_path
|
90
65
|
@options = options
|
91
|
-
@file = "#{path}#{RB_EXT}"
|
92
|
-
@loader = options.fetch(:loader)
|
93
|
-
freeze
|
94
66
|
end
|
95
67
|
|
96
|
-
# Returns
|
97
|
-
#
|
98
|
-
# @example
|
99
|
-
# class MyApp < Dry::System::Container
|
100
|
-
# configure do |config|
|
101
|
-
# config.name = :my_app
|
102
|
-
# config.root = Pathname('/my/app')
|
103
|
-
# end
|
104
|
-
#
|
105
|
-
# auto_register!('lib/clients') do |component|
|
106
|
-
# # some custom initialization logic, ie:
|
107
|
-
# constant = component.loader.constant
|
108
|
-
# constant.create
|
109
|
-
# end
|
110
|
-
# end
|
68
|
+
# Returns the component's instance
|
111
69
|
#
|
112
70
|
# @return [Object] component's class instance
|
113
|
-
#
|
114
71
|
# @api public
|
115
72
|
def instance(*args)
|
116
|
-
loader.call(*args)
|
73
|
+
loader.call(self, *args)
|
117
74
|
end
|
118
75
|
ruby2_keywords(:instance) if respond_to?(:ruby2_keywords, true)
|
119
76
|
|
120
77
|
# @api private
|
121
|
-
def
|
78
|
+
def bootable?
|
122
79
|
false
|
123
80
|
end
|
124
81
|
|
125
|
-
|
126
|
-
|
127
|
-
paths.any? { |path| path.join(file).exist? }
|
82
|
+
def key
|
83
|
+
identifier.to_s
|
128
84
|
end
|
129
85
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
86
|
+
def path
|
87
|
+
identifier.path
|
88
|
+
end
|
89
|
+
|
90
|
+
def root_key
|
91
|
+
identifier.root_key
|
135
92
|
end
|
136
93
|
|
94
|
+
# Returns true if the component has a corresponding file
|
95
|
+
#
|
96
|
+
# @return [Boolean]
|
137
97
|
# @api private
|
138
|
-
def
|
139
|
-
|
140
|
-
path, options.merge(loader: loader.class, namespace: namespace)
|
141
|
-
)
|
98
|
+
def file_exists?
|
99
|
+
!!file_path
|
142
100
|
end
|
143
101
|
|
144
102
|
# @api private
|
145
|
-
def
|
146
|
-
options[:
|
103
|
+
def loader
|
104
|
+
options[:loader]
|
147
105
|
end
|
148
106
|
|
149
107
|
# @api private
|
150
|
-
def
|
151
|
-
options[:
|
108
|
+
def inflector
|
109
|
+
options[:inflector]
|
152
110
|
end
|
153
111
|
|
154
112
|
# @api private
|
155
113
|
def auto_register?
|
156
|
-
|
114
|
+
callable_option?(options[:auto_register])
|
157
115
|
end
|
158
116
|
|
159
117
|
# @api private
|
160
|
-
def
|
161
|
-
|
118
|
+
def memoize?
|
119
|
+
callable_option?(options[:memoize])
|
162
120
|
end
|
163
121
|
|
164
122
|
private
|
165
123
|
|
166
|
-
def
|
167
|
-
|
124
|
+
def callable_option?(value)
|
125
|
+
if value.respond_to?(:call)
|
126
|
+
!!value.call(self)
|
127
|
+
else
|
128
|
+
!!value
|
129
|
+
end
|
168
130
|
end
|
169
131
|
end
|
170
132
|
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require "pathname"
|
2
|
+
require_relative "constants"
|
3
|
+
require_relative "identifier"
|
4
|
+
require_relative "magic_comments_parser"
|
5
|
+
|
6
|
+
module Dry
|
7
|
+
module System
|
8
|
+
# A configured component directory within the container's root. Provides access to the
|
9
|
+
# component directory's configuration, as well as methods for locating component files
|
10
|
+
# within the directory
|
11
|
+
#
|
12
|
+
# @see Dry::System::Config::ComponentDir
|
13
|
+
# @api private
|
14
|
+
class ComponentDir
|
15
|
+
# @!attribute [r] config
|
16
|
+
# @return [Dry::System::Config::ComponentDir] the component directory configuration
|
17
|
+
# @api private
|
18
|
+
attr_reader :config
|
19
|
+
|
20
|
+
# @!attribute [r] container
|
21
|
+
# @return [Dry::System::Container] the container managing the component directory
|
22
|
+
# @api private
|
23
|
+
attr_reader :container
|
24
|
+
|
25
|
+
# @api private
|
26
|
+
def initialize(config:, container:)
|
27
|
+
@config = config
|
28
|
+
@container = container
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns a component for a given identifier if a matching component file could be
|
32
|
+
# found within the component dir
|
33
|
+
#
|
34
|
+
# This will search within the component dir's configured default_namespace first,
|
35
|
+
# then fall back to searching for a non-namespaced file
|
36
|
+
#
|
37
|
+
# @param identifier [String] the identifier string
|
38
|
+
# @return [Dry::System::Component, nil] the component, if found
|
39
|
+
#
|
40
|
+
# @api private
|
41
|
+
def component_for_identifier(identifier)
|
42
|
+
identifier = Identifier.new(
|
43
|
+
identifier,
|
44
|
+
namespace: default_namespace,
|
45
|
+
separator: container.config.namespace_separator
|
46
|
+
)
|
47
|
+
|
48
|
+
if (file_path = find_component_file(identifier.path))
|
49
|
+
return build_component(identifier, file_path)
|
50
|
+
end
|
51
|
+
|
52
|
+
identifier = identifier.with(namespace: nil)
|
53
|
+
if (file_path = find_component_file(identifier.path))
|
54
|
+
build_component(identifier, file_path)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Returns a component for a full path to a Ruby source file within the component dir
|
59
|
+
#
|
60
|
+
# @param path [String] the full path to the file
|
61
|
+
# @return [Dry::System::Component] the component
|
62
|
+
#
|
63
|
+
# @api private
|
64
|
+
def component_for_path(path)
|
65
|
+
separator = container.config.namespace_separator
|
66
|
+
|
67
|
+
key = Pathname(path).relative_path_from(full_path).to_s
|
68
|
+
.sub(RB_EXT, EMPTY_STRING)
|
69
|
+
.scan(WORD_REGEX)
|
70
|
+
.join(separator)
|
71
|
+
|
72
|
+
identifier = Identifier.new(key, separator: separator)
|
73
|
+
|
74
|
+
if identifier.start_with?(default_namespace)
|
75
|
+
identifier = identifier.dequalified(default_namespace, namespace: default_namespace)
|
76
|
+
end
|
77
|
+
|
78
|
+
build_component(identifier, path)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Returns the full path of the component directory
|
82
|
+
#
|
83
|
+
# @return [Pathname]
|
84
|
+
# @api private
|
85
|
+
def full_path
|
86
|
+
container.root.join(path)
|
87
|
+
end
|
88
|
+
|
89
|
+
# @api private
|
90
|
+
def component_options
|
91
|
+
{
|
92
|
+
auto_register: auto_register,
|
93
|
+
loader: loader,
|
94
|
+
memoize: memoize
|
95
|
+
}
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
def build_component(identifier, file_path)
|
101
|
+
options = {
|
102
|
+
inflector: container.config.inflector,
|
103
|
+
**component_options,
|
104
|
+
**MagicCommentsParser.(file_path)
|
105
|
+
}
|
106
|
+
|
107
|
+
Component.new(identifier, file_path: file_path, **options)
|
108
|
+
end
|
109
|
+
|
110
|
+
def find_component_file(component_path)
|
111
|
+
component_file = full_path.join("#{component_path}#{RB_EXT}")
|
112
|
+
component_file if component_file.exist?
|
113
|
+
end
|
114
|
+
|
115
|
+
def method_missing(name, *args, &block)
|
116
|
+
if config.respond_to?(name)
|
117
|
+
config.public_send(name, *args, &block)
|
118
|
+
else
|
119
|
+
super
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def respond_to_missing?(name, include_all = false)
|
124
|
+
config.respond_to?(name) || super
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
3
|
+
require "dry/system/lifecycle"
|
4
|
+
require "dry/system/settings"
|
5
|
+
require "dry/system/components/config"
|
6
|
+
require "dry/system/constants"
|
7
7
|
|
8
8
|
module Dry
|
9
9
|
module System
|
@@ -70,7 +70,7 @@ module Dry
|
|
70
70
|
@config = nil
|
71
71
|
@config_block = nil
|
72
72
|
@identifier = identifier
|
73
|
-
@triggers = {
|
73
|
+
@triggers = {before: TRIGGER_MAP.dup, after: TRIGGER_MAP.dup}
|
74
74
|
@options = block ? options.merge(block: block) : options
|
75
75
|
@namespace = options[:namespace]
|
76
76
|
finalize = options[:finalize] || DEFAULT_FINALIZE
|
@@ -229,38 +229,10 @@ module Dry
|
|
229
229
|
# @return [TrueClass]
|
230
230
|
#
|
231
231
|
# @api private
|
232
|
-
def
|
232
|
+
def bootable?
|
233
233
|
true
|
234
234
|
end
|
235
235
|
|
236
|
-
# Return path to component's boot file
|
237
|
-
#
|
238
|
-
# @return [String]
|
239
|
-
#
|
240
|
-
# @api private
|
241
|
-
def boot_file
|
242
|
-
container_boot_files
|
243
|
-
.detect { |path| Pathname(path).basename(RB_EXT).to_s == identifier.to_s }
|
244
|
-
end
|
245
|
-
|
246
|
-
# Return path to boot dir
|
247
|
-
#
|
248
|
-
# @return [String]
|
249
|
-
#
|
250
|
-
# @api private
|
251
|
-
def boot_path
|
252
|
-
container.boot_path
|
253
|
-
end
|
254
|
-
|
255
|
-
# Return all boot files defined under container's boot path
|
256
|
-
#
|
257
|
-
# @return [String]
|
258
|
-
#
|
259
|
-
# @api private
|
260
|
-
def container_boot_files
|
261
|
-
::Dir[container.boot_path.join("**/#{RB_GLOB}")].sort
|
262
|
-
end
|
263
|
-
|
264
236
|
private
|
265
237
|
|
266
238
|
# Return lifecycle object used for this component
|
@@ -21,8 +21,8 @@ module Dry
|
|
21
21
|
private
|
22
22
|
|
23
23
|
def method_missing(meth, value = nil)
|
24
|
-
if meth.to_s.end_with?(
|
25
|
-
@settings[meth.to_s.gsub(
|
24
|
+
if meth.to_s.end_with?("=")
|
25
|
+
@settings[meth.to_s.gsub("=", "").to_sym] = value
|
26
26
|
elsif @settings.key?(meth)
|
27
27
|
@settings[meth]
|
28
28
|
else
|
@@ -0,0 +1,202 @@
|
|
1
|
+
require "dry/configurable"
|
2
|
+
require "dry/system/loader"
|
3
|
+
|
4
|
+
module Dry
|
5
|
+
module System
|
6
|
+
module Config
|
7
|
+
class ComponentDir
|
8
|
+
include Dry::Configurable
|
9
|
+
|
10
|
+
# @!group Settings
|
11
|
+
|
12
|
+
# @!method auto_register=(policy)
|
13
|
+
#
|
14
|
+
# Sets the auto-registration policy for the component dir.
|
15
|
+
#
|
16
|
+
# This may be a simple boolean to enable or disable auto-registration for all
|
17
|
+
# components, or a proc accepting a `Dry::Sytem::Component` and returning a
|
18
|
+
# boolean to configure auto-registration on a per-component basis
|
19
|
+
#
|
20
|
+
# Defaults to `true`.
|
21
|
+
#
|
22
|
+
# @param policy [Boolean, Proc]
|
23
|
+
# @return [Boolean, Proc]
|
24
|
+
#
|
25
|
+
# @example
|
26
|
+
# dir.auto_register = false
|
27
|
+
#
|
28
|
+
# @example
|
29
|
+
# dir.auto_register = proc do |component|
|
30
|
+
# !component.start_with?("entities")
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# @see auto_register
|
34
|
+
# @see Component
|
35
|
+
#
|
36
|
+
# @!method auto_register
|
37
|
+
#
|
38
|
+
# Returns the configured auto-registration policy.
|
39
|
+
#
|
40
|
+
# @return [Boolean, Proc] the configured policy
|
41
|
+
#
|
42
|
+
# @see auto_register=
|
43
|
+
setting :auto_register, true
|
44
|
+
|
45
|
+
# @!method add_to_load_path=(policy)
|
46
|
+
#
|
47
|
+
# Sets whether the dir should be added to the `$LOAD_PATH` after the container
|
48
|
+
# is configured.
|
49
|
+
#
|
50
|
+
# Defaults to `true`. This may need to be set to `false` when using a class
|
51
|
+
# autoloading system.
|
52
|
+
#
|
53
|
+
# @param policy [Boolean]
|
54
|
+
# @return [Boolean]
|
55
|
+
#
|
56
|
+
# @see add_to_load_path
|
57
|
+
# @see Container.configure
|
58
|
+
#
|
59
|
+
# @!method add_to_load_path
|
60
|
+
#
|
61
|
+
# Returns the configured value.
|
62
|
+
#
|
63
|
+
# @return [Boolean]
|
64
|
+
#
|
65
|
+
# @see add_to_load_path=
|
66
|
+
setting :add_to_load_path, true
|
67
|
+
|
68
|
+
# @!method default_namespace=(leading_namespace)
|
69
|
+
#
|
70
|
+
# Sets the leading namespace segments to be stripped when registering components
|
71
|
+
# from the dir in the container.
|
72
|
+
#
|
73
|
+
# This is useful to configure when the dir contains components in a module
|
74
|
+
# namespace that you don't want repeated in their identifiers.
|
75
|
+
#
|
76
|
+
# Defaults to `nil`.
|
77
|
+
#
|
78
|
+
# @param leading_namespace [String, nil]
|
79
|
+
# @return [String, nil]
|
80
|
+
#
|
81
|
+
# @example
|
82
|
+
# dir.default_namespace = "my_app"
|
83
|
+
#
|
84
|
+
# @example
|
85
|
+
# dir.default_namespace = "my_app.admin"
|
86
|
+
#
|
87
|
+
# @see default_namespace
|
88
|
+
#
|
89
|
+
# @!method default_namespace
|
90
|
+
#
|
91
|
+
# Returns the configured value.
|
92
|
+
#
|
93
|
+
# @return [String, nil]
|
94
|
+
#
|
95
|
+
# @see default_namespace=
|
96
|
+
setting :default_namespace
|
97
|
+
|
98
|
+
# @!method loader=(loader)
|
99
|
+
#
|
100
|
+
# Sets the loader to use when registering coponents from the dir in the container.
|
101
|
+
#
|
102
|
+
# Defaults to `Dry::System::Loader`.
|
103
|
+
#
|
104
|
+
# When using a class autoloader, consider using `Dry::System::Loader::Autoloading`
|
105
|
+
#
|
106
|
+
# @param loader [#call] the loader
|
107
|
+
# @return [#call] the configured loader
|
108
|
+
#
|
109
|
+
# @see loader
|
110
|
+
# @see Loader
|
111
|
+
# @see Loader::Autoloading
|
112
|
+
#
|
113
|
+
# @!method loader
|
114
|
+
#
|
115
|
+
# Returns the configured loader.
|
116
|
+
#
|
117
|
+
# @return [#call]
|
118
|
+
#
|
119
|
+
# @see loader=
|
120
|
+
setting :loader, Dry::System::Loader
|
121
|
+
|
122
|
+
# @!method memoize=(policy)
|
123
|
+
#
|
124
|
+
# Sets whether to memoize components from the dir when registered in the
|
125
|
+
# container.
|
126
|
+
#
|
127
|
+
# This may be a simple boolean to enable or disable memoization for all
|
128
|
+
# components, or a proc accepting a `Dry::Sytem::Component` and returning a
|
129
|
+
# boolean to configure memoization on a per-component basis
|
130
|
+
#
|
131
|
+
# Defaults to `false`.
|
132
|
+
#
|
133
|
+
# @param policy [Boolean, Proc]
|
134
|
+
# @return [Boolean, Proc] the configured memoization policy
|
135
|
+
#
|
136
|
+
# @example
|
137
|
+
# dir.memoize = true
|
138
|
+
#
|
139
|
+
# @example
|
140
|
+
# dir.memoize = proc do |component|
|
141
|
+
# !component.start_with?("providers")
|
142
|
+
# end
|
143
|
+
#
|
144
|
+
# @see memoize
|
145
|
+
# @see Component
|
146
|
+
#
|
147
|
+
# @!method memoize
|
148
|
+
#
|
149
|
+
# Returns the configured memoization policy.
|
150
|
+
#
|
151
|
+
# @return [Boolean, Proc] the configured memoization policy
|
152
|
+
#
|
153
|
+
# @see memoize=
|
154
|
+
setting :memoize, false
|
155
|
+
|
156
|
+
# @!endgroup
|
157
|
+
|
158
|
+
# Returns the component dir path, relative to the configured container root
|
159
|
+
#
|
160
|
+
# @return [String] the path
|
161
|
+
attr_reader :path
|
162
|
+
|
163
|
+
# @api private
|
164
|
+
def initialize(path)
|
165
|
+
super()
|
166
|
+
@path = path
|
167
|
+
yield self if block_given?
|
168
|
+
end
|
169
|
+
|
170
|
+
# @api private
|
171
|
+
def auto_register?
|
172
|
+
!!config.auto_register
|
173
|
+
end
|
174
|
+
|
175
|
+
# Returns true if a setting has been explicitly configured and is not returning
|
176
|
+
# just a default value.
|
177
|
+
#
|
178
|
+
# This is used to determine which settings from `ComponentDirs` should be applied
|
179
|
+
# as additional defaults.
|
180
|
+
#
|
181
|
+
# @api private
|
182
|
+
def configured?(key)
|
183
|
+
config._settings[key].input_defined?
|
184
|
+
end
|
185
|
+
|
186
|
+
private
|
187
|
+
|
188
|
+
def method_missing(name, *args, &block)
|
189
|
+
if config.respond_to?(name)
|
190
|
+
config.public_send(name, *args, &block)
|
191
|
+
else
|
192
|
+
super
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def respond_to_missing?(name, include_all = false)
|
197
|
+
config.respond_to?(name) || super
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|