Skip to content

Commit 420b2f9

Browse files
Add kind of factory for different initializers
1 parent 2851014 commit 420b2f9

8 files changed

+190
-82
lines changed

.rubocop.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ inherit_gem:
33

44
AllCops:
55
DisplayCopNames: true
6-
TargetRubyVersion: 2.7
6+
TargetRubyVersion: 3.2
77

88
Naming/MethodParameterName:
99
AllowedNames: ["x", "y", "z"]

Gemfile

+2
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ gemspec
66

77
gem "bundler-audit"
88
gem "ci-helper"
9+
gem "dry-initializer"
910
gem "pry"
1011
gem "rake"
1112
gem "rspec"
1213
gem "rubocop-config-umbrellio"
1314
gem "simplecov"
1415
gem "simplecov-lcov"
16+
gem "smart_initializer"

Gemfile.lock

+80-73
Original file line numberDiff line numberDiff line change
@@ -2,117 +2,123 @@ PATH
22
remote: .
33
specs:
44
resol (0.9.0)
5+
dry-initializer (~> 3.1)
56
smart_initializer (~> 0.7)
67

78
GEM
89
remote: https://rubygems.org/
910
specs:
10-
activesupport (7.1.2)
11+
activesupport (8.0.1)
1112
base64
13+
benchmark (>= 0.3)
1214
bigdecimal
13-
concurrent-ruby (~> 1.0, >= 1.0.2)
15+
concurrent-ruby (~> 1.0, >= 1.3.1)
1416
connection_pool (>= 2.2.5)
1517
drb
1618
i18n (>= 1.6, < 2)
19+
logger (>= 1.4.2)
1720
minitest (>= 5.1)
18-
mutex_m
19-
tzinfo (~> 2.0)
21+
securerandom (>= 0.3)
22+
tzinfo (~> 2.0, >= 2.0.5)
23+
uri (>= 0.13.1)
2024
ast (2.4.2)
2125
base64 (0.2.0)
22-
bigdecimal (3.1.4)
23-
bundler-audit (0.9.1)
26+
benchmark (0.4.0)
27+
bigdecimal (3.1.8)
28+
bundler-audit (0.9.2)
2429
bundler (>= 1.2.0, < 3)
2530
thor (~> 1.0)
26-
ci-helper (0.5.0)
27-
colorize (~> 0.8)
28-
dry-inflector (~> 0.2)
29-
umbrellio-sequel-plugins (~> 0.4)
31+
ci-helper (0.7.0)
32+
colorize (~> 1.1)
33+
dry-inflector (~> 1.0)
34+
umbrellio-sequel-plugins (~> 0.14)
3035
coderay (1.1.3)
31-
colorize (0.8.1)
32-
concurrent-ruby (1.2.2)
36+
colorize (1.1.0)
37+
concurrent-ruby (1.3.4)
3338
connection_pool (2.4.1)
34-
diff-lcs (1.5.0)
35-
docile (1.4.0)
36-
drb (2.2.0)
37-
ruby2_keywords
38-
dry-inflector (0.3.0)
39-
i18n (1.14.1)
39+
diff-lcs (1.5.1)
40+
docile (1.4.1)
41+
drb (2.2.1)
42+
dry-inflector (1.1.0)
43+
dry-initializer (3.1.1)
44+
i18n (1.14.6)
4045
concurrent-ruby (~> 1.0)
41-
json (2.6.3)
42-
method_source (1.0.0)
43-
minitest (5.20.0)
44-
mutex_m (0.2.0)
45-
parallel (1.23.0)
46-
parser (3.2.2.4)
46+
json (2.9.0)
47+
language_server-protocol (3.17.0.3)
48+
logger (1.6.3)
49+
method_source (1.1.0)
50+
minitest (5.25.4)
51+
parallel (1.26.3)
52+
parser (3.3.6.0)
4753
ast (~> 2.4.1)
4854
racc
49-
pry (0.14.2)
55+
pry (0.15.0)
5056
coderay (~> 1.1)
5157
method_source (~> 1.0)
52-
qonfig (0.28.0)
53-
racc (1.7.3)
54-
rack (3.0.8)
58+
qonfig (0.29.0)
59+
racc (1.8.1)
60+
rack (3.1.8)
5561
rainbow (3.1.1)
56-
rake (13.1.0)
57-
regexp_parser (2.8.2)
58-
rexml (3.2.6)
59-
rspec (3.12.0)
60-
rspec-core (~> 3.12.0)
61-
rspec-expectations (~> 3.12.0)
62-
rspec-mocks (~> 3.12.0)
63-
rspec-core (3.12.2)
64-
rspec-support (~> 3.12.0)
65-
rspec-expectations (3.12.3)
62+
rake (13.2.1)
63+
regexp_parser (2.9.3)
64+
rspec (3.13.0)
65+
rspec-core (~> 3.13.0)
66+
rspec-expectations (~> 3.13.0)
67+
rspec-mocks (~> 3.13.0)
68+
rspec-core (3.13.2)
69+
rspec-support (~> 3.13.0)
70+
rspec-expectations (3.13.3)
6671
diff-lcs (>= 1.2.0, < 2.0)
67-
rspec-support (~> 3.12.0)
68-
rspec-mocks (3.12.6)
72+
rspec-support (~> 3.13.0)
73+
rspec-mocks (3.13.2)
6974
diff-lcs (>= 1.2.0, < 2.0)
70-
rspec-support (~> 3.12.0)
71-
rspec-support (3.12.1)
72-
rubocop (1.50.2)
75+
rspec-support (~> 3.13.0)
76+
rspec-support (3.13.2)
77+
rubocop (1.66.1)
7378
json (~> 2.3)
79+
language_server-protocol (>= 3.17.0)
7480
parallel (~> 1.10)
75-
parser (>= 3.2.0.0)
81+
parser (>= 3.3.0.2)
7682
rainbow (>= 2.2.2, < 4.0)
77-
regexp_parser (>= 1.8, < 3.0)
78-
rexml (>= 3.2.5, < 4.0)
79-
rubocop-ast (>= 1.28.0, < 2.0)
83+
regexp_parser (>= 2.4, < 3.0)
84+
rubocop-ast (>= 1.32.2, < 2.0)
8085
ruby-progressbar (~> 1.7)
8186
unicode-display_width (>= 2.4.0, < 3.0)
82-
rubocop-ast (1.30.0)
83-
parser (>= 3.2.1.0)
84-
rubocop-capybara (2.19.0)
85-
rubocop (~> 1.41)
86-
rubocop-config-umbrellio (1.50.0.85)
87-
rubocop (~> 1.50.0)
88-
rubocop-performance (~> 1.17.0)
89-
rubocop-rails (~> 2.19.0)
87+
rubocop-ast (1.37.0)
88+
parser (>= 3.3.1.0)
89+
rubocop-config-umbrellio (1.66.0.99)
90+
rubocop (~> 1.66.0)
91+
rubocop-factory_bot (~> 2.26.0)
92+
rubocop-performance (~> 1.22.0)
93+
rubocop-rails (~> 2.26.0)
9094
rubocop-rake (~> 0.6.0)
91-
rubocop-rspec (~> 2.20.0)
95+
rubocop-rspec (~> 3.0.0)
9296
rubocop-sequel (~> 0.3.3)
93-
rubocop-performance (1.17.1)
94-
rubocop (>= 1.7.0, < 2.0)
95-
rubocop-ast (>= 0.4.0)
96-
rubocop-rails (2.19.1)
97+
rubocop-factory_bot (2.26.1)
98+
rubocop (~> 1.61)
99+
rubocop-performance (1.22.1)
100+
rubocop (>= 1.48.1, < 2.0)
101+
rubocop-ast (>= 1.31.1, < 2.0)
102+
rubocop-rails (2.26.2)
97103
activesupport (>= 4.2.0)
98104
rack (>= 1.1)
99-
rubocop (>= 1.33.0, < 2.0)
105+
rubocop (>= 1.52.0, < 2.0)
106+
rubocop-ast (>= 1.31.1, < 2.0)
100107
rubocop-rake (0.6.0)
101108
rubocop (~> 1.0)
102-
rubocop-rspec (2.20.0)
103-
rubocop (~> 1.33)
104-
rubocop-capybara (~> 2.17)
105-
rubocop-sequel (0.3.4)
109+
rubocop-rspec (3.0.5)
110+
rubocop (~> 1.61)
111+
rubocop-sequel (0.3.7)
106112
rubocop (~> 1.0)
107113
ruby-progressbar (1.13.0)
108-
ruby2_keywords (0.0.5)
109-
sequel (5.74.0)
114+
securerandom (0.4.0)
115+
sequel (5.87.0)
110116
bigdecimal
111117
simplecov (0.22.0)
112118
docile (~> 1.1)
113119
simplecov-html (~> 0.11)
114120
simplecov_json_formatter (~> 0.1)
115-
simplecov-html (0.12.3)
121+
simplecov-html (0.13.1)
116122
simplecov-lcov (0.8.0)
117123
simplecov_json_formatter (0.1.4)
118124
smart_engine (0.17.0)
@@ -122,14 +128,13 @@ GEM
122128
smart_types (~> 0.8)
123129
smart_types (0.8.0)
124130
smart_engine (~> 0.11)
125-
symbiont-ruby (0.7.0)
126-
thor (1.3.0)
131+
thor (1.3.2)
127132
tzinfo (2.0.6)
128133
concurrent-ruby (~> 1.0)
129-
umbrellio-sequel-plugins (0.14.0.189)
134+
umbrellio-sequel-plugins (0.17.0)
130135
sequel
131-
symbiont-ruby
132-
unicode-display_width (2.5.0)
136+
unicode-display_width (2.6.0)
137+
uri (1.0.2)
133138

134139
PLATFORMS
135140
arm64-darwin-21
@@ -142,13 +147,15 @@ PLATFORMS
142147
DEPENDENCIES
143148
bundler-audit
144149
ci-helper
150+
dry-initializer
145151
pry
146152
rake
147153
resol!
148154
rspec
149155
rubocop-config-umbrellio
150156
simplecov
151157
simplecov-lcov
158+
smart_initializer
152159

153160
BUNDLED WITH
154161
2.4.10

lib/resol/configuration.rb

+3-3
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ def return_engine=(engine)
2525

2626
attr_accessor :smartcore_config
2727

28-
def method_missing(meth, *args, &block)
28+
def method_missing(meth, *, &)
2929
# rubocop:disable Style/SafeNavigation
3030
if smartcore_config && smartcore_config.respond_to?(meth)
3131
# rubocop:enable Style/SafeNavigation
32-
smartcore_config.__send__(meth, *args, &block)
32+
smartcore_config.__send__(meth, *, &)
3333
else
34-
super(meth, *args, &block)
34+
super
3535
end
3636
end
3737

lib/resol/initializers.rb

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# frozen_string_literal: true
2+
3+
module Resol
4+
module Initializers
5+
extend self
6+
7+
INITIALIZER_ANCESTOR_REGEX = /(Dry|SmartCore)::Initializer/
8+
9+
def apply!(service_class, initializer_name)
10+
validate_state!(service_class)
11+
12+
case initializer_name
13+
when :smartcore
14+
require "smart_core/initializer"
15+
service_class.include(Object.const_get("SmartCore::Initializer"))
16+
when :dry
17+
require "dry/initializer"
18+
service_class.extend(Object.const_get("Dry::Initializer"))
19+
else
20+
raise ArgumentError, "unknown initializer #{initializer_name}"
21+
end
22+
23+
(self.applied_classes ||= []) << service_class.name
24+
end
25+
26+
private
27+
28+
attr_accessor :applied_classes
29+
30+
def validate_state!(service_class)
31+
applied_parent = nil
32+
service_class.ancestors.any? { |klass| klass.name.start_with?(INITIALIZER_ANCESTOR_REGEX) }
33+
34+
loop do
35+
applied_parent = service_class.superclass or break
36+
37+
break if applied_classes.key?(applied_parent.name)
38+
end
39+
40+
if applied_parent.nil?
41+
err_message = "#{service_class.name} or his superclasses manually include initializer dsl"
42+
raise ArgumentError, err_message
43+
else
44+
raise ArgumentError, "initializer dsl already applied to #{applied_parent.name}"
45+
end
46+
end
47+
end
48+
end

lib/resol/plugins.rb

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# frozen_string_literal: true
2+
3+
require "pathname"
4+
5+
module Resol
6+
module Plugins
7+
class Manager
8+
include Singleton
9+
10+
def initialize
11+
self.patched_class = Resol::Service
12+
self.plugins = []
13+
self.plugin_lib_path = PathName("resol/plugins")
14+
end
15+
16+
def plugin(plugin_name, ...)
17+
plugin_module = find_plugin_module(plugin_name)
18+
plugin_module.apply(target_class, ...) if plugin_module.respond_to?(:apply)
19+
20+
if defined?(plugin_module::InstanceMethods)
21+
target_class.include(plugin_module::InstanceMethods)
22+
end
23+
24+
if defined?(plugin_module::ClassMethods)
25+
target_class.extend(plugin_module::ClassMethods)
26+
end
27+
28+
plugins << plugin_name
29+
end
30+
31+
private
32+
33+
attr_accessor :target_class, :plugins, :plugin_lib_path
34+
35+
def find_plugin_module(plugin_name)
36+
require plugin_lib_path.join(plugin_name)
37+
rescue LoadError, NameError => e
38+
raise "Failed to load plugin '#{plugin_name}': #{e.message}"
39+
end
40+
41+
def camel_case(string)
42+
string.split("_").map(&:capitalize).join
43+
end
44+
end
45+
end
46+
end

lib/resol/service.rb

+8-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
require_relative "builder"
44
require_relative "callbacks"
55
require_relative "result"
6+
require_relative "initializers"
67

78
module Resol
89
class Service
@@ -27,7 +28,6 @@ def message
2728
end
2829
end
2930

30-
include SmartCore::Initializer
3131
include Resol::Builder
3232
include Resol::Callbacks
3333

@@ -39,13 +39,17 @@ def inherited(klass)
3939
super
4040
end
4141

42-
def call(*args, **kwargs, &block)
43-
service = build(*args, **kwargs)
42+
def use_initializer!(initializer_lib)
43+
Resol::Initializers.apply!(self, initializer_lib)
44+
end
45+
46+
def call(*, **, &)
47+
service = build(*, **)
4448

4549
result = return_engine.wrap_call(service) do
4650
service.instance_variable_set(:@__performing__, true)
4751
__run_callbacks__(service)
48-
service.call(&block)
52+
service.call(&)
4953
end
5054

5155
if return_engine.uncaught_call?(result)

0 commit comments

Comments
 (0)