dry-system 0.14.0 → 0.18.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 +80 -2
- data/dry-system.gemspec +4 -2
- data/lib/dry-system.rb +1 -1
- data/lib/dry/system.rb +2 -2
- data/lib/dry/system/auto_registrar.rb +5 -5
- data/lib/dry/system/booter.rb +49 -41
- data/lib/dry/system/component.rb +7 -7
- 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/constants.rb +5 -36
- data/lib/dry/system/container.rb +67 -48
- data/lib/dry/system/errors.rb +32 -5
- data/lib/dry/system/lifecycle.rb +2 -2
- data/lib/dry/system/loader.rb +1 -1
- 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 +9 -8
- data/lib/dry/system/plugins/bootsnap.rb +4 -4
- data/lib/dry/system/plugins/dependency_graph.rb +6 -4
- data/lib/dry/system/plugins/dependency_graph/strategies.rb +1 -1
- data/lib/dry/system/plugins/logging.rb +10 -8
- 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 +4 -4
- 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 +10 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7634be14c7b544e14f693cd158cd4cdf072e89ea5c947fafec45a0b31e58eb18
|
4
|
+
data.tar.gz: 34a55fe75bbae237be83dbcf534c0c13947a66788b146ee2ec12a387d3976e38
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1802eb1c676eb114126b37fd1ac9607a446317e209de17c62018f6a61bd9dd6770093e673671685c6a8d665ec53c7d7897141c3a7896c4d64ee3f5161c47bc30
|
7
|
+
data.tar.gz: '08fd659802b48151cf10598eb45fcb6555b8f9fa8b55340e6e9f393469608b965ecdefae143e79a880c394bcbede49b719f71f9bf6b96726af73921020121a35'
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,82 @@
|
|
1
|
-
##
|
1
|
+
## 0.18.1 2020-08-26
|
2
|
+
|
3
|
+
|
4
|
+
### Fixed
|
5
|
+
|
6
|
+
- Made `Booter#boot_files` a public method again, since it was required by dry-rails (@timriley)
|
7
|
+
|
8
|
+
|
9
|
+
[Compare v0.18.0...v0.18.1](https://github.com/dry-rb/dry-system/compare/v0.18.0...v0.18.1)
|
10
|
+
|
11
|
+
## 0.18.0 2020-08-24
|
12
|
+
|
13
|
+
|
14
|
+
### Added
|
15
|
+
|
16
|
+
- New `bootable_dirs` setting on `Dry::System::Container`, which accepts paths to multiple directories for looking up bootable component files. (@timriley in PR #151)
|
17
|
+
|
18
|
+
For each entry in the `bootable_dirs` array, relative directories will be appended to the container's `root`, and absolute directories will be left unchanged.
|
19
|
+
|
20
|
+
When searching for bootable files, the first match will win, and any subsequent same-named files will not be loaded. In this way, the `bootable_dirs` act similarly to the `$PATH` in a shell environment.
|
21
|
+
|
22
|
+
|
23
|
+
[Compare v0.17.0...v0.18.0](https://github.com/dry-rb/dry-system/compare/v0.17.0...v0.18.0)
|
24
|
+
|
25
|
+
## 0.17.0 2020-02-19
|
26
|
+
|
27
|
+
|
28
|
+
### Fixed
|
29
|
+
|
30
|
+
- Works with the latest dry-configurable version (issue #141) (@solnic)
|
31
|
+
|
32
|
+
### Changed
|
33
|
+
|
34
|
+
- Depends on dry-configurable `=> 0.11.1` now (@solnic)
|
35
|
+
|
36
|
+
[Compare v0.16.0...v0.17.0](https://github.com/dry-rb/dry-system/compare/v0.16.0...v0.17.0)
|
37
|
+
|
38
|
+
## 0.16.0 2020-02-15
|
39
|
+
|
40
|
+
|
41
|
+
### Changed
|
42
|
+
|
43
|
+
- Plugins can now define their own settings which are available in the `before(:configure)` hook (@solnic)
|
44
|
+
- Dependency on dry-configurable was bumped to `~> 0.11` (@solnic)
|
45
|
+
|
46
|
+
[Compare v0.15.0...v0.16.0](https://github.com/dry-rb/dry-system/compare/v0.15.0...v0.16.0)
|
47
|
+
|
48
|
+
## 0.15.0 2020-01-30
|
49
|
+
|
50
|
+
|
51
|
+
### Added
|
52
|
+
|
53
|
+
- New hook - `before(:configure)` which a plugin should use if it needs to declare new settings (@solnic)
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
# in your plugin code
|
57
|
+
before(:configure) { setting :my_new_setting }
|
58
|
+
|
59
|
+
after(:configure) { config.my_new_setting = "awesome" }
|
60
|
+
```
|
61
|
+
|
62
|
+
|
63
|
+
### Changed
|
64
|
+
|
65
|
+
- Centralize error definitions in `lib/dry/system/errors.rb` (@cgeorgii)
|
66
|
+
- All built-in plugins use `before(:configure)` now to declare their settings (@solnic)
|
67
|
+
|
68
|
+
[Compare v0.14.1...v0.15.0](https://github.com/dry-rb/dry-system/compare/v0.14.1...v0.15.0)
|
69
|
+
|
70
|
+
## 0.14.1 2020-01-22
|
71
|
+
|
72
|
+
|
73
|
+
### Changed
|
74
|
+
|
75
|
+
- Use `Kernel.require` explicitly to avoid issues with monkey-patched `require` from ActiveSupport (@solnic)
|
76
|
+
|
77
|
+
[Compare v0.14.0...v0.14.1](https://github.com/dry-rb/dry-system/compare/v0.14.0...v0.14.1)
|
78
|
+
|
79
|
+
## 0.14.0 2020-01-21
|
2
80
|
|
3
81
|
|
4
82
|
### Fixed
|
@@ -7,7 +85,7 @@
|
|
7
85
|
- Fail fast if auto_registrar config contains incorrect path (@cutalion)
|
8
86
|
|
9
87
|
|
10
|
-
[Compare v0.13.2...
|
88
|
+
[Compare v0.13.2...v0.14.0](https://github.com/dry-rb/dry-system/compare/v0.13.2...v0.14.0)
|
11
89
|
|
12
90
|
## 0.13.2 2019-12-28
|
13
91
|
|
data/dry-system.gemspec
CHANGED
@@ -16,6 +16,8 @@ Gem::Specification.new do |spec|
|
|
16
16
|
spec.description = spec.summary
|
17
17
|
spec.homepage = 'https://dry-rb.org/gems/dry-system'
|
18
18
|
spec.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "dry-system.gemspec", "lib/**/*"]
|
19
|
+
spec.bindir = 'bin'
|
20
|
+
spec.executables = []
|
19
21
|
spec.require_paths = ['lib']
|
20
22
|
|
21
23
|
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
@@ -23,12 +25,12 @@ Gem::Specification.new do |spec|
|
|
23
25
|
spec.metadata['source_code_uri'] = 'https://github.com/dry-rb/dry-system'
|
24
26
|
spec.metadata['bug_tracker_uri'] = 'https://github.com/dry-rb/dry-system/issues'
|
25
27
|
|
26
|
-
spec.required_ruby_version =
|
28
|
+
spec.required_ruby_version = ">= 2.4.0"
|
27
29
|
|
28
30
|
# to update dependencies edit project.yml
|
29
31
|
spec.add_runtime_dependency "concurrent-ruby", "~> 1.0"
|
30
32
|
spec.add_runtime_dependency "dry-auto_inject", ">= 0.4.0"
|
31
|
-
spec.add_runtime_dependency "dry-configurable", "~> 0.
|
33
|
+
spec.add_runtime_dependency "dry-configurable", "~> 0.11", ">= 0.11.1"
|
32
34
|
spec.add_runtime_dependency "dry-container", "~> 0.7", ">= 0.7.2"
|
33
35
|
spec.add_runtime_dependency "dry-core", "~> 0.3", ">= 0.3.1"
|
34
36
|
spec.add_runtime_dependency "dry-equalizer", "~> 0.2"
|
data/lib/dry-system.rb
CHANGED
data/lib/dry/system.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require "dry/system/constants"
|
4
|
+
require "dry/system/magic_comments_parser"
|
5
|
+
require "dry/system/auto_registrar/configuration"
|
6
6
|
|
7
7
|
module Dry
|
8
8
|
module System
|
@@ -67,8 +67,8 @@ module Dry
|
|
67
67
|
|
68
68
|
# @api private
|
69
69
|
def relative_path(dir, file_path)
|
70
|
-
dir_root = root.join(dir.to_s.split(
|
71
|
-
file_path.to_s.sub("#{dir_root}/",
|
70
|
+
dir_root = root.join(dir.to_s.split("/")[0])
|
71
|
+
file_path.to_s.sub("#{dir_root}/", "").sub(RB_EXT, EMPTY_STRING)
|
72
72
|
end
|
73
73
|
|
74
74
|
# @api private
|
data/lib/dry/system/booter.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
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"
|
8
9
|
|
9
10
|
module Dry
|
10
11
|
module System
|
@@ -16,29 +17,22 @@ module Dry
|
|
16
17
|
#
|
17
18
|
# @api private
|
18
19
|
class Booter
|
19
|
-
attr_reader :
|
20
|
+
attr_reader :paths
|
20
21
|
|
21
22
|
attr_reader :booted
|
22
23
|
|
23
24
|
attr_reader :components
|
24
25
|
|
25
26
|
# @api private
|
26
|
-
def initialize(
|
27
|
-
@
|
27
|
+
def initialize(paths)
|
28
|
+
@paths = paths
|
28
29
|
@booted = []
|
29
30
|
@components = ComponentRegistry.new
|
30
31
|
end
|
31
32
|
|
32
33
|
# @api private
|
33
34
|
def bootable?(component)
|
34
|
-
boot_file(component).
|
35
|
-
end
|
36
|
-
|
37
|
-
# @api private
|
38
|
-
def boot_file(name)
|
39
|
-
name = name.respond_to?(:root_key) ? name.root_key.to_s : name
|
40
|
-
|
41
|
-
path.join("#{name}#{RB_EXT}")
|
35
|
+
!boot_file(component).nil?
|
42
36
|
end
|
43
37
|
|
44
38
|
# @api private
|
@@ -47,15 +41,6 @@ module Dry
|
|
47
41
|
self
|
48
42
|
end
|
49
43
|
|
50
|
-
# @api private
|
51
|
-
def load_component(path)
|
52
|
-
identifier = Pathname(path).basename(RB_EXT).to_s.to_sym
|
53
|
-
|
54
|
-
require path unless components.exists?(identifier)
|
55
|
-
|
56
|
-
self
|
57
|
-
end
|
58
|
-
|
59
44
|
# @api private
|
60
45
|
def finalize!
|
61
46
|
boot_files.each do |path|
|
@@ -120,7 +105,7 @@ module Dry
|
|
120
105
|
# @api private
|
121
106
|
def call(name_or_component)
|
122
107
|
with_component(name_or_component) do |component|
|
123
|
-
raise ComponentFileMismatchError
|
108
|
+
raise ComponentFileMismatchError, name unless component
|
124
109
|
|
125
110
|
yield(component) if block_given?
|
126
111
|
|
@@ -129,11 +114,30 @@ module Dry
|
|
129
114
|
end
|
130
115
|
|
131
116
|
# @api private
|
132
|
-
def
|
133
|
-
|
117
|
+
def boot_dependency(component)
|
118
|
+
boot_file = boot_file(component)
|
119
|
+
|
120
|
+
start(boot_file.basename(".*").to_s.to_sym) if boot_file
|
134
121
|
end
|
135
122
|
|
136
123
|
# @api private
|
124
|
+
def boot_files
|
125
|
+
@boot_files ||= paths.each_with_object([[], []]) { |path, (boot_files, loaded)|
|
126
|
+
files = Dir["#{path}/#{RB_GLOB}"].sort
|
127
|
+
|
128
|
+
files.each do |file|
|
129
|
+
basename = File.basename(file)
|
130
|
+
|
131
|
+
unless loaded.include?(basename)
|
132
|
+
boot_files << Pathname(file)
|
133
|
+
loaded << basename
|
134
|
+
end
|
135
|
+
end
|
136
|
+
}.first
|
137
|
+
end
|
138
|
+
|
139
|
+
private
|
140
|
+
|
137
141
|
def with_component(id_or_component)
|
138
142
|
component =
|
139
143
|
case id_or_component
|
@@ -149,24 +153,28 @@ module Dry
|
|
149
153
|
yield(component)
|
150
154
|
end
|
151
155
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
}
|
156
|
+
def load_component(path)
|
157
|
+
identifier = Pathname(path).basename(RB_EXT).to_s.to_sym
|
158
|
+
|
159
|
+
Kernel.require path unless components.exists?(identifier)
|
157
160
|
|
158
|
-
|
161
|
+
self
|
159
162
|
end
|
160
163
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
+
def boot_file(name)
|
165
|
+
name = name.respond_to?(:root_key) ? name.root_key.to_s : name
|
166
|
+
|
167
|
+
find_boot_file(name)
|
164
168
|
end
|
165
169
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
+
def require_boot_file(identifier)
|
171
|
+
boot_file = find_boot_file(identifier)
|
172
|
+
|
173
|
+
Kernel.require boot_file if boot_file
|
174
|
+
end
|
175
|
+
|
176
|
+
def find_boot_file(name)
|
177
|
+
boot_files.detect { |file| File.basename(file, RB_EXT) == name.to_s }
|
170
178
|
end
|
171
179
|
end
|
172
180
|
end
|
data/lib/dry/system/component.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
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-equalizer"
|
6
|
+
require "dry/inflector"
|
7
|
+
require "dry/system/loader"
|
8
|
+
require "dry/system/errors"
|
9
|
+
require "dry/system/constants"
|
10
10
|
|
11
11
|
module Dry
|
12
12
|
module System
|
@@ -118,7 +118,7 @@ module Dry
|
|
118
118
|
ruby2_keywords(:instance) if respond_to?(:ruby2_keywords, true)
|
119
119
|
|
120
120
|
# @api private
|
121
|
-
def
|
121
|
+
def bootable?
|
122
122
|
false
|
123
123
|
end
|
124
124
|
|
@@ -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
|
data/lib/dry/system/constants.rb
CHANGED
@@ -1,46 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "dry/core/constants"
|
4
4
|
|
5
5
|
module Dry
|
6
6
|
module System
|
7
7
|
include Dry::Core::Constants
|
8
8
|
|
9
|
-
RB_EXT =
|
10
|
-
RB_GLOB =
|
11
|
-
PATH_SEPARATOR =
|
12
|
-
DEFAULT_SEPARATOR =
|
9
|
+
RB_EXT = ".rb"
|
10
|
+
RB_GLOB = "*.rb"
|
11
|
+
PATH_SEPARATOR = "/"
|
12
|
+
DEFAULT_SEPARATOR = "."
|
13
13
|
WORD_REGEX = /\w+/.freeze
|
14
|
-
|
15
|
-
ComponentsDirMissing = Class.new(StandardError)
|
16
|
-
DuplicatedComponentKeyError = Class.new(ArgumentError)
|
17
|
-
InvalidSettingsError = Class.new(ArgumentError) do
|
18
|
-
# @api private
|
19
|
-
def initialize(attributes)
|
20
|
-
message = <<~STR
|
21
|
-
Could not initialize settings. The following settings were invalid:
|
22
|
-
|
23
|
-
#{attributes_errors(attributes).join("\n")}
|
24
|
-
STR
|
25
|
-
super(message)
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
def attributes_errors(attributes)
|
31
|
-
attributes.map { |key, error| "#{key.name}: #{error}" }
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
# Exception raise when a plugin dependency failed to load
|
36
|
-
#
|
37
|
-
# @api public
|
38
|
-
PluginDependencyMissing = Class.new(StandardError) do
|
39
|
-
# @api private
|
40
|
-
def initialize(plugin, message, gem = nil)
|
41
|
-
details = gem ? "#{message} - add #{gem} to your Gemfile" : message
|
42
|
-
super("dry-system plugin #{plugin.inspect} failed to load its dependencies: #{details}")
|
43
|
-
end
|
44
|
-
end
|
45
14
|
end
|
46
15
|
end
|
data/lib/dry/system/container.rb
CHANGED
@@ -1,24 +1,24 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
|
10
|
-
require
|
11
|
-
|
12
|
-
require
|
13
|
-
require
|
14
|
-
require
|
15
|
-
require
|
16
|
-
require
|
17
|
-
require
|
18
|
-
require
|
19
|
-
require
|
20
|
-
require
|
21
|
-
require
|
3
|
+
require "pathname"
|
4
|
+
|
5
|
+
require "dry-auto_inject"
|
6
|
+
require "dry-configurable"
|
7
|
+
require "dry-container"
|
8
|
+
require "dry/inflector"
|
9
|
+
|
10
|
+
require "dry/core/deprecations"
|
11
|
+
|
12
|
+
require "dry/system"
|
13
|
+
require "dry/system/errors"
|
14
|
+
require "dry/system/loader"
|
15
|
+
require "dry/system/booter"
|
16
|
+
require "dry/system/auto_registrar"
|
17
|
+
require "dry/system/manual_registrar"
|
18
|
+
require "dry/system/importer"
|
19
|
+
require "dry/system/component"
|
20
|
+
require "dry/system/constants"
|
21
|
+
require "dry/system/plugins"
|
22
22
|
|
23
23
|
module Dry
|
24
24
|
module System
|
@@ -48,8 +48,6 @@ module Dry
|
|
48
48
|
#
|
49
49
|
# * `:name` - a unique container identifier
|
50
50
|
# * `:root` - a system root directory (defaults to `pwd`)
|
51
|
-
# * `:system_dir` - directory name relative to root, where bootable components
|
52
|
-
# can be defined in `boot` dir this defaults to `system`
|
53
51
|
#
|
54
52
|
# @example
|
55
53
|
# class MyApp < Dry::System::Container
|
@@ -75,8 +73,9 @@ module Dry
|
|
75
73
|
setting :name
|
76
74
|
setting :default_namespace
|
77
75
|
setting(:root, Pathname.pwd.freeze) { |path| Pathname(path) }
|
78
|
-
setting :system_dir,
|
79
|
-
setting :
|
76
|
+
setting :system_dir, "system"
|
77
|
+
setting :bootable_dirs, ["system/boot"]
|
78
|
+
setting :registrations_dir, "container"
|
80
79
|
setting :auto_register, []
|
81
80
|
setting :inflector, Dry::Inflector.new
|
82
81
|
setting :loader, Dry::System::Loader
|
@@ -95,7 +94,19 @@ module Dry
|
|
95
94
|
end
|
96
95
|
end
|
97
96
|
|
98
|
-
extend Dry::Core::Deprecations[
|
97
|
+
extend Dry::Core::Deprecations["Dry::System::Container"]
|
98
|
+
|
99
|
+
# Define a new configuration setting
|
100
|
+
#
|
101
|
+
# @see https://dry-rb.org/gems/dry-configurable
|
102
|
+
#
|
103
|
+
# @api public
|
104
|
+
def setting(name, *args, &block)
|
105
|
+
super(name, *args, &block)
|
106
|
+
# TODO: dry-configurable needs a public API for this
|
107
|
+
config._settings << _settings[name]
|
108
|
+
self
|
109
|
+
end
|
99
110
|
|
100
111
|
# Configures the container
|
101
112
|
#
|
@@ -112,9 +123,10 @@ module Dry
|
|
112
123
|
#
|
113
124
|
# @api public
|
114
125
|
def configure(&block)
|
126
|
+
hooks[:before_configure].each { |hook| instance_eval(&hook) }
|
115
127
|
super(&block)
|
116
128
|
load_paths!(config.system_dir)
|
117
|
-
hooks[:
|
129
|
+
hooks[:after_configure].each { |hook| instance_eval(&hook) }
|
118
130
|
self
|
119
131
|
end
|
120
132
|
|
@@ -157,9 +169,10 @@ module Dry
|
|
157
169
|
|
158
170
|
# Registers finalization function for a bootable component
|
159
171
|
#
|
160
|
-
# By convention, boot files for components should be placed in
|
161
|
-
#
|
162
|
-
# are loaded in isolation, or during finalization
|
172
|
+
# By convention, boot files for components should be placed in a
|
173
|
+
# `bootable_dirs` entry and they will be loaded on demand when
|
174
|
+
# components are loaded in isolation, or during the finalization
|
175
|
+
# process.
|
163
176
|
#
|
164
177
|
# @example
|
165
178
|
# # system/container.rb
|
@@ -242,30 +255,24 @@ module Dry
|
|
242
255
|
boot_local(name, **opts, &block)
|
243
256
|
end
|
244
257
|
|
258
|
+
booter.register_component component
|
259
|
+
|
245
260
|
components[name] = component
|
246
261
|
end
|
247
262
|
deprecate :finalize, :boot
|
248
263
|
|
249
264
|
# @api private
|
250
265
|
def boot_external(identifier, from:, key: nil, namespace: nil, &block)
|
251
|
-
|
266
|
+
System.providers[from].component(
|
252
267
|
identifier, key: key, namespace: namespace, finalize: block, container: self
|
253
268
|
)
|
254
|
-
|
255
|
-
booter.register_component(component)
|
256
|
-
|
257
|
-
component
|
258
269
|
end
|
259
270
|
|
260
271
|
# @api private
|
261
272
|
def boot_local(identifier, namespace: nil, &block)
|
262
|
-
|
273
|
+
Components::Bootable.new(
|
263
274
|
identifier, container: self, namespace: namespace, &block
|
264
275
|
)
|
265
|
-
|
266
|
-
booter.register_component(component)
|
267
|
-
|
268
|
-
component
|
269
276
|
end
|
270
277
|
|
271
278
|
# Return if a container was finalized
|
@@ -475,7 +482,7 @@ module Dry
|
|
475
482
|
# @param options [Hash] injector options
|
476
483
|
#
|
477
484
|
# @api public
|
478
|
-
def injector(options = {
|
485
|
+
def injector(options = {strategies: strategies})
|
479
486
|
Dry::AutoInject(self, options)
|
480
487
|
end
|
481
488
|
|
@@ -493,9 +500,9 @@ module Dry
|
|
493
500
|
# @api public
|
494
501
|
def require_from_root(*paths)
|
495
502
|
paths.flat_map { |path|
|
496
|
-
path.to_s.include?(
|
503
|
+
path.to_s.include?("*") ? ::Dir[root.join(path)].sort : root.join(path)
|
497
504
|
}.each { |path|
|
498
|
-
require path.to_s
|
505
|
+
Kernel.require path.to_s
|
499
506
|
}
|
500
507
|
end
|
501
508
|
|
@@ -556,12 +563,20 @@ module Dry
|
|
556
563
|
|
557
564
|
# @api private
|
558
565
|
def booter
|
559
|
-
@booter ||= config.booter.new(
|
566
|
+
@booter ||= config.booter.new(boot_paths)
|
560
567
|
end
|
561
568
|
|
562
569
|
# @api private
|
563
|
-
def
|
564
|
-
|
570
|
+
def boot_paths
|
571
|
+
config.bootable_dirs.map { |dir|
|
572
|
+
dir = Pathname(dir)
|
573
|
+
|
574
|
+
if dir.relative?
|
575
|
+
root.join(dir)
|
576
|
+
else
|
577
|
+
dir
|
578
|
+
end
|
579
|
+
}
|
565
580
|
end
|
566
581
|
|
567
582
|
# @api private
|
@@ -622,13 +637,13 @@ module Dry
|
|
622
637
|
return self if registered?(key)
|
623
638
|
|
624
639
|
component(key).tap do |component|
|
625
|
-
if component.
|
640
|
+
if component.bootable?
|
626
641
|
booter.start(component)
|
627
642
|
else
|
628
643
|
root_key = component.root_key
|
629
644
|
|
630
|
-
if (
|
631
|
-
booter.start(
|
645
|
+
if (root_bootable = component(root_key)).bootable?
|
646
|
+
booter.start(root_bootable)
|
632
647
|
elsif importer.key?(root_key)
|
633
648
|
load_imported_component(component.namespaced(root_key))
|
634
649
|
end
|
@@ -642,7 +657,11 @@ module Dry
|
|
642
657
|
|
643
658
|
# @api private
|
644
659
|
def after(event, &block)
|
645
|
-
hooks[event] << block
|
660
|
+
hooks[:"after_#{event}"] << block
|
661
|
+
end
|
662
|
+
|
663
|
+
def before(event, &block)
|
664
|
+
hooks[:"before_#{event}"] << block
|
646
665
|
end
|
647
666
|
|
648
667
|
# @api private
|
data/lib/dry/system/errors.rb
CHANGED
@@ -17,12 +17,8 @@ module Dry
|
|
17
17
|
# @api public
|
18
18
|
ComponentFileMismatchError = Class.new(StandardError) do
|
19
19
|
def initialize(component)
|
20
|
-
path = component.boot_path
|
21
|
-
files = component.container_boot_files
|
22
|
-
|
23
20
|
super(<<-STR)
|
24
|
-
|
25
|
-
Container boot files under #{path}: #{files.inspect}")
|
21
|
+
Bootable component #{component.identifier.inspect} not found
|
26
22
|
STR
|
27
23
|
end
|
28
24
|
end
|
@@ -84,5 +80,36 @@ module Dry
|
|
84
80
|
super("Plugin #{plugin_name.inspect} does not exist")
|
85
81
|
end
|
86
82
|
end
|
83
|
+
|
84
|
+
ComponentsDirMissing = Class.new(StandardError)
|
85
|
+
DuplicatedComponentKeyError = Class.new(ArgumentError)
|
86
|
+
InvalidSettingsError = Class.new(ArgumentError) do
|
87
|
+
# @api private
|
88
|
+
def initialize(attributes)
|
89
|
+
message = <<~STR
|
90
|
+
Could not initialize settings. The following settings were invalid:
|
91
|
+
|
92
|
+
#{attributes_errors(attributes).join("\n")}
|
93
|
+
STR
|
94
|
+
super(message)
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
|
99
|
+
def attributes_errors(attributes)
|
100
|
+
attributes.map { |key, error| "#{key.name}: #{error}" }
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Exception raise when a plugin dependency failed to load
|
105
|
+
#
|
106
|
+
# @api public
|
107
|
+
PluginDependencyMissing = Class.new(StandardError) do
|
108
|
+
# @api private
|
109
|
+
def initialize(plugin, message, gem = nil)
|
110
|
+
details = gem ? "#{message} - add #{gem} to your Gemfile" : message
|
111
|
+
super("dry-system plugin #{plugin.inspect} failed to load its dependencies: #{details}")
|
112
|
+
end
|
113
|
+
end
|
87
114
|
end
|
88
115
|
end
|
data/lib/dry/system/lifecycle.rb
CHANGED
data/lib/dry/system/loader.rb
CHANGED
data/lib/dry/system/plugins.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "dry/system/constants"
|
4
4
|
|
5
5
|
module Dry
|
6
6
|
module System
|
@@ -40,7 +40,7 @@ module Dry
|
|
40
40
|
|
41
41
|
# @api private
|
42
42
|
def load_dependency(dependency, gem)
|
43
|
-
require dependency
|
43
|
+
Kernel.require dependency
|
44
44
|
Plugins.loaded_dependencies << dependency.to_s
|
45
45
|
rescue LoadError => e
|
46
46
|
raise PluginDependencyMissing.new(name, e.message, gem)
|
@@ -94,6 +94,7 @@ module Dry
|
|
94
94
|
# @api public
|
95
95
|
def use(name, options = {})
|
96
96
|
return self if enabled_plugins.include?(name)
|
97
|
+
|
97
98
|
raise PluginNotFoundError, name unless (plugin = Plugins.registry[name])
|
98
99
|
|
99
100
|
plugin.load_dependencies
|
@@ -115,22 +116,22 @@ module Dry
|
|
115
116
|
@enabled_plugins ||= []
|
116
117
|
end
|
117
118
|
|
118
|
-
require
|
119
|
+
require "dry/system/plugins/bootsnap"
|
119
120
|
register(:bootsnap, Plugins::Bootsnap)
|
120
121
|
|
121
|
-
require
|
122
|
+
require "dry/system/plugins/logging"
|
122
123
|
register(:logging, Plugins::Logging)
|
123
124
|
|
124
|
-
require
|
125
|
+
require "dry/system/plugins/env"
|
125
126
|
register(:env, Plugins::Env)
|
126
127
|
|
127
|
-
require
|
128
|
+
require "dry/system/plugins/notifications"
|
128
129
|
register(:notifications, Plugins::Notifications)
|
129
130
|
|
130
|
-
require
|
131
|
+
require "dry/system/plugins/monitoring"
|
131
132
|
register(:monitoring, Plugins::Monitoring)
|
132
133
|
|
133
|
-
require
|
134
|
+
require "dry/system/plugins/dependency_graph"
|
134
135
|
register(:dependency_graph, Plugins::DependencyGraph)
|
135
136
|
end
|
136
137
|
end
|
@@ -16,13 +16,13 @@ module Dry
|
|
16
16
|
def self.extended(system)
|
17
17
|
super
|
18
18
|
system.use(:env)
|
19
|
-
system.setting :bootsnap, DEFAULT_OPTIONS
|
19
|
+
system.before(:configure) { setting :bootsnap, DEFAULT_OPTIONS }
|
20
20
|
system.after(:configure, &:setup_bootsnap)
|
21
21
|
end
|
22
22
|
|
23
23
|
# @api private
|
24
24
|
def self.dependencies
|
25
|
-
{
|
25
|
+
{bootsnap: "bootsnap"}
|
26
26
|
end
|
27
27
|
|
28
28
|
# Set up bootsnap for faster booting
|
@@ -31,12 +31,12 @@ module Dry
|
|
31
31
|
def setup_bootsnap
|
32
32
|
return unless bootsnap_available?
|
33
33
|
|
34
|
-
::Bootsnap.setup(config.bootsnap.merge(cache_dir: root.join(
|
34
|
+
::Bootsnap.setup(config.bootsnap.merge(cache_dir: root.join("tmp/cache").to_s))
|
35
35
|
end
|
36
36
|
|
37
37
|
# @api private
|
38
38
|
def bootsnap_available?
|
39
|
-
RUBY_ENGINE ==
|
39
|
+
RUBY_ENGINE == "ruby" && RUBY_VERSION >= "2.3.0" && RUBY_VERSION < "2.5.0"
|
40
40
|
end
|
41
41
|
end
|
42
42
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "dry/system/constants"
|
4
|
+
require "dry/system/plugins/dependency_graph/strategies"
|
5
5
|
|
6
6
|
module Dry
|
7
7
|
module System
|
@@ -14,7 +14,9 @@ module Dry
|
|
14
14
|
|
15
15
|
system.use(:notifications)
|
16
16
|
|
17
|
-
system.
|
17
|
+
system.before(:configure) do
|
18
|
+
setting :ignored_dependencies, []
|
19
|
+
end
|
18
20
|
|
19
21
|
system.after(:configure) do
|
20
22
|
self[:notifications].register_event(:resolved_dependency)
|
@@ -26,7 +28,7 @@ module Dry
|
|
26
28
|
|
27
29
|
# @api private
|
28
30
|
def self.dependencies
|
29
|
-
{
|
31
|
+
{'dry-events': "dry/events/publisher"}
|
30
32
|
end
|
31
33
|
|
32
34
|
# @api private
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "logger"
|
4
4
|
|
5
5
|
module Dry
|
6
6
|
module System
|
@@ -8,16 +8,18 @@ module Dry
|
|
8
8
|
module Logging
|
9
9
|
# @api private
|
10
10
|
def self.extended(system)
|
11
|
-
system.
|
11
|
+
system.before(:configure) do
|
12
|
+
setting :logger, reader: true
|
12
13
|
|
13
|
-
|
14
|
+
setting :log_dir, "log"
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
setting :log_levels,
|
17
|
+
development: Logger::DEBUG,
|
18
|
+
test: Logger::DEBUG,
|
19
|
+
production: Logger::ERROR
|
19
20
|
|
20
|
-
|
21
|
+
setting :logger_class, ::Logger, reader: true
|
22
|
+
end
|
21
23
|
|
22
24
|
system.after(:configure, &:register_logger)
|
23
25
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "dry/system/constants"
|
4
|
+
require "dry/system/plugins/monitoring/proxy"
|
5
5
|
|
6
6
|
module Dry
|
7
7
|
module System
|
@@ -21,7 +21,7 @@ module Dry
|
|
21
21
|
|
22
22
|
# @api private
|
23
23
|
def self.dependencies
|
24
|
-
{
|
24
|
+
{'dry-events': "dry/events/publisher"}
|
25
25
|
end
|
26
26
|
|
27
27
|
# @api private
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "delegate"
|
4
4
|
|
5
5
|
module Dry
|
6
6
|
module System
|
@@ -9,7 +9,7 @@ module Dry
|
|
9
9
|
# @api private
|
10
10
|
class Proxy < SimpleDelegator
|
11
11
|
# @api private
|
12
|
-
def self.for(target, key:, methods: []
|
12
|
+
def self.for(target, key:, methods: [])
|
13
13
|
monitored_methods =
|
14
14
|
if methods.empty?
|
15
15
|
target.public_methods - Object.public_instance_methods
|
@@ -30,7 +30,7 @@ module Dry
|
|
30
30
|
monitored_methods.each do |meth|
|
31
31
|
define_method(meth) do |*args, &block|
|
32
32
|
object = __getobj__
|
33
|
-
opts = {
|
33
|
+
opts = {target: key, object: object, method: meth, args: args}
|
34
34
|
|
35
35
|
__notifications__.instrument(:monitoring, opts) do
|
36
36
|
object.public_send(meth, *args, &block)
|
data/lib/dry/system/provider.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require "concurrent/map"
|
4
|
+
require "dry/system/constants"
|
5
|
+
require "dry/system/components/bootable"
|
6
6
|
|
7
7
|
module Dry
|
8
8
|
module System
|
@@ -41,7 +41,7 @@ module Dry
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def load_components
|
44
|
-
boot_files.each { |f| require f }
|
44
|
+
boot_files.each { |f| Kernel.require f }
|
45
45
|
freeze
|
46
46
|
self
|
47
47
|
end
|
data/lib/dry/system/settings.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require "dry/core/class_builder"
|
4
|
+
require "dry/types"
|
5
|
+
require "dry/struct"
|
6
6
|
|
7
|
-
require
|
8
|
-
require
|
7
|
+
require "dry/system/settings/file_loader"
|
8
|
+
require "dry/system/constants"
|
9
9
|
|
10
10
|
module Dry
|
11
11
|
module System
|
@@ -22,7 +22,7 @@ module Dry
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def call
|
25
|
-
Core::ClassBuilder.new(name:
|
25
|
+
Core::ClassBuilder.new(name: "Configuration", parent: Configuration).call do |klass|
|
26
26
|
schema.each do |key, type|
|
27
27
|
klass.setting(key, type)
|
28
28
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "dry/system/settings/file_parser"
|
4
4
|
|
5
5
|
module Dry
|
6
6
|
module System
|
@@ -20,7 +20,7 @@ module Dry
|
|
20
20
|
|
21
21
|
def files(root, env)
|
22
22
|
[
|
23
|
-
root.join(
|
23
|
+
root.join(".env"),
|
24
24
|
root.join(".env.#{env}")
|
25
25
|
].compact
|
26
26
|
end
|
data/lib/dry/system/stubs.rb
CHANGED
data/lib/dry/system/version.rb
CHANGED
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.18.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Solnica
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-08-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -44,14 +44,20 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '0.
|
47
|
+
version: '0.11'
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: 0.11.1
|
48
51
|
type: :runtime
|
49
52
|
prerelease: false
|
50
53
|
version_requirements: !ruby/object:Gem::Requirement
|
51
54
|
requirements:
|
52
55
|
- - "~>"
|
53
56
|
- !ruby/object:Gem::Version
|
54
|
-
version: '0.
|
57
|
+
version: '0.11'
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 0.11.1
|
55
61
|
- !ruby/object:Gem::Dependency
|
56
62
|
name: dry-container
|
57
63
|
requirement: !ruby/object:Gem::Requirement
|