decouplio 1.0.0alpha7 → 1.0.0rc
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/README.md +313 -15
- data/decouplio.gemspec +8 -2
- data/lib/decouplio/action.rb +34 -74
- data/lib/decouplio/action_state_printer.rb +34 -0
- data/lib/decouplio/const/flows.rb +59 -0
- data/lib/decouplio/const/reserved_methods.rb +6 -13
- data/lib/decouplio/const/types.rb +1 -165
- data/lib/decouplio/const/validations/common.rb +10 -0
- data/lib/decouplio/const/validations/octo.rb +16 -0
- data/lib/decouplio/const/validations/resq.rb +12 -1
- data/lib/decouplio/ctx.rb +13 -0
- data/lib/decouplio/default_meta_store.rb +37 -0
- data/lib/decouplio/errors/action_class_error.rb +0 -3
- data/lib/decouplio/errors/base_error.rb +0 -3
- data/lib/decouplio/errors/execution_error.rb +0 -2
- data/lib/decouplio/errors/extra_key_for_pass_error.rb +0 -3
- data/lib/decouplio/errors/fail_can_not_be_first_step_error.rb +0 -3
- data/lib/decouplio/errors/fail_controversial_keys_error.rb +0 -3
- data/lib/decouplio/errors/fail_finish_him_error.rb +0 -3
- data/lib/decouplio/errors/invalid_error_class_error.rb +0 -3
- data/lib/decouplio/errors/invalid_options_for_resq_step.rb +18 -0
- data/lib/decouplio/errors/invalid_wrap_name_error.rb +0 -3
- data/lib/decouplio/errors/logic_is_not_defined_error.rb +0 -3
- data/lib/decouplio/errors/logic_redefinition_error.rb +0 -3
- data/lib/decouplio/errors/octo_block_is_not_defined_error.rb +0 -3
- data/lib/decouplio/errors/octo_case_is_not_defined_error.rb +19 -0
- data/lib/decouplio/errors/octo_controversial_keys_error.rb +0 -3
- data/lib/decouplio/errors/{error_store_error.rb → octo_finish_him_is_not_allowed_error.rb} +2 -4
- data/lib/decouplio/errors/options_validation_error.rb +13 -1
- data/lib/decouplio/errors/palp_block_is_not_defined_error.rb +0 -3
- data/lib/decouplio/errors/palp_validation_error.rb +0 -3
- data/lib/decouplio/errors/pass_controversial_keys_error.rb +0 -3
- data/lib/decouplio/errors/pass_finish_him_error.rb +0 -3
- data/lib/decouplio/errors/required_options_is_missing_for_octo_error.rb +0 -3
- data/lib/decouplio/errors/resq_definition_error.rb +0 -3
- data/lib/decouplio/errors/resq_error_class_error.rb +0 -3
- data/lib/decouplio/errors/resq_handler_method_error.rb +0 -3
- data/lib/decouplio/errors/step_controversial_keys_error.rb +0 -3
- data/lib/decouplio/errors/step_definition_error.rb +17 -0
- data/lib/decouplio/errors/step_finish_him_error.rb +0 -3
- data/lib/decouplio/errors/step_is_not_defined_for_fail_error.rb +0 -3
- data/lib/decouplio/errors/step_is_not_defined_for_pass_error.rb +0 -4
- data/lib/decouplio/errors/step_is_not_defined_for_step_error.rb +0 -4
- data/lib/decouplio/errors/step_is_not_defined_for_wrap_error.rb +0 -3
- data/lib/decouplio/errors/step_name_error.rb +0 -3
- data/lib/decouplio/errors/wrap_block_is_not_defined_error.rb +0 -3
- data/lib/decouplio/errors/wrap_controversial_keys_error.rb +0 -3
- data/lib/decouplio/errors/wrap_finish_him_error.rb +0 -3
- data/lib/decouplio/errors/wrap_klass_method_error.rb +0 -3
- data/lib/decouplio/graph.rb +9 -0
- data/lib/decouplio/logic_dsl.rb +337 -107
- data/lib/decouplio/new_flow.rb +283 -0
- data/lib/decouplio/octo_hash_case.rb +20 -5
- data/lib/decouplio/octo_options_validator.rb +10 -64
- data/lib/decouplio/step_validator.rb +200 -0
- data/lib/decouplio/steps/base_condition.rb +21 -0
- data/lib/decouplio/steps/base_if_condition.rb +11 -0
- data/lib/decouplio/steps/base_inner_action.rb +42 -0
- data/lib/decouplio/steps/base_octo.rb +26 -0
- data/lib/decouplio/steps/base_resq.rb +25 -28
- data/lib/decouplio/steps/base_resq_with_mapping.rb +34 -0
- data/lib/decouplio/steps/base_service_step.rb +39 -0
- data/lib/decouplio/steps/base_step.rb +33 -6
- data/lib/decouplio/steps/base_unless_condition.rb +11 -0
- data/lib/decouplio/steps/base_wrap.rb +27 -0
- data/lib/decouplio/steps/fail.rb +1 -28
- data/lib/decouplio/steps/if_condition_fail.rb +1 -21
- data/lib/decouplio/steps/if_condition_pass.rb +1 -19
- data/lib/decouplio/steps/inner_action_fail.rb +1 -33
- data/lib/decouplio/steps/inner_action_pass.rb +12 -30
- data/lib/decouplio/steps/inner_action_step.rb +1 -33
- data/lib/decouplio/steps/octo_by_key.rb +31 -0
- data/lib/decouplio/steps/octo_by_method.rb +31 -0
- data/lib/decouplio/steps/pass.rb +5 -26
- data/lib/decouplio/steps/resq_fail.rb +0 -2
- data/lib/decouplio/steps/resq_pass.rb +1 -3
- data/lib/decouplio/steps/resq_with_mapping_fail.rb +8 -0
- data/lib/decouplio/steps/resq_with_mapping_pass.rb +8 -0
- data/lib/decouplio/steps/service_as_fail.rb +8 -0
- data/lib/decouplio/steps/service_as_pass.rb +16 -0
- data/lib/decouplio/steps/service_as_step.rb +8 -0
- data/lib/decouplio/steps/step.rb +0 -24
- data/lib/decouplio/steps/unless_condition_fail.rb +1 -21
- data/lib/decouplio/steps/unless_condition_pass.rb +1 -19
- data/lib/decouplio/steps/wrap.rb +25 -37
- data/lib/decouplio/steps/wrap_with_class.rb +43 -0
- data/lib/decouplio/steps/wrap_with_class_method.rb +45 -0
- data/lib/decouplio/utils/prepare_resq_mappings.rb +17 -0
- data/lib/decouplio/version.rb +1 -1
- data/lib/decouplio.rb +93 -0
- metadata +32 -55
- data/.circleci/config.yml +0 -63
- data/.dockerignore +0 -12
- data/.gitignore +0 -13
- data/.rspec +0 -3
- data/.rubocop.yml +0 -116
- data/.rubocop_todo.yml +0 -147
- data/.ruby-version +0 -1
- data/.vscode/settings.json +0 -3
- data/Dockerfile +0 -12
- data/Gemfile +0 -8
- data/benchmarks/.ruby-version +0 -1
- data/benchmarks/Dockerfile +0 -12
- data/benchmarks/Gemfile +0 -12
- data/benchmarks/multi_step_benchmark.rb +0 -336
- data/benchmarks/single_step_benchmark.rb +0 -159
- data/bin/console +0 -15
- data/bin/setup +0 -8
- data/docker-compose.yml +0 -29
- data/lib/decouplio/composer.rb +0 -691
- data/lib/decouplio/const/colors.rb +0 -25
- data/lib/decouplio/const/doby_aide_options.rb +0 -16
- data/lib/decouplio/const/results.rb +0 -15
- data/lib/decouplio/const/step_options.rb +0 -16
- data/lib/decouplio/const/validations/aide.rb +0 -38
- data/lib/decouplio/const/validations/doby.rb +0 -36
- data/lib/decouplio/default_error_handler.rb +0 -39
- data/lib/decouplio/errors/aide_can_not_be_first_step_error.rb +0 -18
- data/lib/decouplio/errors/aide_controversial_keys_error.rb +0 -26
- data/lib/decouplio/errors/aide_finish_him_error.rb +0 -26
- data/lib/decouplio/errors/doby_controversial_keys_error.rb +0 -26
- data/lib/decouplio/errors/doby_finish_him_error.rb +0 -26
- data/lib/decouplio/errors/extra_key_for_fail_error.rb +0 -26
- data/lib/decouplio/errors/extra_key_for_octo_error.rb +0 -26
- data/lib/decouplio/errors/extra_key_for_resq_error.rb +0 -29
- data/lib/decouplio/errors/extra_key_for_step_error.rb +0 -23
- data/lib/decouplio/errors/extra_key_for_wrap_error.rb +0 -23
- data/lib/decouplio/errors/palp_is_not_defined_error.rb +0 -26
- data/lib/decouplio/errors/step_is_not_defined_for_aide_error.rb +0 -26
- data/lib/decouplio/errors/step_is_not_defined_for_doby_error.rb +0 -27
- data/lib/decouplio/flow.rb +0 -17
- data/lib/decouplio/options_validator.rb +0 -716
- data/lib/decouplio/processor.rb +0 -20
- data/lib/decouplio/steps/aide.rb +0 -37
- data/lib/decouplio/steps/doby.rb +0 -37
- data/lib/decouplio/steps/octo.rb +0 -27
- data/lib/decouplio/steps/service_fail.rb +0 -41
- data/lib/decouplio/steps/service_pass.rb +0 -41
- data/lib/decouplio/steps/service_step.rb +0 -41
- data/lib/decouplio/steps/shared/fail_resolver.rb +0 -40
- data/lib/decouplio/steps/shared/step_resolver.rb +0 -43
- data/lib/decouplio/validators/condition.rb +0 -59
@@ -0,0 +1,283 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decouplio
|
4
|
+
class NewFlow
|
5
|
+
def self.call(logic)
|
6
|
+
logic_container_raw_data = Class.new(Decouplio::LogicDsl, &logic)
|
7
|
+
|
8
|
+
steps = logic_container_raw_data.steps
|
9
|
+
|
10
|
+
compose_steps(steps.delete_at(0), steps)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.compose_steps(stp, steps)
|
14
|
+
return stp if stp.nil?
|
15
|
+
|
16
|
+
Decouplio::StepValidator.call(stp, steps)
|
17
|
+
|
18
|
+
if stp.is_a?(Decouplio::Steps::BaseOcto)
|
19
|
+
next_success_step, success_resolver = compose_flow_direction(stp, steps, :success)
|
20
|
+
next_failure_step, failure_resolver = compose_flow_direction(stp, steps, :failure)
|
21
|
+
next_on_error, on_error_resolver = compose_flow_direction(stp, steps, :error)
|
22
|
+
|
23
|
+
stp._add_next_steps([next_success_step, next_failure_step, next_on_error])
|
24
|
+
stp._add_resolvers([success_resolver, failure_resolver, on_error_resolver])
|
25
|
+
|
26
|
+
compose_octo(stp, steps)
|
27
|
+
elsif Decouplio::Const::Flows::RESQ_CLASSES.include?(stp.class)
|
28
|
+
next_success_step, success_resolver = compose_flow_direction(stp.step_to_resq, steps, :success)
|
29
|
+
next_failure_step, failure_resolver = compose_flow_direction(stp.step_to_resq, steps, :failure)
|
30
|
+
next_on_error, on_error_resolver = compose_flow_direction(stp.step_to_resq, steps, :error)
|
31
|
+
|
32
|
+
stp.step_to_resq._add_next_steps([next_success_step, next_failure_step, next_on_error])
|
33
|
+
stp.step_to_resq._add_resolvers([success_resolver, failure_resolver, on_error_resolver])
|
34
|
+
|
35
|
+
compose_wrap(stp.step_to_resq) if stp.step_to_resq.is_a?(Decouplio::Steps::BaseWrap)
|
36
|
+
|
37
|
+
# next_success_step, success_resolver = compose_flow_direction(stp.step_to_resq, steps, :success)
|
38
|
+
# next_failure_step, failure_resolver = compose_flow_direction(stp.step_to_resq, steps, :failure)
|
39
|
+
# next_on_error, on_error_resolver = compose_flow_direction(stp.step_to_resq, steps, :error)
|
40
|
+
|
41
|
+
# stp.step_to_resq._add_next_steps([next_success_step, next_failure_step, next_on_error])
|
42
|
+
# stp.step_to_resq._add_resolvers([success_resolver, failure_resolver, on_error_resolver])
|
43
|
+
elsif stp.is_a?(Decouplio::Steps::BaseWrap)
|
44
|
+
compose_wrap(stp)
|
45
|
+
compose_step(stp, steps)
|
46
|
+
else
|
47
|
+
compose_step(stp, steps)
|
48
|
+
end
|
49
|
+
|
50
|
+
next_step_to_process = steps.delete_at(0)
|
51
|
+
compose_steps(next_step_to_process, steps)
|
52
|
+
stp
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.compose_wrap(stp)
|
56
|
+
wrap_first_step = call(stp.wrap_block)
|
57
|
+
stp._add_wrap_first_step(wrap_first_step)
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.compose_octo(stp, steps)
|
61
|
+
linked_hash_case = stp.hash_case.to_h do |key, octo_step|
|
62
|
+
if octo_step.on_success.nil?
|
63
|
+
next_success_step = stp.on_success
|
64
|
+
success_resolver = stp.on_success_resolver
|
65
|
+
else
|
66
|
+
next_success_step, success_resolver = compose_flow_direction(octo_step, steps, :success)
|
67
|
+
end
|
68
|
+
|
69
|
+
if octo_step.on_failure.nil?
|
70
|
+
next_failure_step = stp.on_failure
|
71
|
+
failure_resolver = stp.on_failure_resolver
|
72
|
+
else
|
73
|
+
next_failure_step, failure_resolver = compose_flow_direction(octo_step, steps, :failure)
|
74
|
+
end
|
75
|
+
|
76
|
+
if octo_step.on_error.nil?
|
77
|
+
next_on_error = stp.on_error
|
78
|
+
on_error_resolver = stp.on_error_resolver
|
79
|
+
else
|
80
|
+
next_on_error, on_error_resolver = compose_flow_direction(octo_step, steps, :error)
|
81
|
+
end
|
82
|
+
|
83
|
+
compose_wrap(octo_step)
|
84
|
+
|
85
|
+
octo_step._add_next_steps(
|
86
|
+
[
|
87
|
+
next_success_step,
|
88
|
+
next_failure_step,
|
89
|
+
next_on_error
|
90
|
+
]
|
91
|
+
)
|
92
|
+
octo_step._add_resolvers(
|
93
|
+
[
|
94
|
+
success_resolver,
|
95
|
+
failure_resolver,
|
96
|
+
on_error_resolver
|
97
|
+
]
|
98
|
+
)
|
99
|
+
|
100
|
+
if stp.resq
|
101
|
+
octo_resq_step = stp.resq.clone
|
102
|
+
octo_resq_step._add_step_to_resq(octo_step)
|
103
|
+
[key, octo_resq_step]
|
104
|
+
else
|
105
|
+
[key, octo_step]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
stp._add_octo_next_steps(linked_hash_case)
|
110
|
+
end
|
111
|
+
|
112
|
+
def self.compose_step(stp, steps)
|
113
|
+
next_success_step, success_resolver = compose_flow_direction(stp, steps, :success)
|
114
|
+
next_failure_step, failure_resolver = compose_flow_direction(stp, steps, :failure)
|
115
|
+
|
116
|
+
stp._add_next_steps([next_success_step, next_failure_step])
|
117
|
+
stp._add_resolvers([success_resolver, failure_resolver])
|
118
|
+
end
|
119
|
+
|
120
|
+
def self.compose_flow_direction(stp, steps, type)
|
121
|
+
case stp
|
122
|
+
when Decouplio::Steps::Step,
|
123
|
+
Decouplio::Steps::InnerActionStep,
|
124
|
+
Decouplio::Steps::ServiceAsStep
|
125
|
+
compose_step_outcome("for_step_#{type}".to_sym, stp, steps)
|
126
|
+
when Decouplio::Steps::Fail,
|
127
|
+
Decouplio::Steps::InnerActionFail,
|
128
|
+
Decouplio::Steps::ServiceAsFail
|
129
|
+
compose_step_outcome("for_fail_#{type}".to_sym, stp, steps)
|
130
|
+
when Decouplio::Steps::Pass,
|
131
|
+
Decouplio::Steps::InnerActionPass,
|
132
|
+
Decouplio::Steps::ServiceAsPass
|
133
|
+
compose_step_outcome("for_pass_#{type}".to_sym, stp, steps)
|
134
|
+
when Decouplio::Steps::IfConditionPass
|
135
|
+
compose_condition_outcome("for_if_pass_#{type}".to_sym, stp, steps)
|
136
|
+
when Decouplio::Steps::IfConditionFail
|
137
|
+
compose_condition_outcome("for_if_fail_#{type}".to_sym, stp, steps)
|
138
|
+
when Decouplio::Steps::UnlessConditionPass
|
139
|
+
compose_condition_outcome("for_unless_pass_#{type}".to_sym, stp, steps)
|
140
|
+
when Decouplio::Steps::UnlessConditionFail
|
141
|
+
compose_condition_outcome("for_unless_fail_#{type}".to_sym, stp, steps)
|
142
|
+
when Decouplio::Steps::Wrap,
|
143
|
+
Decouplio::Steps::WrapWithClass,
|
144
|
+
Decouplio::Steps::WrapWithClassMethod
|
145
|
+
compose_step_outcome("for_wrap_#{type}".to_sym, stp, steps)
|
146
|
+
when Decouplio::Steps::BaseOcto
|
147
|
+
compose_step_outcome("for_octo_#{type}".to_sym, stp, steps)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def self.compose_step_outcome(flow, stp, steps)
|
152
|
+
case flow
|
153
|
+
when :for_fail_success
|
154
|
+
return [nil, false] if stp.finish_him == true
|
155
|
+
return [nil, false] if stp.finish_him == :on_success
|
156
|
+
return [next_failure_step(steps), false] if stp.on_success.nil?
|
157
|
+
return [nil, false] if stp.on_success == :finish_him
|
158
|
+
return [next_success_step(steps), true] if stp.on_success == :PASS
|
159
|
+
return [next_failure_step(steps), false] if stp.on_success == :FAIL
|
160
|
+
|
161
|
+
[next_step(stp.on_success, steps), false]
|
162
|
+
when :for_fail_failure
|
163
|
+
return [nil, false] if stp.finish_him == true
|
164
|
+
return [nil, false] if stp.finish_him == :on_failure
|
165
|
+
return [next_failure_step(steps), false] if stp.on_failure.nil?
|
166
|
+
return [nil, false] if stp.on_failure == :finish_him
|
167
|
+
return [next_success_step(steps), true] if stp.on_failure == :PASS
|
168
|
+
return [next_failure_step(steps), false] if stp.on_failure == :FAIL
|
169
|
+
|
170
|
+
[next_step(stp.on_failure, steps), false]
|
171
|
+
when :for_pass_success
|
172
|
+
return [nil, true] if stp.finish_him == true
|
173
|
+
|
174
|
+
[next_success_step(steps), true]
|
175
|
+
when :for_pass_failure
|
176
|
+
[nil, nil]
|
177
|
+
when :for_step_success, :for_wrap_success, :for_octo_success
|
178
|
+
return [nil, true] if stp.finish_him == :on_success
|
179
|
+
return [next_success_step(steps), true] if stp.on_success.nil?
|
180
|
+
return [nil, true] if stp.on_success == :finish_him
|
181
|
+
return [next_success_step(steps), true] if stp.on_success == :PASS
|
182
|
+
return [next_failure_step(steps), false] if stp.on_success == :FAIL
|
183
|
+
|
184
|
+
[next_step(stp.on_success, steps), true]
|
185
|
+
when :for_step_failure, :for_wrap_failure, :for_octo_failure
|
186
|
+
return [nil, false] if stp.finish_him == :on_failure
|
187
|
+
return [next_failure_step(steps), false] if stp.on_failure.nil?
|
188
|
+
return [nil, false] if stp.on_failure == :finish_him
|
189
|
+
return [next_success_step(steps), true] if stp.on_failure == :PASS
|
190
|
+
return [next_failure_step(steps), false] if stp.on_failure == :FAIL
|
191
|
+
|
192
|
+
[next_step(stp.on_failure, steps), false]
|
193
|
+
when :for_step_error,
|
194
|
+
:for_fail_error,
|
195
|
+
:for_pass_error,
|
196
|
+
:for_octo_error,
|
197
|
+
:for_wrap_error
|
198
|
+
return [nil, false] if stp.finish_him == :on_error
|
199
|
+
return [next_failure_step(steps), false] if stp.on_error.nil?
|
200
|
+
return [nil, false] if stp.on_error == :finish_him
|
201
|
+
return [next_success_step(steps), true] if stp.on_error == :PASS
|
202
|
+
return [next_failure_step(steps), false] if stp.on_error == :FAIL
|
203
|
+
|
204
|
+
[next_step(stp.on_error, steps), false]
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
def self.compose_condition_outcome(flow, _stp, steps)
|
209
|
+
case flow
|
210
|
+
when :for_if_pass_success, :for_unless_pass_success
|
211
|
+
[next_success_step(steps), nil]
|
212
|
+
when :for_if_pass_failure, :for_unless_pass_failure
|
213
|
+
[next_success_step(steps[1..]), nil]
|
214
|
+
when :for_if_fail_success, :for_unless_fail_success
|
215
|
+
[next_failure_step(steps), nil]
|
216
|
+
when :for_if_fail_failure, :for_unless_fail_failure
|
217
|
+
[next_failure_step(steps[1..]), nil]
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
def self.next_success_step(steps)
|
222
|
+
steps.detect do |flow_step|
|
223
|
+
[
|
224
|
+
Decouplio::Steps::Step,
|
225
|
+
Decouplio::Steps::Pass,
|
226
|
+
Decouplio::Steps::IfConditionPass,
|
227
|
+
Decouplio::Steps::UnlessConditionPass,
|
228
|
+
Decouplio::Steps::OctoByKey,
|
229
|
+
Decouplio::Steps::OctoByMethod,
|
230
|
+
Decouplio::Steps::InnerActionStep,
|
231
|
+
Decouplio::Steps::InnerActionPass,
|
232
|
+
Decouplio::Steps::ServiceAsStep,
|
233
|
+
Decouplio::Steps::ServiceAsPass,
|
234
|
+
Decouplio::Steps::ResqPass,
|
235
|
+
Decouplio::Steps::ResqWithMappingPass,
|
236
|
+
Decouplio::Steps::Wrap,
|
237
|
+
Decouplio::Steps::WrapWithClass,
|
238
|
+
Decouplio::Steps::WrapWithClassMethod
|
239
|
+
].include?(flow_step.class)
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
def self.next_failure_step(steps)
|
244
|
+
steps.detect do |flow_step|
|
245
|
+
[
|
246
|
+
Decouplio::Steps::Fail,
|
247
|
+
Decouplio::Steps::IfConditionFail,
|
248
|
+
Decouplio::Steps::UnlessConditionFail,
|
249
|
+
Decouplio::Steps::InnerActionFail,
|
250
|
+
Decouplio::Steps::ServiceAsFail,
|
251
|
+
Decouplio::Steps::ResqFail,
|
252
|
+
Decouplio::Steps::ResqWithMappingFail
|
253
|
+
].include?(flow_step.class)
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
def self.next_step(step_name, steps)
|
258
|
+
steps.each_with_index do |flow_step, index|
|
259
|
+
if flow_step.name == step_name
|
260
|
+
if [
|
261
|
+
Decouplio::Steps::IfConditionFail,
|
262
|
+
Decouplio::Steps::UnlessConditionFail,
|
263
|
+
Decouplio::Steps::IfConditionPass,
|
264
|
+
Decouplio::Steps::UnlessConditionPass
|
265
|
+
].include?(steps[index - 1].class)
|
266
|
+
return steps[index - 1]
|
267
|
+
else
|
268
|
+
return flow_step
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
raise StandardError, 'Most likely it is a bug, please create an issue here https://github.com/differencialx/decouplio/issues'
|
273
|
+
end
|
274
|
+
|
275
|
+
def self.validate_wrap(logic_container_raw_data)
|
276
|
+
logic_container_raw_data.steps.map(&:class).each do |step_class|
|
277
|
+
next unless Decouplio::Const::Flows::OCTO_CLASSES.include?(step_class)
|
278
|
+
|
279
|
+
raise Decouplio::Errors::OctoInsideWrapError
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative 'octo_options_validator'
|
4
|
-
|
5
3
|
module Decouplio
|
6
4
|
class OctoHashCase
|
7
5
|
class << self
|
@@ -16,9 +14,26 @@ module Decouplio
|
|
16
14
|
@hash_case = {}
|
17
15
|
end
|
18
16
|
|
19
|
-
def on(
|
20
|
-
|
21
|
-
|
17
|
+
def on(octo_case, stp = nil, **options, &block)
|
18
|
+
if stp || block_given?
|
19
|
+
validate_options(options)
|
20
|
+
on_success = options.delete(:on_success)
|
21
|
+
on_failure = options.delete(:on_failure)
|
22
|
+
on_error = options.delete(:on_error)
|
23
|
+
wrap_block = block_given? ? block : proc { step(stp, **options) }
|
24
|
+
@hash_case[octo_case] = Decouplio::Steps::Wrap.new(
|
25
|
+
octo_case,
|
26
|
+
wrap_block,
|
27
|
+
on_success,
|
28
|
+
on_failure,
|
29
|
+
on_error,
|
30
|
+
nil
|
31
|
+
)
|
32
|
+
else
|
33
|
+
raise Decouplio::Errors::OctoCaseIsNotDefinedError.new(
|
34
|
+
errored_option: "on :#{octo_case}"
|
35
|
+
)
|
36
|
+
end
|
22
37
|
end
|
23
38
|
|
24
39
|
private
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative 'errors/options_validation_error'
|
4
|
-
|
5
3
|
module Decouplio
|
6
4
|
class OctoOptionsValidator
|
7
5
|
def self.call(options:)
|
@@ -13,77 +11,25 @@ module Decouplio
|
|
13
11
|
end
|
14
12
|
|
15
13
|
def call
|
16
|
-
|
17
|
-
validate_option_count
|
14
|
+
validate_options unless @options.empty?
|
18
15
|
end
|
19
16
|
|
20
17
|
private
|
21
18
|
|
22
|
-
def
|
23
|
-
|
24
|
-
return if extra_options.size.zero?
|
25
|
-
|
26
|
-
raise_validation_error(
|
27
|
-
compose_message(
|
28
|
-
STRATEGY_ON_ERROR_MESSAGE,
|
29
|
-
YELLOW,
|
30
|
-
extra_options,
|
31
|
-
EXTRA_OPTIONS_NOT_ALLOWED % extra_options,
|
32
|
-
ON_ALLOWED_OPTIONS,
|
33
|
-
STRATEGY_MANUAL_URL,
|
34
|
-
NO_COLOR
|
35
|
-
)
|
36
|
-
)
|
37
|
-
end
|
19
|
+
def validate_options
|
20
|
+
has_invalid_options = @options.keys.any? { |key| NOT_ALLOWED_OPTIONS.include?(key) }
|
38
21
|
|
39
|
-
|
40
|
-
return if @options.keys.size == 1
|
22
|
+
return unless has_invalid_options
|
41
23
|
|
42
|
-
raise_validation_error
|
43
|
-
compose_message(
|
44
|
-
STRATEGY_ON_ERROR_MESSAGE,
|
45
|
-
YELLOW,
|
46
|
-
@options,
|
47
|
-
ONLY_ONE_OPTION_PER_TIME_IS_ALLOWED,
|
48
|
-
ON_ALLOWED_OPTIONS,
|
49
|
-
STRATEGY_MANUAL_URL,
|
50
|
-
NO_COLOR
|
51
|
-
)
|
52
|
-
)
|
24
|
+
raise_validation_error
|
53
25
|
end
|
54
26
|
|
55
|
-
def raise_validation_error
|
56
|
-
raise Decouplio::Errors::OptionsValidationError
|
57
|
-
|
58
|
-
|
59
|
-
def compose_message(message, *interpolation_params)
|
60
|
-
message % interpolation_params
|
27
|
+
def raise_validation_error
|
28
|
+
raise Decouplio::Errors::OptionsValidationError.new(
|
29
|
+
errored_option: @options
|
30
|
+
)
|
61
31
|
end
|
62
32
|
|
63
|
-
|
64
|
-
YELLOW = "\033[1;33m"
|
65
|
-
NO_COLOR = "\033[0m"
|
66
|
-
STRATEGY_ON_ERROR_MESSAGE = <<~ERROR_MESSAGE
|
67
|
-
%s
|
68
|
-
Next options are not allowed for "on":
|
69
|
-
%s
|
70
|
-
|
71
|
-
Details:
|
72
|
-
%s
|
73
|
-
|
74
|
-
Allowed options are:
|
75
|
-
%s
|
76
|
-
|
77
|
-
Please read the manual about allowed options here:
|
78
|
-
%s
|
79
|
-
%s
|
80
|
-
ERROR_MESSAGE
|
81
|
-
EXTRA_OPTIONS_NOT_ALLOWED = '%s is not allowed for "on"'
|
82
|
-
ONLY_ONE_OPTION_PER_TIME_IS_ALLOWED = 'Only one option is allowed for "on".'
|
83
|
-
ON_ALLOWED_OPTIONS = %i[
|
84
|
-
step
|
85
|
-
palp
|
86
|
-
].freeze
|
87
|
-
STRATEGY_MANUAL_URL = 'https://stub.strategy.manual.url'
|
33
|
+
NOT_ALLOWED_OPTIONS = %i[finish_him if unless].freeze
|
88
34
|
end
|
89
35
|
end
|
@@ -0,0 +1,200 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decouplio
|
4
|
+
class StepValidator
|
5
|
+
def self.call(stp, steps)
|
6
|
+
case stp
|
7
|
+
when Decouplio::Steps::Step
|
8
|
+
validate_name(stp.name)
|
9
|
+
validate_step(stp, steps)
|
10
|
+
when Decouplio::Steps::InnerActionStep, Decouplio::Steps::ServiceAsStep
|
11
|
+
validate_step(stp, steps)
|
12
|
+
when Decouplio::Steps::Fail
|
13
|
+
validate_name(stp.name)
|
14
|
+
validate_fail(stp, steps)
|
15
|
+
when Decouplio::Steps::InnerActionFail, Decouplio::Steps::ServiceAsFail
|
16
|
+
validate_fail(stp, steps)
|
17
|
+
when Decouplio::Steps::Pass
|
18
|
+
validate_name(stp.name)
|
19
|
+
validate_pass(stp, steps)
|
20
|
+
when Decouplio::Steps::ServiceAsPass, Decouplio::Steps::InnerActionPass
|
21
|
+
validate_pass(stp, steps)
|
22
|
+
when Decouplio::Steps::Wrap,
|
23
|
+
Decouplio::Steps::WrapWithClassMethod
|
24
|
+
validate_name(stp.name)
|
25
|
+
validate_finish_him(stp, Decouplio::Errors::WrapFinishHimError)
|
26
|
+
validate_contraversal_key(stp, Decouplio::Errors::WrapControversialKeysError)
|
27
|
+
validate_on_s(stp, steps, Decouplio::Errors::StepIsNotDefinedForWrapError)
|
28
|
+
validate_on_f(stp, steps, Decouplio::Errors::StepIsNotDefinedForWrapError)
|
29
|
+
validate_on_e(stp, steps, Decouplio::Errors::StepIsNotDefinedForWrapError)
|
30
|
+
when Decouplio::Steps::OctoByKey,
|
31
|
+
Decouplio::Steps::OctoByMethod
|
32
|
+
validate_name(stp.name)
|
33
|
+
when Decouplio::Steps::ResqPass,
|
34
|
+
Decouplio::Steps::ResqFail
|
35
|
+
validate_name(stp.name)
|
36
|
+
validate_name(stp.handler_method)
|
37
|
+
call(stp.step_to_resq, steps)
|
38
|
+
when Decouplio::Steps::ResqWithMappingPass,
|
39
|
+
Decouplio::Steps::ResqWithMappingFail
|
40
|
+
validate_name(stp.name)
|
41
|
+
stp.mappings.each do |class_to_handle, handler_method_name|
|
42
|
+
validate_symbol(handler_method_name)
|
43
|
+
validate_name(handler_method_name)
|
44
|
+
validate_class(class_to_handle, handler_method_name)
|
45
|
+
validate_exception_inheritance(class_to_handle)
|
46
|
+
end
|
47
|
+
call(stp.step_to_resq, steps)
|
48
|
+
when Decouplio::Steps::IfConditionPass,
|
49
|
+
Decouplio::Steps::IfConditionFail,
|
50
|
+
Decouplio::Steps::UnlessConditionPass,
|
51
|
+
Decouplio::Steps::UnlessConditionFail
|
52
|
+
validate_name(stp.condition_method)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.validate_step(stp, steps)
|
57
|
+
validate_finish_him(stp, Decouplio::Errors::StepFinishHimError)
|
58
|
+
validate_contraversal_key(stp, Decouplio::Errors::StepControversialKeysError)
|
59
|
+
validate_on_s(stp, steps, Decouplio::Errors::StepIsNotDefinedForStepError)
|
60
|
+
validate_on_f(stp, steps, Decouplio::Errors::StepIsNotDefinedForStepError)
|
61
|
+
validate_on_e(stp, steps, Decouplio::Errors::StepIsNotDefinedForStepError)
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.validate_fail(stp, steps)
|
65
|
+
validate_finish_him_for_fail(stp, Decouplio::Errors::FailFinishHimError)
|
66
|
+
validate_contraversal_key(stp, Decouplio::Errors::FailControversialKeysError)
|
67
|
+
validate_on_s(stp, steps, Decouplio::Errors::StepIsNotDefinedForFailError)
|
68
|
+
validate_on_f(stp, steps, Decouplio::Errors::StepIsNotDefinedForFailError)
|
69
|
+
validate_on_e(stp, steps, Decouplio::Errors::StepIsNotDefinedForFailError)
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.validate_pass(stp, steps)
|
73
|
+
validate_finish_him_for_pass(stp, Decouplio::Errors::PassFinishHimError)
|
74
|
+
validate_contraversal_key(stp, Decouplio::Errors::StepControversialKeysError)
|
75
|
+
validate_on_s(stp, steps, Decouplio::Errors::StepIsNotDefinedForPassError)
|
76
|
+
validate_on_f(stp, steps, Decouplio::Errors::StepIsNotDefinedForPassError)
|
77
|
+
validate_on_e(stp, steps, Decouplio::Errors::StepIsNotDefinedForPassError)
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.validate_class(class_to_handle, handler_method_name)
|
81
|
+
return if class_to_handle.is_a?(Class)
|
82
|
+
|
83
|
+
raise Decouplio::Errors::ResqErrorClassError.new(
|
84
|
+
errored_option: class_to_handle,
|
85
|
+
details: handler_method_name
|
86
|
+
)
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.validate_exception_inheritance(class_to_handle)
|
90
|
+
return if class_to_handle < Exception
|
91
|
+
|
92
|
+
raise Decouplio::Errors::InvalidErrorClassError.new(
|
93
|
+
errored_option: class_to_handle,
|
94
|
+
details: class_to_handle
|
95
|
+
)
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.validate_symbol(stp_name)
|
99
|
+
return if stp_name.is_a?(Symbol)
|
100
|
+
|
101
|
+
raise Decouplio::Errors::ResqHandlerMethodError.new(
|
102
|
+
errored_option: stp_name
|
103
|
+
)
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.validate_name(stp_name)
|
107
|
+
if Decouplio::Const::ReservedMethods::NAMES.include?(stp_name)
|
108
|
+
raise Decouplio::Errors::StepNameError.new(
|
109
|
+
errored_option: stp_name
|
110
|
+
)
|
111
|
+
end
|
112
|
+
|
113
|
+
unless stp_name.is_a?(Symbol) ||
|
114
|
+
(
|
115
|
+
(stp_name.is_a?(Class) && stp_name < Decouplio::Action) ||
|
116
|
+
(stp_name.is_a?(Class) && stp.respond_to?(:call))
|
117
|
+
)
|
118
|
+
raise Decouplio::Errors::StepDefinitionError.new(
|
119
|
+
errored_option: stp_name
|
120
|
+
)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def self.validate_on_s(stp, steps, exception_class)
|
125
|
+
return if [nil, :finish_him, :PASS, :FAIL].include?(stp.on_success)
|
126
|
+
return if steps.any? { |s| s.name == stp.on_success }
|
127
|
+
|
128
|
+
raise exception_class.new(
|
129
|
+
errored_option: { on_success: stp.on_success },
|
130
|
+
details: stp.on_success
|
131
|
+
)
|
132
|
+
end
|
133
|
+
|
134
|
+
def self.validate_on_f(stp, steps, exception_class)
|
135
|
+
return if [nil, :finish_him, :PASS, :FAIL].include?(stp.on_failure)
|
136
|
+
return if steps.any? { |s| s.name == stp.on_failure }
|
137
|
+
|
138
|
+
raise exception_class.new(
|
139
|
+
errored_option: { on_failure: stp.on_failure },
|
140
|
+
details: stp.on_failure
|
141
|
+
)
|
142
|
+
end
|
143
|
+
|
144
|
+
def self.validate_on_e(stp, steps, exception_class)
|
145
|
+
return if [nil, :finish_him, :PASS, :FAIL].include?(stp.on_error)
|
146
|
+
return if steps.any? { |s| s.name == stp.on_error }
|
147
|
+
|
148
|
+
raise exception_class.new(
|
149
|
+
errored_option: { on_error: stp.on_error },
|
150
|
+
details: stp.on_error
|
151
|
+
)
|
152
|
+
end
|
153
|
+
|
154
|
+
def self.validate_finish_him(stp, exception_class)
|
155
|
+
return if [nil, :on_success, :on_failure, :on_error].include?(stp.finish_him)
|
156
|
+
|
157
|
+
raise exception_class.new(
|
158
|
+
errored_option: { finish_him: stp.finish_him },
|
159
|
+
details: stp.finish_him
|
160
|
+
)
|
161
|
+
end
|
162
|
+
|
163
|
+
def self.validate_finish_him_for_fail(stp, exception_class)
|
164
|
+
return if [nil, true, :on_success, :on_failure, :on_error].include?(stp.finish_him)
|
165
|
+
|
166
|
+
raise exception_class.new(
|
167
|
+
errored_option: { finish_him: stp.finish_him },
|
168
|
+
details: stp.finish_him
|
169
|
+
)
|
170
|
+
end
|
171
|
+
|
172
|
+
def self.validate_finish_him_for_pass(stp, exception_class)
|
173
|
+
return if [nil, true, :on_error].include?(stp.finish_him)
|
174
|
+
|
175
|
+
raise exception_class.new(
|
176
|
+
errored_option: { finish_him: stp.finish_him },
|
177
|
+
details: stp.finish_him
|
178
|
+
)
|
179
|
+
end
|
180
|
+
|
181
|
+
def self.validate_contraversal_key(stp, exception_class)
|
182
|
+
if stp.on_success && stp.finish_him
|
183
|
+
raise exception_class.new(
|
184
|
+
errored_option: { on_success: stp.on_success, finish_him: stp.finish_him },
|
185
|
+
details: %i[on_success finish_him]
|
186
|
+
)
|
187
|
+
elsif stp.on_failure && stp.finish_him
|
188
|
+
raise exception_class.new(
|
189
|
+
errored_option: { on_failure: stp.on_failure, finish_him: stp.finish_him },
|
190
|
+
details: %i[on_failure finish_him]
|
191
|
+
)
|
192
|
+
elsif stp.on_error && stp.finish_him
|
193
|
+
raise exception_class.new(
|
194
|
+
errored_option: { on_error: stp.on_error, finish_him: stp.finish_him },
|
195
|
+
details: %i[on_error finish_him]
|
196
|
+
)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decouplio
|
4
|
+
module Steps
|
5
|
+
class BaseCondition
|
6
|
+
attr_reader :condition_method
|
7
|
+
|
8
|
+
alias name condition_method
|
9
|
+
|
10
|
+
def initialize(condition_method)
|
11
|
+
@condition_method = condition_method
|
12
|
+
end
|
13
|
+
|
14
|
+
def _add_next_steps(steps)
|
15
|
+
@perform_condition_step, @skip_condition_step = steps
|
16
|
+
end
|
17
|
+
|
18
|
+
def _add_resolvers(_); end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decouplio
|
4
|
+
module Steps
|
5
|
+
class BaseInnerAction
|
6
|
+
attr_reader :name, :on_success, :on_failure, :on_error, :finish_him, :on_error_resolver
|
7
|
+
|
8
|
+
def initialize(name, action_class, on_success, on_failure, on_error, finish_him)
|
9
|
+
@name = name
|
10
|
+
@action_class = action_class
|
11
|
+
@on_success = on_success
|
12
|
+
@on_failure = on_failure
|
13
|
+
@on_error = on_error
|
14
|
+
@finish_him = finish_him
|
15
|
+
end
|
16
|
+
|
17
|
+
def process(instance)
|
18
|
+
instance.railway_flow << @name
|
19
|
+
result = @action_class.call(
|
20
|
+
_parent_meta_store: instance.ms,
|
21
|
+
_parent_railway_flow: instance.railway_flow,
|
22
|
+
_parent_ctx: instance.ctx
|
23
|
+
)
|
24
|
+
if result.success?
|
25
|
+
instance.success = @on_success_resolver
|
26
|
+
@on_success
|
27
|
+
else
|
28
|
+
instance.success = @on_failure_resolver
|
29
|
+
@on_failure
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def _add_next_steps(steps)
|
34
|
+
@on_success, @on_failure, @on_error = steps
|
35
|
+
end
|
36
|
+
|
37
|
+
def _add_resolvers(resolvers)
|
38
|
+
@on_success_resolver, @on_failure_resolver = resolvers
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|