decouplio 1.0.0alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.circleci/config.yml +53 -0
- data/.dockerignore +12 -0
- data/.gitignore +13 -0
- data/.rspec +3 -0
- data/.rubocop.yml +106 -0
- data/.rubocop_todo.yml +147 -0
- data/.ruby-version +1 -0
- data/.vscode/settings.json +3 -0
- data/Dockerfile +12 -0
- data/Gemfile +8 -0
- data/LICENSE +21 -0
- data/LICENSE.txt +21 -0
- data/README.md +29 -0
- data/Rakefile +8 -0
- data/benchmarks/.ruby-version +1 -0
- data/benchmarks/Dockerfile +12 -0
- data/benchmarks/Gemfile +11 -0
- data/benchmarks/benchmarks.rb +527 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/decouplio.gemspec +40 -0
- data/docker-compose.yml +18 -0
- data/docs/_config.yml +1 -0
- data/docs/benchmarks.md +1 -0
- data/docs/context.md +74 -0
- data/docs/context.rb +62 -0
- data/docs/doby.md +80 -0
- data/docs/doby.rb +38 -0
- data/docs/error_store.md +347 -0
- data/docs/error_store.rb +202 -0
- data/docs/fail.md +1016 -0
- data/docs/fail.rb +762 -0
- data/docs/index.md +25 -0
- data/docs/inner_action.md +63 -0
- data/docs/inner_action.rb +43 -0
- data/docs/logic_block.md +25 -0
- data/docs/octo.md +269 -0
- data/docs/octo.rb +164 -0
- data/docs/pass.md +309 -0
- data/docs/pass.rb +213 -0
- data/docs/quick_start.md +71 -0
- data/docs/quick_start.rb +38 -0
- data/docs/resq.md +263 -0
- data/docs/resq.rb +176 -0
- data/docs/step.md +737 -0
- data/docs/step.rb +526 -0
- data/docs/step_as_a_service.md +109 -0
- data/docs/step_as_a_service.rb +77 -0
- data/docs/wrap.md +232 -0
- data/docs/wrap.rb +137 -0
- data/lib/decouplio/action.rb +111 -0
- data/lib/decouplio/composer.rb +599 -0
- data/lib/decouplio/const/colors.rb +25 -0
- data/lib/decouplio/const/reserved_methods.rb +18 -0
- data/lib/decouplio/const/results.rb +13 -0
- data/lib/decouplio/const/types.rb +173 -0
- data/lib/decouplio/const/validations/action_option_class.rb +17 -0
- data/lib/decouplio/const/validations/common.rb +14 -0
- data/lib/decouplio/const/validations/fail.rb +34 -0
- data/lib/decouplio/const/validations/logic.rb +15 -0
- data/lib/decouplio/const/validations/octo.rb +44 -0
- data/lib/decouplio/const/validations/palp.rb +20 -0
- data/lib/decouplio/const/validations/pass.rb +32 -0
- data/lib/decouplio/const/validations/resq.rb +67 -0
- data/lib/decouplio/const/validations/step.rb +35 -0
- data/lib/decouplio/const/validations/wrap.rb +41 -0
- data/lib/decouplio/default_error_handler.rb +24 -0
- data/lib/decouplio/errors/action_class_error.rb +26 -0
- data/lib/decouplio/errors/base_error.rb +30 -0
- data/lib/decouplio/errors/error_store_error.rb +17 -0
- data/lib/decouplio/errors/extra_key_for_fail_error.rb +26 -0
- data/lib/decouplio/errors/extra_key_for_octo_error.rb +26 -0
- data/lib/decouplio/errors/extra_key_for_pass_error.rb +26 -0
- data/lib/decouplio/errors/extra_key_for_resq_error.rb +29 -0
- data/lib/decouplio/errors/extra_key_for_step_error.rb +23 -0
- data/lib/decouplio/errors/extra_key_for_wrap_error.rb +23 -0
- data/lib/decouplio/errors/fail_controversial_keys_error.rb +26 -0
- data/lib/decouplio/errors/fail_finish_him_error.rb +26 -0
- data/lib/decouplio/errors/fail_is_first_step_error.rb +18 -0
- data/lib/decouplio/errors/invalid_error_class_error.rb +29 -0
- data/lib/decouplio/errors/invalid_wrap_name_error.rb +23 -0
- data/lib/decouplio/errors/logic_is_not_defined_error.rb +23 -0
- data/lib/decouplio/errors/logic_redefinition_error.rb +23 -0
- data/lib/decouplio/errors/octo_block_is_not_defined_error.rb +18 -0
- data/lib/decouplio/errors/octo_controversial_keys_error.rb +26 -0
- data/lib/decouplio/errors/options_validation_error.rb +7 -0
- data/lib/decouplio/errors/palp_block_is_not_defined_error.rb +18 -0
- data/lib/decouplio/errors/palp_is_not_defined_error.rb +26 -0
- data/lib/decouplio/errors/palp_validation_error.rb +21 -0
- data/lib/decouplio/errors/pass_controversial_keys_error.rb +26 -0
- data/lib/decouplio/errors/pass_finish_him_error.rb +26 -0
- data/lib/decouplio/errors/required_options_is_missing_for_octo_error.rb +25 -0
- data/lib/decouplio/errors/resq_definition_error.rb +21 -0
- data/lib/decouplio/errors/resq_error_class_error.rb +29 -0
- data/lib/decouplio/errors/resq_handler_method_error.rb +26 -0
- data/lib/decouplio/errors/step_controversial_keys_error.rb +26 -0
- data/lib/decouplio/errors/step_finish_him_error.rb +26 -0
- data/lib/decouplio/errors/step_is_not_defined_for_fail_error.rb +26 -0
- data/lib/decouplio/errors/step_is_not_defined_for_step_error.rb +27 -0
- data/lib/decouplio/errors/step_is_not_defined_for_wrap_error.rb +26 -0
- data/lib/decouplio/errors/step_name_error.rb +20 -0
- data/lib/decouplio/errors/wrap_block_is_not_defined_error.rb +18 -0
- data/lib/decouplio/errors/wrap_controversial_keys_error.rb +26 -0
- data/lib/decouplio/errors/wrap_finish_him_error.rb +26 -0
- data/lib/decouplio/errors/wrap_klass_method_error.rb +23 -0
- data/lib/decouplio/flow.rb +17 -0
- data/lib/decouplio/logic_dsl.rb +96 -0
- data/lib/decouplio/octo_hash_case.rb +31 -0
- data/lib/decouplio/octo_options_validator.rb +89 -0
- data/lib/decouplio/options_validator.rb +566 -0
- data/lib/decouplio/processor.rb +20 -0
- data/lib/decouplio/steps/base_resq.rb +31 -0
- data/lib/decouplio/steps/base_step.rb +16 -0
- data/lib/decouplio/steps/doby.rb +32 -0
- data/lib/decouplio/steps/fail.rb +50 -0
- data/lib/decouplio/steps/if_condition_fail.rb +28 -0
- data/lib/decouplio/steps/if_condition_pass.rb +26 -0
- data/lib/decouplio/steps/inner_action_fail.rb +55 -0
- data/lib/decouplio/steps/inner_action_pass.rb +38 -0
- data/lib/decouplio/steps/inner_action_step.rb +51 -0
- data/lib/decouplio/steps/octo.rb +22 -0
- data/lib/decouplio/steps/pass.rb +35 -0
- data/lib/decouplio/steps/resq_fail.rb +10 -0
- data/lib/decouplio/steps/resq_pass.rb +10 -0
- data/lib/decouplio/steps/service_fail.rb +51 -0
- data/lib/decouplio/steps/service_pass.rb +36 -0
- data/lib/decouplio/steps/service_step.rb +47 -0
- data/lib/decouplio/steps/step.rb +43 -0
- data/lib/decouplio/steps/unless_condition_fail.rb +28 -0
- data/lib/decouplio/steps/unless_condition_pass.rb +26 -0
- data/lib/decouplio/steps/wrap.rb +62 -0
- data/lib/decouplio/validators/condition.rb +49 -0
- data/lib/decouplio/version.rb +5 -0
- data/lib/decouplio.rb +7 -0
- metadata +266 -0
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base_error'
|
4
|
+
require_relative '../const/validations/common'
|
5
|
+
|
6
|
+
module Decouplio
|
7
|
+
module Errors
|
8
|
+
class StepNameError < Decouplio::Errors::BaseError
|
9
|
+
def template
|
10
|
+
Decouplio::Const::Validations::Common::STEP_NAME
|
11
|
+
end
|
12
|
+
|
13
|
+
def interpolation_values
|
14
|
+
[
|
15
|
+
@errored_option
|
16
|
+
]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base_error'
|
4
|
+
require_relative '../const/validations/wrap'
|
5
|
+
|
6
|
+
module Decouplio
|
7
|
+
module Errors
|
8
|
+
class WrapBlockIsNotDefinedError < Decouplio::Errors::BaseError
|
9
|
+
def template
|
10
|
+
Decouplio::Const::Validations::Wrap::NOT_DEFINED
|
11
|
+
end
|
12
|
+
|
13
|
+
def interpolation_values
|
14
|
+
[]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base_error'
|
4
|
+
require_relative '../const/validations/wrap'
|
5
|
+
|
6
|
+
module Decouplio
|
7
|
+
module Errors
|
8
|
+
class WrapControversialKeysError < Decouplio::Errors::BaseError
|
9
|
+
def template
|
10
|
+
Decouplio::Const::Validations::Wrap::VALIDATION_ERROR_MESSAGE
|
11
|
+
end
|
12
|
+
|
13
|
+
def interpolation_values
|
14
|
+
[
|
15
|
+
@errored_option,
|
16
|
+
format(
|
17
|
+
Decouplio::Const::Validations::Wrap::CONTROVERSIAL_KEYS,
|
18
|
+
*@details
|
19
|
+
),
|
20
|
+
Decouplio::Const::Validations::Wrap::ALLOWED_OPTIONS_MESSAGE,
|
21
|
+
Decouplio::Const::Validations::Wrap::MANUAL_URL
|
22
|
+
]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base_error'
|
4
|
+
require_relative '../const/validations/wrap'
|
5
|
+
|
6
|
+
module Decouplio
|
7
|
+
module Errors
|
8
|
+
class WrapFinishHimError < Decouplio::Errors::BaseError
|
9
|
+
def template
|
10
|
+
Decouplio::Const::Validations::Wrap::VALIDATION_ERROR_MESSAGE
|
11
|
+
end
|
12
|
+
|
13
|
+
def interpolation_values
|
14
|
+
[
|
15
|
+
@errored_option,
|
16
|
+
format(
|
17
|
+
Decouplio::Const::Validations::Common::WRONG_FINISH_HIM_VALUE,
|
18
|
+
@details
|
19
|
+
),
|
20
|
+
Decouplio::Const::Validations::Wrap::ALLOWED_OPTIONS_MESSAGE,
|
21
|
+
Decouplio::Const::Validations::Wrap::MANUAL_URL
|
22
|
+
]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base_error'
|
4
|
+
require_relative '../const/validations/wrap'
|
5
|
+
|
6
|
+
module Decouplio
|
7
|
+
module Errors
|
8
|
+
class WrapKlassMethodError < Decouplio::Errors::BaseError
|
9
|
+
def template
|
10
|
+
Decouplio::Const::Validations::Wrap::VALIDATION_ERROR_MESSAGE
|
11
|
+
end
|
12
|
+
|
13
|
+
def interpolation_values
|
14
|
+
[
|
15
|
+
@errored_option,
|
16
|
+
Decouplio::Const::Validations::Wrap::KLASS_AND_METHOD_PRESENCE,
|
17
|
+
Decouplio::Const::Validations::Wrap::ALLOWED_OPTIONS_MESSAGE,
|
18
|
+
Decouplio::Const::Validations::Wrap::MANUAL_URL
|
19
|
+
]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'logic_dsl'
|
4
|
+
require_relative 'composer'
|
5
|
+
|
6
|
+
module Decouplio
|
7
|
+
class Flow
|
8
|
+
def self.call(logic:, action_class:)
|
9
|
+
logic_container_raw_data = Class.new(Decouplio::LogicDsl, &logic)
|
10
|
+
|
11
|
+
Decouplio::Composer.compose(
|
12
|
+
logic_container_raw_data: logic_container_raw_data,
|
13
|
+
action_class: action_class
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'flow'
|
4
|
+
require_relative 'const/types'
|
5
|
+
require_relative 'octo_hash_case'
|
6
|
+
require_relative 'errors/options_validation_error'
|
7
|
+
require_relative 'errors/palp_validation_error'
|
8
|
+
require_relative 'errors/resq_definition_error'
|
9
|
+
require_relative 'errors/wrap_block_is_not_defined_error'
|
10
|
+
require_relative 'errors/palp_block_is_not_defined_error'
|
11
|
+
require_relative 'errors/fail_is_first_step_error'
|
12
|
+
require_relative 'errors/octo_block_is_not_defined_error'
|
13
|
+
|
14
|
+
module Decouplio
|
15
|
+
class LogicDsl
|
16
|
+
DEFAULT_WRAP_NAME = 'wrap'
|
17
|
+
|
18
|
+
class << self
|
19
|
+
attr_reader :steps, :palps
|
20
|
+
|
21
|
+
def inherited(subclass)
|
22
|
+
subclass.init_steps
|
23
|
+
end
|
24
|
+
|
25
|
+
def init_steps
|
26
|
+
@steps = []
|
27
|
+
@palps = {}
|
28
|
+
end
|
29
|
+
|
30
|
+
def step(stp, **options)
|
31
|
+
@steps << options.merge(type: Decouplio::Const::Types::STEP_TYPE, name: stp)
|
32
|
+
end
|
33
|
+
|
34
|
+
def fail(stp, **options)
|
35
|
+
raise Decouplio::Errors::FailCanNotBeTheFirstStepError if @steps.empty?
|
36
|
+
|
37
|
+
@steps << options.merge(type: Decouplio::Const::Types::FAIL_TYPE, name: stp)
|
38
|
+
end
|
39
|
+
|
40
|
+
def pass(stp, **options)
|
41
|
+
@steps << options.merge(type: Decouplio::Const::Types::PASS_TYPE, name: stp)
|
42
|
+
end
|
43
|
+
|
44
|
+
def octo(octo_name, **options, &block)
|
45
|
+
raise Decouplio::Errors::OctoBlockIsNotDefinedError unless block_given?
|
46
|
+
|
47
|
+
hash_case = Class.new(Decouplio::OctoHashCase, &block).hash_case
|
48
|
+
|
49
|
+
raise Decouplio::Errors::OctoBlockIsNotDefinedError if hash_case.empty?
|
50
|
+
|
51
|
+
options[:hash_case] = hash_case
|
52
|
+
@steps << options.merge(type: Decouplio::Const::Types::OCTO_TYPE, name: octo_name)
|
53
|
+
end
|
54
|
+
|
55
|
+
def palp(palp_name, **options, &block)
|
56
|
+
raise Decouplio::Errors::PalpBlockIsNotDefinedError unless block_given?
|
57
|
+
|
58
|
+
options.empty? || raise(Decouplio::Errors::PalpValidationError)
|
59
|
+
|
60
|
+
@palps[palp_name] = Class.new(self, &block)
|
61
|
+
end
|
62
|
+
|
63
|
+
def resq(name = :resq, **options)
|
64
|
+
unless Decouplio::Const::Types::MAIN_FLOW_TYPES.include?(@steps.last&.[](:type))
|
65
|
+
raise Decouplio::Errors::ResqDefinitionError
|
66
|
+
end
|
67
|
+
|
68
|
+
@steps << {
|
69
|
+
name: name,
|
70
|
+
type: Decouplio::Const::Types::RESQ_TYPE,
|
71
|
+
step_to_resq: @steps.delete(@steps.last),
|
72
|
+
handler_hash: options
|
73
|
+
}
|
74
|
+
end
|
75
|
+
|
76
|
+
def wrap(name = nil, **options, &block)
|
77
|
+
raise Decouplio::Errors::WrapBlockIsNotDefinedError unless block_given?
|
78
|
+
|
79
|
+
@steps << options.merge(
|
80
|
+
type: Decouplio::Const::Types::WRAP_TYPE,
|
81
|
+
name: name,
|
82
|
+
wrap_flow: block
|
83
|
+
)
|
84
|
+
end
|
85
|
+
|
86
|
+
def doby(doby_class, **options)
|
87
|
+
@steps << {
|
88
|
+
type: Decouplio::Const::Types::DOBY_TYPE,
|
89
|
+
name: doby_class.name.to_sym,
|
90
|
+
doby_class: doby_class,
|
91
|
+
doby_options: options
|
92
|
+
}
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'octo_options_validator'
|
4
|
+
|
5
|
+
module Decouplio
|
6
|
+
class OctoHashCase
|
7
|
+
class << self
|
8
|
+
attr_reader :hash_case
|
9
|
+
|
10
|
+
def inherited(subclass)
|
11
|
+
subclass.init_hash_case
|
12
|
+
super(subclass)
|
13
|
+
end
|
14
|
+
|
15
|
+
def init_hash_case
|
16
|
+
@hash_case = {}
|
17
|
+
end
|
18
|
+
|
19
|
+
def on(strategy_flow, **options)
|
20
|
+
validate_options(options)
|
21
|
+
@hash_case[strategy_flow] = options
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def validate_options(options)
|
27
|
+
OctoOptionsValidator.call(options: options)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'errors/options_validation_error'
|
4
|
+
|
5
|
+
module Decouplio
|
6
|
+
class OctoOptionsValidator
|
7
|
+
def self.call(options:)
|
8
|
+
new(options: options).call
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(options:)
|
12
|
+
@options = options
|
13
|
+
end
|
14
|
+
|
15
|
+
def call
|
16
|
+
validate_option_keys
|
17
|
+
validate_option_count
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def validate_option_keys
|
23
|
+
extra_options = (@options.keys - ON_ALLOWED_OPTIONS)
|
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
|
38
|
+
|
39
|
+
def validate_option_count
|
40
|
+
return if @options.keys.size == 1
|
41
|
+
|
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
|
+
)
|
53
|
+
end
|
54
|
+
|
55
|
+
def raise_validation_error(message)
|
56
|
+
raise Decouplio::Errors::OptionsValidationError, message
|
57
|
+
end
|
58
|
+
|
59
|
+
def compose_message(message, *interpolation_params)
|
60
|
+
message % interpolation_params
|
61
|
+
end
|
62
|
+
|
63
|
+
ALLOWED_OPTIONS = %i[palp step].freeze
|
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'
|
88
|
+
end
|
89
|
+
end
|