flow_object 0.2.0 → 0.3.0
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 +5 -5
- data/.gitignore +0 -0
- data/.rspec +0 -0
- data/.rubocop.yml +78 -0
- data/.ruby-version +1 -1
- data/.travis.yml +0 -0
- data/CODE_OF_CONDUCT.md +0 -0
- data/Gemfile +4 -2
- data/Gemfile.lock +35 -8
- data/LICENSE.txt +0 -0
- data/README.md +0 -0
- data/Rakefile +5 -3
- data/bin/console +4 -3
- data/flow_object.gemspec +9 -5
- data/lib/flow_object/base.rb +76 -88
- data/lib/flow_object/callbacks.rb +73 -0
- data/lib/flow_object/runner.rb +44 -0
- data/lib/flow_object/version.rb +3 -1
- data/lib/flow_object.rb +5 -1
- metadata +38 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 0612652b790e12566782ac7aede6677315ae05c773ca066afee9b39fd9ac4335
|
|
4
|
+
data.tar.gz: ebf9b7de4d50e5003f83197f87a3557d831ee20c040947dedaf421d2c3ff73c6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8f9a6e6cdd8aadba78d66c68a9014fe868927bf6b3f877f34650847162e6dfbe541a69dd779002e09f2799faab8f27799554777429c49d63afc8029318760eb4
|
|
7
|
+
data.tar.gz: def73238080897d12e9d5d1c2aa501872fb9b0e5e6a770b15cb197108b6edd95b5bfa4d78a7a8dc6891a3c20ed6080ce0d7ecfc4e37a3a642ead55e8302eace2
|
data/.gitignore
CHANGED
|
File without changes
|
data/.rspec
CHANGED
|
File without changes
|
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
AllCops:
|
|
2
|
+
NewCops: enable
|
|
3
|
+
Exclude:
|
|
4
|
+
- flow_object.gemspec
|
|
5
|
+
Gemspec/DateAssignment: # (new in 1.10)
|
|
6
|
+
Enabled: true
|
|
7
|
+
Layout/SpaceBeforeBrackets: # (new in 1.7)
|
|
8
|
+
Enabled: true
|
|
9
|
+
Lint/AmbiguousAssignment: # (new in 1.7)
|
|
10
|
+
Enabled: true
|
|
11
|
+
Lint/DeprecatedConstants: # (new in 1.8)
|
|
12
|
+
Enabled: true
|
|
13
|
+
Lint/DuplicateBranch: # (new in 1.3)
|
|
14
|
+
Enabled: true
|
|
15
|
+
Lint/DuplicateRegexpCharacterClassElement: # (new in 1.1)
|
|
16
|
+
Enabled: true
|
|
17
|
+
Lint/EmptyBlock: # (new in 1.1)
|
|
18
|
+
Enabled: true
|
|
19
|
+
Exclude:
|
|
20
|
+
- lib/flow_object/callbacks.rb
|
|
21
|
+
Lint/EmptyClass: # (new in 1.3)
|
|
22
|
+
Enabled: true
|
|
23
|
+
Exclude:
|
|
24
|
+
- spec/**/*.rb
|
|
25
|
+
Lint/LambdaWithoutLiteralBlock: # (new in 1.8)
|
|
26
|
+
Enabled: true
|
|
27
|
+
Lint/NoReturnInBeginEndBlocks: # (new in 1.2)
|
|
28
|
+
Enabled: true
|
|
29
|
+
Lint/NumberedParameterAssignment: # (new in 1.9)
|
|
30
|
+
Enabled: true
|
|
31
|
+
Lint/OrAssignmentToConstant: # (new in 1.9)
|
|
32
|
+
Enabled: true
|
|
33
|
+
Lint/RedundantDirGlobSort: # (new in 1.8)
|
|
34
|
+
Enabled: true
|
|
35
|
+
Lint/SymbolConversion: # (new in 1.9)
|
|
36
|
+
Enabled: true
|
|
37
|
+
Lint/ToEnumArguments: # (new in 1.1)
|
|
38
|
+
Enabled: true
|
|
39
|
+
Lint/TripleQuotes: # (new in 1.9)
|
|
40
|
+
Enabled: true
|
|
41
|
+
Lint/UnexpectedBlockArity: # (new in 1.5)
|
|
42
|
+
Enabled: true
|
|
43
|
+
Lint/UnmodifiedReduceAccumulator: # (new in 1.1)
|
|
44
|
+
Enabled: true
|
|
45
|
+
Style/ArgumentsForwarding: # (new in 1.1)
|
|
46
|
+
Enabled: true
|
|
47
|
+
Style/CollectionCompact: # (new in 1.2)
|
|
48
|
+
Enabled: true
|
|
49
|
+
Style/DocumentDynamicEvalDefinition: # (new in 1.1)
|
|
50
|
+
Enabled: true
|
|
51
|
+
Style/EndlessMethod: # (new in 1.8)
|
|
52
|
+
Enabled: true
|
|
53
|
+
Style/HashConversion: # (new in 1.10)
|
|
54
|
+
Enabled: true
|
|
55
|
+
Style/HashExcept: # (new in 1.7)
|
|
56
|
+
Enabled: true
|
|
57
|
+
Style/IfWithBooleanLiteralBranches: # (new in 1.9)
|
|
58
|
+
Enabled: true
|
|
59
|
+
Style/NegatedIfElseCondition: # (new in 1.2)
|
|
60
|
+
Enabled: true
|
|
61
|
+
Style/NilLambda: # (new in 1.3)
|
|
62
|
+
Enabled: true
|
|
63
|
+
Style/RedundantArgument: # (new in 1.4)
|
|
64
|
+
Enabled: true
|
|
65
|
+
Style/StringChars: # (new in 1.12)
|
|
66
|
+
Enabled: true
|
|
67
|
+
Style/SwapValues: # (new in 1.1)
|
|
68
|
+
Enabled: true
|
|
69
|
+
Metrics/BlockLength:
|
|
70
|
+
Exclude:
|
|
71
|
+
- spec/**/*.rb
|
|
72
|
+
Naming/MethodParameterName:
|
|
73
|
+
Exclude:
|
|
74
|
+
- spec/**/*.rb
|
|
75
|
+
Style/Semicolon:
|
|
76
|
+
Exclude:
|
|
77
|
+
- spec/**/*.rb
|
|
78
|
+
|
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.
|
|
1
|
+
2.4.0
|
data/.travis.yml
CHANGED
|
File without changes
|
data/CODE_OF_CONDUCT.md
CHANGED
|
File without changes
|
data/Gemfile
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
source 'https://rubygems.org'
|
|
4
|
+
|
|
5
|
+
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
|
4
6
|
|
|
5
7
|
# Specify your gem's dependencies in flow_object.gemspec
|
|
6
8
|
gemspec
|
data/Gemfile.lock
CHANGED
|
@@ -1,23 +1,31 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
flow_object (0.
|
|
5
|
-
|
|
4
|
+
flow_object (0.3.0)
|
|
5
|
+
hospodar (~> 1)
|
|
6
6
|
|
|
7
7
|
GEM
|
|
8
8
|
remote: https://rubygems.org/
|
|
9
9
|
specs:
|
|
10
|
+
ast (2.4.2)
|
|
10
11
|
coderay (1.1.3)
|
|
11
12
|
diff-lcs (1.4.4)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
docile (1.3.5)
|
|
14
|
+
dry-inflector (0.2.0)
|
|
15
|
+
hospodar (1.0.1)
|
|
16
|
+
json (2.5.1)
|
|
16
17
|
method_source (1.0.0)
|
|
18
|
+
dry-inflector (~> 0.1)
|
|
19
|
+
parallel (1.20.1)
|
|
20
|
+
parser (3.0.2.0)
|
|
21
|
+
ast (~> 2.4.1)
|
|
17
22
|
pry (0.13.1)
|
|
18
23
|
coderay (~> 1.1)
|
|
19
24
|
method_source (~> 1.0)
|
|
25
|
+
rainbow (3.0.0)
|
|
20
26
|
rake (10.5.0)
|
|
27
|
+
regexp_parser (2.1.1)
|
|
28
|
+
rexml (3.2.5)
|
|
21
29
|
rspec (3.9.0)
|
|
22
30
|
rspec-core (~> 3.9.0)
|
|
23
31
|
rspec-expectations (~> 3.9.0)
|
|
@@ -33,7 +41,24 @@ GEM
|
|
|
33
41
|
rspec-support (3.9.3)
|
|
34
42
|
rspec_vars_helper (0.1.0)
|
|
35
43
|
rspec (>= 2.4)
|
|
36
|
-
|
|
44
|
+
rubocop (1.12.1)
|
|
45
|
+
parallel (~> 1.10)
|
|
46
|
+
parser (>= 3.0.0.0)
|
|
47
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
48
|
+
regexp_parser (>= 1.8, < 3.0)
|
|
49
|
+
rexml
|
|
50
|
+
rubocop-ast (>= 1.2.0, < 2.0)
|
|
51
|
+
ruby-progressbar (~> 1.7)
|
|
52
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
|
53
|
+
rubocop-ast (1.4.1)
|
|
54
|
+
parser (>= 2.7.1.5)
|
|
55
|
+
ruby-progressbar (1.11.0)
|
|
56
|
+
simplecov (0.17.0)
|
|
57
|
+
docile (~> 1.1)
|
|
58
|
+
json (>= 1.8, < 3)
|
|
59
|
+
simplecov-html (~> 0.10.0)
|
|
60
|
+
simplecov-html (0.10.2)
|
|
61
|
+
unicode-display_width (2.0.0)
|
|
37
62
|
|
|
38
63
|
PLATFORMS
|
|
39
64
|
ruby
|
|
@@ -45,6 +70,8 @@ DEPENDENCIES
|
|
|
45
70
|
rake (~> 10.0)
|
|
46
71
|
rspec (~> 3.0)
|
|
47
72
|
rspec_vars_helper (~> 0.1)
|
|
73
|
+
rubocop
|
|
74
|
+
simplecov (= 0.17)
|
|
48
75
|
|
|
49
76
|
BUNDLED WITH
|
|
50
|
-
1.17.
|
|
77
|
+
1.17.3
|
data/LICENSE.txt
CHANGED
|
File without changes
|
data/README.md
CHANGED
|
File without changes
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
4
|
+
require 'bundler/setup'
|
|
5
|
+
require 'flow_object'
|
|
5
6
|
|
|
6
7
|
# You can add fixtures and/or initialization code here to make experimenting
|
|
7
8
|
# with your gem easier. You can also use a different console, if you like.
|
|
8
9
|
|
|
9
10
|
# (If you use this, don't forget to add pry to your Gemfile!)
|
|
10
|
-
require
|
|
11
|
+
require 'pry'
|
|
11
12
|
Pry.start
|
|
12
13
|
|
|
13
14
|
# require "irb"
|
data/flow_object.gemspec
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
|
|
2
|
-
lib = File.expand_path(
|
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
5
|
require 'flow_object/version'
|
|
5
6
|
|
|
@@ -9,10 +10,11 @@ Gem::Specification.new do |spec|
|
|
|
9
10
|
spec.authors = ['Andrii Baran']
|
|
10
11
|
spec.email = ['andriy.baran.v@gmail.com']
|
|
11
12
|
|
|
12
|
-
spec.summary =
|
|
13
|
-
spec.description =
|
|
13
|
+
spec.summary = 'Create objects for storing application flows'
|
|
14
|
+
spec.description = 'General purpose software library designed for happiness'
|
|
14
15
|
spec.homepage = 'https://github.com/andriy-baran/flow_object'
|
|
15
16
|
spec.license = 'MIT'
|
|
17
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.4.0')
|
|
16
18
|
|
|
17
19
|
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
|
18
20
|
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
|
@@ -29,18 +31,20 @@ Gem::Specification.new do |spec|
|
|
|
29
31
|
|
|
30
32
|
# Specify which files should be added to the gem when it is released.
|
|
31
33
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
32
|
-
spec.files
|
|
34
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
33
35
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
34
36
|
end
|
|
35
37
|
spec.bindir = 'exe'
|
|
36
38
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
37
39
|
spec.require_paths = ['lib']
|
|
38
40
|
|
|
39
|
-
spec.add_dependency '
|
|
41
|
+
spec.add_dependency 'hospodar', '~> 1'
|
|
40
42
|
|
|
41
43
|
spec.add_development_dependency 'bundler', '~> 1.17'
|
|
42
44
|
spec.add_development_dependency 'pry'
|
|
43
45
|
spec.add_development_dependency 'rake', '~> 10.0'
|
|
44
46
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
|
45
47
|
spec.add_development_dependency 'rspec_vars_helper', '~> 0.1'
|
|
48
|
+
spec.add_development_dependency 'rubocop'
|
|
49
|
+
spec.add_development_dependency 'simplecov', '0.17'
|
|
46
50
|
end
|
data/lib/flow_object/base.rb
CHANGED
|
@@ -1,20 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module FlowObject
|
|
4
|
+
# Provides DSL for flows definitions
|
|
2
5
|
class Base
|
|
3
|
-
include
|
|
4
|
-
include
|
|
6
|
+
include Hospodar
|
|
7
|
+
include Hospodar::Builder
|
|
5
8
|
|
|
6
|
-
|
|
9
|
+
produces :stages, :inputs, :outputs
|
|
7
10
|
|
|
8
11
|
class << self
|
|
9
12
|
attr_reader :in, :out, :initial_values
|
|
10
13
|
end
|
|
11
14
|
|
|
12
|
-
|
|
15
|
+
extend Forwardable
|
|
16
|
+
def_delegators :callbacks, :output_initialized
|
|
17
|
+
|
|
18
|
+
attr_reader :output, :callbacks
|
|
13
19
|
|
|
14
|
-
def initialize(
|
|
15
|
-
@
|
|
16
|
-
@
|
|
17
|
-
|
|
20
|
+
def initialize(flow, callbacks, step_name = :flow)
|
|
21
|
+
@output = self.class.send(:fo_wrap_output)
|
|
22
|
+
@callbacks = callbacks
|
|
23
|
+
Hospodar::Builder.def_accessor(step_name, on: @output, to: flow, delegate: true)
|
|
24
|
+
output_initialized.call(@output)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def on_exception(exception = nil)
|
|
28
|
+
# NOOP
|
|
18
29
|
end
|
|
19
30
|
|
|
20
31
|
def on_failure(failed_step = nil)
|
|
@@ -25,16 +36,12 @@ module FlowObject
|
|
|
25
36
|
# NOOP
|
|
26
37
|
end
|
|
27
38
|
|
|
39
|
+
# Class-level interface for flow objects
|
|
28
40
|
module ClassMethods
|
|
29
41
|
def inherited(subclass)
|
|
30
42
|
super
|
|
31
43
|
subclass.from(self.in)
|
|
32
|
-
subclass.to(
|
|
33
|
-
subclass.after_input_initialize(&self.after_input_initialize)
|
|
34
|
-
subclass.after_flow_initialize(&self.after_flow_initialize)
|
|
35
|
-
subclass.after_input_check(&self.after_input_check)
|
|
36
|
-
subclass.after_flow_check(&self.after_flow_check)
|
|
37
|
-
subclass.after_output_initialize(&self.after_output_initialize)
|
|
44
|
+
subclass.to(out)
|
|
38
45
|
end
|
|
39
46
|
|
|
40
47
|
def from(input)
|
|
@@ -52,115 +59,96 @@ module FlowObject
|
|
|
52
59
|
self
|
|
53
60
|
end
|
|
54
61
|
|
|
55
|
-
def call(flow: :main)
|
|
56
|
-
|
|
62
|
+
def call(flow: :main, &block)
|
|
63
|
+
fo_resolve(fo_process(flow: flow, &block))
|
|
57
64
|
end
|
|
58
65
|
|
|
59
66
|
def flow(name = :main, &block)
|
|
60
|
-
wrap(name, delegate: true, &block)
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def after_input_initialize(&block)
|
|
64
|
-
block_given? ? @after_input_initialize = block : @after_input_initialize
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def after_flow_initialize(&block)
|
|
68
|
-
block_given? ? @after_flow_initialize = block : @after_flow_initialize
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def after_input_check(&block)
|
|
72
|
-
block_given? ? @after_input_check = block : @after_input_check
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
def after_flow_check(&block)
|
|
76
|
-
block_given? ? @after_flow_check = block : @after_flow_check
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def after_output_initialize(&block)
|
|
80
|
-
block_given? ? @after_output_initialize = block : @after_output_initialize
|
|
67
|
+
wrap(name, delegate: true, on_exception: :halt, &block)
|
|
81
68
|
end
|
|
82
69
|
|
|
83
70
|
private
|
|
84
71
|
|
|
85
|
-
def halt_flow?(
|
|
72
|
+
def halt_flow?(_object, _id)
|
|
86
73
|
false
|
|
87
74
|
end
|
|
88
75
|
|
|
89
|
-
def
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
proc{ failure = true },
|
|
95
|
-
after_input_initialize,
|
|
96
|
-
after_flow_initialize)
|
|
97
|
-
after_flow_check.call(cascade.public_send(step_name)) if after_flow_check
|
|
98
|
-
[cascade, step_name, failure]
|
|
76
|
+
def fo_process(flow: :main, &block)
|
|
77
|
+
plan = fo_build_flow(flow, self.in, :input, fo_wrap_input)
|
|
78
|
+
callbacks = Callbacks.new(@callbacks_allowlist)
|
|
79
|
+
block.call(callbacks) if block_given?
|
|
80
|
+
Runner.new(plan, callbacks, method(:halt_flow?)).execute_plan
|
|
99
81
|
end
|
|
100
82
|
|
|
101
|
-
def
|
|
102
|
-
|
|
83
|
+
def fo_build_flow(flow, step_name, group, object)
|
|
84
|
+
plan = send(:"hospodar_perform_planing_for_#{flow}", object, step_name, group)
|
|
85
|
+
@callbacks_allowlist = plan.map(&:last).map(&:to_sym) + [:"#{out}_output"]
|
|
86
|
+
send(:"hospodar_execute_plan_for_#{flow}", plan)
|
|
103
87
|
end
|
|
104
88
|
|
|
105
|
-
def
|
|
106
|
-
step_index = 0
|
|
107
|
-
plan.call do |object, id|
|
|
108
|
-
on_input.call(object) if on_input && id.group == :input
|
|
109
|
-
on_flow.call(object) if step_index == 1 && on_flow && id.group == :stage
|
|
110
|
-
on_step.call(object, id)
|
|
111
|
-
step_index += 1
|
|
112
|
-
if halt_flow?(object, id)
|
|
113
|
-
on_failure.call(object, id)
|
|
114
|
-
throw :halt
|
|
115
|
-
end
|
|
116
|
-
after_input_check.call(object) if after_input_check && id.group == :input
|
|
117
|
-
end
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
def __fo_wrap_input__
|
|
89
|
+
def fo_wrap_input
|
|
121
90
|
return initial_values if self.in.nil?
|
|
91
|
+
|
|
122
92
|
input_class = public_send(:"#{self.in}_input_class")
|
|
123
93
|
return initial_values if input_class.nil?
|
|
94
|
+
|
|
124
95
|
public_send(:"new_#{self.in}_input_instance", *initial_values)
|
|
125
96
|
end
|
|
126
97
|
|
|
127
|
-
def
|
|
98
|
+
def fo_wrap_output
|
|
128
99
|
# rescue NoMethodError => ex
|
|
129
100
|
# "You have not define output class. Please add `output :#{self.out}`"
|
|
130
|
-
return if
|
|
131
|
-
return unless
|
|
132
|
-
|
|
101
|
+
return if out.nil?
|
|
102
|
+
return unless respond_to?(:"#{out}_output_class")
|
|
103
|
+
|
|
104
|
+
output_class = public_send(:"#{out}_output_class")
|
|
133
105
|
return if output_class.nil?
|
|
134
|
-
|
|
106
|
+
|
|
107
|
+
public_send(:"new_#{out}_output_instance")
|
|
135
108
|
end
|
|
136
109
|
|
|
137
|
-
def
|
|
138
|
-
new(
|
|
139
|
-
if
|
|
140
|
-
|
|
110
|
+
def fo_resolve(runner)
|
|
111
|
+
new(runner.flow.public_send(runner.step_name), runner.callbacks, runner.step_name).tap do |handler|
|
|
112
|
+
if runner.flow.exceptional?
|
|
113
|
+
fo_notify_exception(handler, runner.flow.exception)
|
|
114
|
+
elsif runner.failure
|
|
115
|
+
fo_notify_error(handler, runner.step_name)
|
|
141
116
|
else
|
|
142
|
-
|
|
117
|
+
fo_notify_success(handler)
|
|
143
118
|
end
|
|
144
119
|
end
|
|
145
120
|
end
|
|
146
121
|
|
|
147
|
-
def
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
122
|
+
def fo_notify_exception(handler, exception)
|
|
123
|
+
callback = :"on_#{exception.step_id.title}_exception"
|
|
124
|
+
if handler.output.respond_to?(callback)
|
|
125
|
+
handler.output.public_send(callback, exception)
|
|
126
|
+
elsif handler.output.respond_to?(:on_exception)
|
|
127
|
+
handler.output.on_exception(exception)
|
|
128
|
+
elsif handler.respond_to?(callback)
|
|
129
|
+
handler.public_send(callback, exception)
|
|
130
|
+
else
|
|
131
|
+
handler.on_exception(exception)
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def fo_notify_error(handler, step)
|
|
136
|
+
if handler.output.respond_to?(:"on_#{step}_failure")
|
|
137
|
+
handler.output.public_send(:"on_#{step}_failure")
|
|
138
|
+
elsif handler.output.respond_to?(:on_failure)
|
|
139
|
+
handler.output.on_failure(step)
|
|
140
|
+
elsif handler.respond_to?(:"on_#{step}_failure")
|
|
141
|
+
handler.public_send(:"on_#{step}_failure")
|
|
154
142
|
else
|
|
155
|
-
|
|
143
|
+
handler.on_failure(step)
|
|
156
144
|
end
|
|
157
145
|
end
|
|
158
146
|
|
|
159
|
-
def
|
|
160
|
-
if
|
|
161
|
-
|
|
147
|
+
def fo_notify_success(handler)
|
|
148
|
+
if handler.output.respond_to?(:on_success)
|
|
149
|
+
handler.output.on_success
|
|
162
150
|
else
|
|
163
|
-
|
|
151
|
+
handler.on_success
|
|
164
152
|
end
|
|
165
153
|
end
|
|
166
154
|
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module FlowObject
|
|
4
|
+
# Storage for users callbacks
|
|
5
|
+
class Callbacks
|
|
6
|
+
NOOP = proc {}.freeze
|
|
7
|
+
|
|
8
|
+
Iteration = Struct.new(:idx, :type, :list_size) do
|
|
9
|
+
def output_checked?
|
|
10
|
+
output? && checked?
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def generic_alias
|
|
14
|
+
return :"input_#{type}" if input?
|
|
15
|
+
return :flow_initialized if flow_initialized?
|
|
16
|
+
return :flow_checked if flow_checked?
|
|
17
|
+
return :output_initialized if output_initialized?
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def flow_initialized?
|
|
23
|
+
idx == 1 && initialized?
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def flow_checked?
|
|
27
|
+
idx == list_size - 2 && checked?
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def output_initialized?
|
|
31
|
+
output? && initialized?
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def input?
|
|
35
|
+
idx.zero?
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def initialized?
|
|
39
|
+
type == :initialized
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def checked?
|
|
43
|
+
type == :checked
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def output?
|
|
47
|
+
idx == list_size - 1
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def initialize(list)
|
|
52
|
+
@callbacks = Hash.new { |hash, key| hash[key] = NOOP }
|
|
53
|
+
each_callback(list) do |callback, callback_alias|
|
|
54
|
+
define_singleton_method(callback) do |&block|
|
|
55
|
+
block.nil? ? @callbacks[callback] : @callbacks[callback] = block
|
|
56
|
+
end
|
|
57
|
+
singleton_class.class_eval { alias_method(callback_alias, callback) } if callback_alias
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
private
|
|
62
|
+
|
|
63
|
+
def each_callback(list)
|
|
64
|
+
list_size = list.size
|
|
65
|
+
list.each.with_index do |method_name, idx|
|
|
66
|
+
{ initialized: :"#{method_name}_initialized", checked: :"#{method_name}_checked" }.each do |type, callback|
|
|
67
|
+
callback_alias = Iteration.new(idx, type, list_size).generic_alias
|
|
68
|
+
yield(callback, callback_alias)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module FlowObject
|
|
4
|
+
# Triggers flow execution and users callbacks
|
|
5
|
+
class Runner
|
|
6
|
+
attr_reader :step_name, :failure, :flow, :callbacks
|
|
7
|
+
|
|
8
|
+
def initialize(plan, callbacks, halt_if_proc)
|
|
9
|
+
@plan = plan
|
|
10
|
+
@flow = flow
|
|
11
|
+
@failure = false
|
|
12
|
+
@step_name = nil
|
|
13
|
+
@callbacks = callbacks
|
|
14
|
+
@halt_if_proc = halt_if_proc
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def execute_plan
|
|
18
|
+
@flow = flow_builder.call
|
|
19
|
+
self
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def flow_builder
|
|
25
|
+
@plan.do_until do |object, id|
|
|
26
|
+
@step_name = id.title
|
|
27
|
+
after_initialize(object, id)
|
|
28
|
+
@failure = @halt_if_proc.call(object, id)
|
|
29
|
+
next true if @failure
|
|
30
|
+
|
|
31
|
+
after_check(object, id)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def after_initialize(object, id)
|
|
36
|
+
@callbacks.public_send(:"#{id}_initialized").call(object)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def after_check(object, id)
|
|
40
|
+
@callbacks.public_send(:"#{id}_checked").call(object)
|
|
41
|
+
false
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
data/lib/flow_object/version.rb
CHANGED
data/lib/flow_object.rb
CHANGED
metadata
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: flow_object
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrii Baran
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2021-
|
|
11
|
+
date: 2021-11-27 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
|
-
name:
|
|
14
|
+
name: hospodar
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
17
|
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version:
|
|
19
|
+
version: '1'
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version:
|
|
26
|
+
version: '1'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: bundler
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -94,6 +94,34 @@ dependencies:
|
|
|
94
94
|
- - "~>"
|
|
95
95
|
- !ruby/object:Gem::Version
|
|
96
96
|
version: '0.1'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: rubocop
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - ">="
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '0'
|
|
104
|
+
type: :development
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - ">="
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '0'
|
|
111
|
+
- !ruby/object:Gem::Dependency
|
|
112
|
+
name: simplecov
|
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
|
114
|
+
requirements:
|
|
115
|
+
- - '='
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
version: '0.17'
|
|
118
|
+
type: :development
|
|
119
|
+
prerelease: false
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - '='
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: '0.17'
|
|
97
125
|
description: General purpose software library designed for happiness
|
|
98
126
|
email:
|
|
99
127
|
- andriy.baran.v@gmail.com
|
|
@@ -103,6 +131,7 @@ extra_rdoc_files: []
|
|
|
103
131
|
files:
|
|
104
132
|
- ".gitignore"
|
|
105
133
|
- ".rspec"
|
|
134
|
+
- ".rubocop.yml"
|
|
106
135
|
- ".ruby-version"
|
|
107
136
|
- ".travis.yml"
|
|
108
137
|
- CODE_OF_CONDUCT.md
|
|
@@ -116,6 +145,8 @@ files:
|
|
|
116
145
|
- flow_object.gemspec
|
|
117
146
|
- lib/flow_object.rb
|
|
118
147
|
- lib/flow_object/base.rb
|
|
148
|
+
- lib/flow_object/callbacks.rb
|
|
149
|
+
- lib/flow_object/runner.rb
|
|
119
150
|
- lib/flow_object/version.rb
|
|
120
151
|
homepage: https://github.com/andriy-baran/flow_object
|
|
121
152
|
licenses:
|
|
@@ -132,15 +163,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
132
163
|
requirements:
|
|
133
164
|
- - ">="
|
|
134
165
|
- !ruby/object:Gem::Version
|
|
135
|
-
version:
|
|
166
|
+
version: 2.4.0
|
|
136
167
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
137
168
|
requirements:
|
|
138
169
|
- - ">="
|
|
139
170
|
- !ruby/object:Gem::Version
|
|
140
171
|
version: '0'
|
|
141
172
|
requirements: []
|
|
142
|
-
|
|
143
|
-
rubygems_version: 2.5.1
|
|
173
|
+
rubygems_version: 3.2.30
|
|
144
174
|
signing_key:
|
|
145
175
|
specification_version: 4
|
|
146
176
|
summary: Create objects for storing application flows
|