w_flow 0.1.0 → 0.10.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 +4 -4
- data/.gitignore +2 -0
- data/.travis.yml +1 -0
- data/README.md +36 -8
- data/lib/w_flow/configuration.rb +29 -0
- data/lib/w_flow/flow.rb +12 -26
- data/lib/w_flow/node.rb +14 -0
- data/lib/w_flow/node_process.rb +58 -0
- data/lib/w_flow/process.rb +47 -25
- data/lib/w_flow/report.rb +10 -0
- data/lib/w_flow/supervisor.rb +118 -0
- data/lib/w_flow/version.rb +1 -1
- data/lib/w_flow.rb +19 -5
- data/w_flow.gemspec +3 -1
- metadata +9 -6
- data/lib/w_flow/exceptions.rb +0 -7
- data/lib/w_flow/process_node.rb +0 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 542302c862a2fd32f275fdcc7ef118fe28d782df
|
4
|
+
data.tar.gz: cdffac74ea395e3869a48dd1d92e6f0381fba377
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b1f200b2a3de539ea4328ddc6be29cbf988b784b07c5ca5cd4c1b6bc2622d47613296a66c1d2279952be962b8002a6ae05db9fd0af9ad23b654ee57cbc1c2ece
|
7
|
+
data.tar.gz: ded155f14d82e06a0c437d9b6ef8f273c5b958b3921604302dd146588605e15178ebef0b22a7dda8cfab98007c408a26cd2fe75b601bf34edc00ef07ad8d39ef
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,16 +1,26 @@
|
|
1
1
|
# WFlow
|
2
2
|
|
3
|
-
[](http://badge.fury.io/rb/w_flow)
|
4
|
+
[](https://travis-ci.org/junhanamaki/w_flow)
|
5
|
+
[](https://codeclimate.com/github/junhanamaki/w_flow)
|
6
|
+
[](https://codeclimate.com/github/junhanamaki/w_flow)
|
7
|
+
[](https://gemnasium.com/junhanamaki/w_flow)
|
8
|
+
|
9
|
+
WFlow aims to help on designing workflows based on [Single
|
10
|
+
Responsibility Principle](http://en.wikipedia.org/wiki/Single_responsibility_principle). WFlow
|
11
|
+
proposes to achieve this by providing tools to build classes where each are responsible for a task
|
12
|
+
and one task only, and by providing tools to compose these classes.
|
13
|
+
|
14
|
+
Word of appreciation for [usecasing](https://github.com/tdantas/usecasing),
|
15
|
+
[interactor](https://github.com/collectiveidea/interactor) and
|
16
|
+
[rest_my_case](https://github.com/goncalvesjoao/rest_my_case) that served as
|
17
|
+
inspiration for this gem.
|
8
18
|
|
9
19
|
## Dependencies
|
10
20
|
|
11
21
|
Tested with:
|
12
22
|
|
13
|
-
* ruby 2.2.0, 2.1.1, 2.0.0
|
23
|
+
* ruby 2.2.1, 2.2.0, 2.1.1, 2.0.0
|
14
24
|
|
15
25
|
## Installation
|
16
26
|
|
@@ -30,11 +40,29 @@ Or install it yourself as:
|
|
30
40
|
|
31
41
|
## Usage
|
32
42
|
|
33
|
-
|
43
|
+
On its most simplest form a task (in WFlow called a Process) is something like this:
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
class SaveUser
|
47
|
+
include WFlow::Process
|
48
|
+
|
49
|
+
def perform
|
50
|
+
# arguments passed to run will be under flow.data
|
51
|
+
flow.data.user.save
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# run process, it will return a report object
|
56
|
+
report = SaveUser.run(user: current_user)
|
57
|
+
|
58
|
+
report.data.success?
|
59
|
+
```
|
60
|
+
|
61
|
+
|
34
62
|
|
35
63
|
## Contributing
|
36
64
|
|
37
|
-
1. Fork it ( https://github.com/
|
65
|
+
1. Fork it ( https://github.com/junhanamaki/w_flow/fork )
|
38
66
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
39
67
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
40
68
|
4. Push to the branch (`git push origin my-new-feature`)
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module WFlow
|
2
|
+
class Configuration
|
3
|
+
attr_reader :supress_errors
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def config
|
7
|
+
yield configuration
|
8
|
+
end
|
9
|
+
|
10
|
+
def supress_errors?
|
11
|
+
configuration.supress_errors
|
12
|
+
end
|
13
|
+
|
14
|
+
def configuration
|
15
|
+
@configuration ||= new
|
16
|
+
end
|
17
|
+
|
18
|
+
def reset_configuration
|
19
|
+
@configuration = new
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
protected
|
24
|
+
|
25
|
+
def initialize
|
26
|
+
@supress_errors = false
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/w_flow/flow.rb
CHANGED
@@ -1,32 +1,18 @@
|
|
1
1
|
module WFlow
|
2
2
|
class Flow
|
3
|
-
|
3
|
+
extend Forwardable
|
4
|
+
def_delegator :@supervisor, :add_to_finalizables, :finalizable!
|
5
|
+
def_delegator :@supervisor, :add_to_rollbackables, :rollbackable!
|
6
|
+
def_delegators :@supervisor,
|
7
|
+
:skip!,
|
8
|
+
:stop!,
|
9
|
+
:failure!,
|
10
|
+
:data,
|
11
|
+
:success?,
|
12
|
+
:failure?
|
4
13
|
|
5
|
-
def initialize(
|
6
|
-
@
|
7
|
-
@failure = false
|
8
|
-
@failure_message = nil
|
9
|
-
end
|
10
|
-
|
11
|
-
def success?
|
12
|
-
!failure?
|
13
|
-
end
|
14
|
-
|
15
|
-
def failure?
|
16
|
-
@failure
|
17
|
-
end
|
18
|
-
|
19
|
-
def failure!(message = nil)
|
20
|
-
@failure = true
|
21
|
-
@failure_message = message
|
22
|
-
end
|
23
|
-
|
24
|
-
def stop!
|
25
|
-
throw :stop
|
26
|
-
end
|
27
|
-
|
28
|
-
def skip!
|
29
|
-
throw :skip
|
14
|
+
def initialize(supervisor)
|
15
|
+
@supervisor = supervisor
|
30
16
|
end
|
31
17
|
end
|
32
18
|
end
|
data/lib/w_flow/node.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
module WFlow
|
2
|
+
class Node
|
3
|
+
def initialize(components, options)
|
4
|
+
@components = components
|
5
|
+
@options = options
|
6
|
+
end
|
7
|
+
|
8
|
+
def execute(supervisor, process)
|
9
|
+
node_process = NodeProcess.new(@components, @options)
|
10
|
+
|
11
|
+
node_process.execute(supervisor, process)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module WFlow
|
2
|
+
class NodeProcess
|
3
|
+
def initialize(components, options)
|
4
|
+
@components = components
|
5
|
+
@around_option = options[:around]
|
6
|
+
@if_option = options[:if]
|
7
|
+
@unless_option = options[:unless]
|
8
|
+
@stop_option = options[:stop]
|
9
|
+
@failure_option = options[:failure]
|
10
|
+
end
|
11
|
+
|
12
|
+
def execute(supervisor, process)
|
13
|
+
@supervisor = supervisor
|
14
|
+
@process = process
|
15
|
+
|
16
|
+
if execute_node?
|
17
|
+
supervisor.supervise(self) do
|
18
|
+
if @around_option.nil?
|
19
|
+
execute_components
|
20
|
+
else
|
21
|
+
process_eval(@around_option, method(:execute_components))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def cancel_stop?
|
28
|
+
!@stop_option.nil? && !process_eval(@stop_option)
|
29
|
+
end
|
30
|
+
|
31
|
+
def cancel_failure?
|
32
|
+
!@failure_option.nil? && !process_eval(@failure_option)
|
33
|
+
end
|
34
|
+
|
35
|
+
protected
|
36
|
+
|
37
|
+
def execute_node?
|
38
|
+
(@if_option.nil? || process_eval(@if_option)) &&
|
39
|
+
(@unless_option.nil? || !process_eval(@unless_option))
|
40
|
+
end
|
41
|
+
|
42
|
+
def execute_components
|
43
|
+
@components.each { |component| process_eval(component) }
|
44
|
+
end
|
45
|
+
|
46
|
+
def process_eval(object, *args)
|
47
|
+
if object.is_a?(String) || object.is_a?(Symbol)
|
48
|
+
@process.send(object.to_s, *args)
|
49
|
+
elsif object.is_a?(Proc)
|
50
|
+
@process.instance_exec(*args, &object)
|
51
|
+
elsif object <= Process
|
52
|
+
object.new.wflow_execute(@supervisor, *args)
|
53
|
+
else
|
54
|
+
raise InvalidArguments, UNKNOWN_EXPRESSION
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/w_flow/process.rb
CHANGED
@@ -1,58 +1,80 @@
|
|
1
1
|
module WFlow
|
2
2
|
module Process
|
3
|
+
def self.included(klass)
|
4
|
+
klass.extend(ClassMethods)
|
5
|
+
end
|
6
|
+
|
3
7
|
attr_reader :flow
|
4
8
|
|
5
|
-
def
|
6
|
-
|
9
|
+
def wflow_execute(supervisor)
|
10
|
+
supervisor.supervise(self) do |flow|
|
11
|
+
@flow = flow
|
12
|
+
|
13
|
+
setup
|
14
|
+
|
15
|
+
flow.finalizable!
|
16
|
+
|
17
|
+
self.class.wflow_nodes.each do |node|
|
18
|
+
node.execute(supervisor, self)
|
19
|
+
end
|
20
|
+
|
21
|
+
perform
|
22
|
+
|
23
|
+
flow.rollbackable!
|
24
|
+
end
|
7
25
|
end
|
8
26
|
|
9
27
|
def setup; end
|
10
28
|
def perform; end
|
11
29
|
def rollback; end
|
12
|
-
def
|
13
|
-
|
14
|
-
def self.included(klass)
|
15
|
-
klass.extend(ClassMethods)
|
30
|
+
def finalize; end
|
16
31
|
|
17
|
-
|
18
|
-
end
|
32
|
+
protected
|
19
33
|
|
20
34
|
module ClassMethods
|
35
|
+
attr_reader :wflow_nodes
|
36
|
+
|
37
|
+
def self.extended(klass)
|
38
|
+
klass.instance_variable_set('@wflow_nodes', [])
|
39
|
+
end
|
40
|
+
|
41
|
+
def inherited(klass)
|
42
|
+
klass.instance_variable_set('@wflow_nodes', wflow_nodes.dup)
|
43
|
+
end
|
44
|
+
|
21
45
|
def data_accessor(*keys)
|
22
|
-
data_writer(keys)
|
23
|
-
data_reader(keys)
|
46
|
+
data_writer(*keys)
|
47
|
+
data_reader(*keys)
|
24
48
|
end
|
25
49
|
|
26
50
|
def data_writer(*keys)
|
27
51
|
keys.each do |key|
|
28
|
-
define_method
|
29
|
-
flow.data[key] = val
|
30
|
-
end
|
52
|
+
define_method("#{key}=") { |val| flow.data.send("#{key}=", val) }
|
31
53
|
end
|
32
54
|
end
|
33
55
|
|
34
56
|
def data_reader(*keys)
|
35
57
|
keys.each do |key|
|
36
|
-
define_method key
|
37
|
-
flow.data[key]
|
38
|
-
end
|
58
|
+
define_method(key) { flow.data.send(key.to_s) }
|
39
59
|
end
|
40
60
|
end
|
41
61
|
|
42
|
-
def execute(*
|
43
|
-
options =
|
44
|
-
|
45
|
-
|
46
|
-
@process_nodes << ProcessNode.new(args, options)
|
62
|
+
def execute(*components, &block)
|
63
|
+
options = components.last.is_a?(Hash) ? components.pop : {}
|
64
|
+
components << block if block_given?
|
65
|
+
wflow_nodes << Node.new(components, options)
|
47
66
|
end
|
48
67
|
|
49
68
|
def run(params = {})
|
50
|
-
unless params.is_a?(Hash)
|
51
|
-
raise InvalidArgument,
|
69
|
+
unless params.nil? || params.is_a?(Hash)
|
70
|
+
raise InvalidArgument, INVALID_RUN_PARAMS
|
52
71
|
end
|
53
|
-
end
|
54
72
|
|
55
|
-
|
73
|
+
supervisor = Supervisor.new(params)
|
74
|
+
|
75
|
+
new.wflow_execute(supervisor)
|
76
|
+
|
77
|
+
supervisor.report
|
56
78
|
end
|
57
79
|
end
|
58
80
|
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
module WFlow
|
2
|
+
class Supervisor
|
3
|
+
attr_reader :data, :message
|
4
|
+
|
5
|
+
def initialize(params)
|
6
|
+
@data = Data.new(params)
|
7
|
+
@flow = Flow.new(self)
|
8
|
+
@failure = false
|
9
|
+
@message = false
|
10
|
+
@backlog = []
|
11
|
+
@finalizables = []
|
12
|
+
@rollbackables = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def supervise(process, &block)
|
16
|
+
@backlog << @current_process unless @current_process.nil?
|
17
|
+
@current_process = process
|
18
|
+
|
19
|
+
if parent_process?
|
20
|
+
supervise_parent_process(&block)
|
21
|
+
finalize_processes
|
22
|
+
else
|
23
|
+
supervise_child_process(&block)
|
24
|
+
end
|
25
|
+
ensure
|
26
|
+
@current_process = @backlog.pop
|
27
|
+
end
|
28
|
+
|
29
|
+
def add_to_finalizables
|
30
|
+
@finalizables.unshift(@current_process)
|
31
|
+
end
|
32
|
+
|
33
|
+
def add_to_rollbackables
|
34
|
+
@rollbackables << @current_process
|
35
|
+
end
|
36
|
+
|
37
|
+
def skip!
|
38
|
+
throw :wflow_interrupt, :wflow_skip
|
39
|
+
end
|
40
|
+
|
41
|
+
def stop!
|
42
|
+
throw :wflow_interrupt, :wflow_stop
|
43
|
+
end
|
44
|
+
|
45
|
+
def failure!(message = nil)
|
46
|
+
raise FlowFailure, Marshal.dump(message)
|
47
|
+
end
|
48
|
+
|
49
|
+
def success?
|
50
|
+
!failure?
|
51
|
+
end
|
52
|
+
|
53
|
+
def failure?
|
54
|
+
@failure
|
55
|
+
end
|
56
|
+
|
57
|
+
def report
|
58
|
+
Report.new(self)
|
59
|
+
end
|
60
|
+
|
61
|
+
protected
|
62
|
+
|
63
|
+
def parent_process?
|
64
|
+
!@current_process.nil? && @backlog.empty?
|
65
|
+
end
|
66
|
+
|
67
|
+
def supervise_parent_process
|
68
|
+
catch :wflow_interrupt do
|
69
|
+
yield @flow
|
70
|
+
end
|
71
|
+
rescue FlowFailure => e
|
72
|
+
set_failure(true, Marshal.load(e.message))
|
73
|
+
rescue ::StandardError => e
|
74
|
+
raise unless Configuration.supress_errors?
|
75
|
+
|
76
|
+
set_failure(true, message: e.message, backtrace: e.backtrace)
|
77
|
+
end
|
78
|
+
|
79
|
+
def supervise_child_process
|
80
|
+
interrupt = catch :wflow_interrupt do
|
81
|
+
yield @flow
|
82
|
+
end
|
83
|
+
|
84
|
+
stop! if interrupt == :wflow_stop && rethrow_stop?
|
85
|
+
rescue FlowFailure => e
|
86
|
+
if reraise_error?
|
87
|
+
set_failure(true, Marshal.load(e.message))
|
88
|
+
raise
|
89
|
+
else
|
90
|
+
set_failure(false, Marshal.load(e.message))
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def finalize_processes
|
95
|
+
interrupt = catch :wflow_interrupt do
|
96
|
+
@rollbackables.each(&:rollback) if failure?
|
97
|
+
@finalizables.each(&:finalize)
|
98
|
+
end
|
99
|
+
|
100
|
+
raise FlowFailure if [:wflow_stop, :wflow_skip].include?(interrupt)
|
101
|
+
rescue FlowFailure
|
102
|
+
raise InvalidOperation, INVALID_OPERATION
|
103
|
+
end
|
104
|
+
|
105
|
+
def set_failure(state, message)
|
106
|
+
@failure = state
|
107
|
+
@message << message unless message.nil?
|
108
|
+
end
|
109
|
+
|
110
|
+
def rethrow_stop?
|
111
|
+
!@current_process.is_a?(NodeProcess) || !@current_process.cancel_stop?
|
112
|
+
end
|
113
|
+
|
114
|
+
def reraise_error?
|
115
|
+
!@current_process.is_a?(NodeProcess) || !@current_process.cancel_failure?
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
data/lib/w_flow/version.rb
CHANGED
data/lib/w_flow.rb
CHANGED
@@ -1,9 +1,23 @@
|
|
1
1
|
require "w_flow/version"
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
2
|
+
require "w_flow/configuration"
|
3
|
+
require "w_flow/data"
|
4
|
+
require "w_flow/report"
|
5
|
+
require "w_flow/supervisor"
|
6
|
+
require "w_flow/flow"
|
7
|
+
require "w_flow/node_process"
|
8
|
+
require "w_flow/node"
|
9
|
+
require "w_flow/process"
|
7
10
|
|
8
11
|
module WFlow
|
12
|
+
# WFlow errors
|
13
|
+
class StandardError < ::StandardError; end
|
14
|
+
|
15
|
+
class InvalidArguments < StandardError; end
|
16
|
+
class FlowFailure < StandardError; end
|
17
|
+
class InvalidOperation < StandardError; end
|
18
|
+
|
19
|
+
# WFlow message constants
|
20
|
+
INVALID_RUN_PARAMS = "run must be invoked without arguments or an Hash"
|
21
|
+
UNKNOWN_EXPRESSION = "can't evaluate expression"
|
22
|
+
INVALID_OPERATION = "skip!, stop! or failure! can't be invoked during finalize/rollback"
|
9
23
|
end
|
data/w_flow.gemspec
CHANGED
@@ -12,13 +12,15 @@ Gem::Specification.new do |spec|
|
|
12
12
|
spec.summary = %q{A workflow composer based on Single Responsability Principle to help organize projects}
|
13
13
|
spec.description = %q{WFlow is a workflow composer that helps in organizing projects by splitting logic into reusable modules (processes)}
|
14
14
|
spec.homepage = "https://github.com/junhanamaki/w_flow"
|
15
|
-
spec.license = 'MIT'
|
16
15
|
|
17
16
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
17
|
spec.bindir = "exe"
|
19
18
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
19
|
spec.require_paths = ["lib"]
|
21
20
|
|
21
|
+
spec.license = 'MIT'
|
22
|
+
spec.required_ruby_version = '>= 2.0.0'
|
23
|
+
|
22
24
|
spec.add_development_dependency "bundler", "~> 1.9"
|
23
25
|
spec.add_development_dependency "rspec", '~> 3.2'
|
24
26
|
spec.add_development_dependency "pry", '~> 0.10'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: w_flow
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- junhanamaki
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-05-
|
11
|
+
date: 2015-05-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -95,11 +95,14 @@ files:
|
|
95
95
|
- README.md
|
96
96
|
- Rakefile
|
97
97
|
- lib/w_flow.rb
|
98
|
+
- lib/w_flow/configuration.rb
|
98
99
|
- lib/w_flow/data.rb
|
99
|
-
- lib/w_flow/exceptions.rb
|
100
100
|
- lib/w_flow/flow.rb
|
101
|
+
- lib/w_flow/node.rb
|
102
|
+
- lib/w_flow/node_process.rb
|
101
103
|
- lib/w_flow/process.rb
|
102
|
-
- lib/w_flow/
|
104
|
+
- lib/w_flow/report.rb
|
105
|
+
- lib/w_flow/supervisor.rb
|
103
106
|
- lib/w_flow/version.rb
|
104
107
|
- w_flow.gemspec
|
105
108
|
homepage: https://github.com/junhanamaki/w_flow
|
@@ -114,7 +117,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
114
117
|
requirements:
|
115
118
|
- - ">="
|
116
119
|
- !ruby/object:Gem::Version
|
117
|
-
version:
|
120
|
+
version: 2.0.0
|
118
121
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
122
|
requirements:
|
120
123
|
- - ">="
|
@@ -122,7 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
122
125
|
version: '0'
|
123
126
|
requirements: []
|
124
127
|
rubyforge_project:
|
125
|
-
rubygems_version: 2.4.
|
128
|
+
rubygems_version: 2.4.6
|
126
129
|
signing_key:
|
127
130
|
specification_version: 4
|
128
131
|
summary: A workflow composer based on Single Responsability Principle to help organize
|
data/lib/w_flow/exceptions.rb
DELETED
data/lib/w_flow/process_node.rb
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
module WFlow
|
2
|
-
class ProcessNode
|
3
|
-
def initialize(tasks, options)
|
4
|
-
@tasks = tasks
|
5
|
-
@options = options
|
6
|
-
end
|
7
|
-
|
8
|
-
def execute(owner_process)
|
9
|
-
return unless execute_node?(owner_process)
|
10
|
-
|
11
|
-
@tasks.each do |task|
|
12
|
-
if task.is_a?(String) || task.is_a?(Symbol)
|
13
|
-
owner_process.instance_eval(task.to_s)
|
14
|
-
elsif task.is_a?(Proc)
|
15
|
-
owner_process.instance_eval(&task)
|
16
|
-
elsif task.is_a?(Process)
|
17
|
-
task.run(owner_process.flow)
|
18
|
-
else
|
19
|
-
raise UnknownTask, "don't know how to execute task #{task}"
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
protected
|
25
|
-
|
26
|
-
def execute_node?(owner_process)
|
27
|
-
if_condition_allows_execution?(owner_process) &&
|
28
|
-
unless_condition_allows_execution?(owner_process)
|
29
|
-
end
|
30
|
-
|
31
|
-
def if_condition_allows_execution?(owner_process)
|
32
|
-
@options[:if].nil? || eval_condition(@options[:if], owner_process)
|
33
|
-
end
|
34
|
-
|
35
|
-
def unless_condition_allows_execution?(owner_process)
|
36
|
-
@options[:unless].nil? || !eval_condition(@options[:unless], owner_process)
|
37
|
-
end
|
38
|
-
|
39
|
-
def eval_condition?(condition, owner_process)
|
40
|
-
((condition.is_a?(String) || condition.is_a?(Symbol)) &&
|
41
|
-
owner_process.instance_eval(condition.to_s)) ||
|
42
|
-
(condition.is_a?(Proc) && owner_process.instance_eval(&condition))
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|