w_flow 0.11.0 → 0.12.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/README.md +106 -34
- data/lib/w_flow/configuration.rb +2 -0
- data/lib/w_flow/data.rb +2 -0
- data/lib/w_flow/node.rb +4 -104
- data/lib/w_flow/node_worker.rb +91 -0
- data/lib/w_flow/process.rb +4 -4
- data/lib/w_flow/process_worker.rb +16 -29
- data/lib/w_flow/tasks_worker.rb +70 -0
- data/lib/w_flow/version.rb +1 -1
- data/lib/w_flow.rb +2 -0
- data/w_flow.gemspec +2 -2
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4c6971610a0278716309118842acdfd7532ed202
|
4
|
+
data.tar.gz: bbda595555d7dcc881280bd7369d1456c8561ff6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2012a6ea13452f2dc30418ea861fe8f54b5dcb30723cf8aa4a372835b25a9713670695ec4efee5a187b70885f40830e15fe9ddf62c0d85d9ff8c994915c4404d
|
7
|
+
data.tar.gz: fca65b36b9966e01f743fe9619b9477e5200ff96ddf2b23100749d2101b6a26a15a1550cac133067c3a843a52dc9ec81e5782a120e88b3b86480055e52a1f575
|
data/README.md
CHANGED
@@ -8,8 +8,7 @@
|
|
8
8
|
|
9
9
|
WFlow aims to help on designing workflows based on [Single
|
10
10
|
Responsibility Principle](http://en.wikipedia.org/wiki/Single_responsibility_principle). WFlow
|
11
|
-
proposes to achieve this by providing tools to
|
12
|
-
and one task only, and by providing tools to compose these classes.
|
11
|
+
proposes to achieve this by providing tools to help compose those classes into a workflow.
|
13
12
|
|
14
13
|
Word of appreciation for [usecasing](https://github.com/tdantas/usecasing),
|
15
14
|
[interactor](https://github.com/collectiveidea/interactor) and
|
@@ -40,66 +39,139 @@ Or install it yourself as:
|
|
40
39
|
|
41
40
|
## Usage
|
42
41
|
|
43
|
-
|
44
|
-
and publish it in google calendar if needed:
|
42
|
+
In its most simplest form a Process would look like this:
|
45
43
|
|
46
44
|
```ruby
|
47
|
-
|
45
|
+
# Process to retrive a user from the database given a user_id
|
46
|
+
class FindUser
|
47
|
+
# include module Process
|
48
48
|
include WFlow::Process
|
49
49
|
|
50
|
-
#
|
51
|
-
data_reader :appointment_id
|
52
|
-
data_writer :appointment
|
53
|
-
|
54
|
-
# perform is the name of the method that will be invoked when calling 'run'
|
50
|
+
# perform is where you'll execute your business logic
|
55
51
|
def perform
|
56
|
-
|
52
|
+
# flow is an object present in a Process, and it is how you retrieve data
|
53
|
+
# from the current flow, in this case the input user_id
|
54
|
+
user_id = flow.data.user_id
|
57
55
|
|
58
|
-
#
|
59
|
-
|
56
|
+
# when you want to output a value from the Process you set it in data
|
57
|
+
flow.data.user = User.find(user_id)
|
60
58
|
end
|
61
59
|
end
|
60
|
+
```
|
62
61
|
|
63
|
-
|
64
|
-
|
62
|
+
And you invoke it like this:
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
# run will returns a report object
|
66
|
+
report = FindUser.run(user_id: 10)
|
65
67
|
|
66
|
-
|
68
|
+
# this report object will contain the output from the Process
|
69
|
+
report.data.user
|
70
|
+
```
|
67
71
|
|
68
|
-
|
72
|
+
This and any other Process can be used to compose a workflow, so lets try that:
|
69
73
|
|
70
|
-
|
74
|
+
```ruby
|
75
|
+
class SendWelcomeEmail
|
76
|
+
include WFlow::Process
|
77
|
+
|
78
|
+
# use previously created Process to find the user
|
79
|
+
execute FindUser
|
71
80
|
|
72
|
-
def
|
73
|
-
|
81
|
+
def perform
|
82
|
+
# code to send email to user
|
74
83
|
end
|
75
84
|
end
|
76
85
|
|
77
|
-
|
78
|
-
report = UpdateAppointment.run(appointment_id: appointment_id, attributes: new_attributes)
|
79
|
-
|
80
|
-
# ask if workflow was a success
|
81
|
-
report.success?
|
86
|
+
report = SendWelcomeEmail.run(user_id: 10)
|
82
87
|
```
|
83
88
|
|
84
|
-
|
85
|
-
|
89
|
+
Processes passed to execute will be called before the perform method. You can
|
90
|
+
have as any execute as you want and as many Processes (and method nomes and Procs) in a execute.
|
91
|
+
This means that when you run SendWelcomeEmail process, it will first execute FindUser which will
|
92
|
+
set the user under flow.data, and than you can use that user to get the email address
|
93
|
+
for where to send the email.
|
94
|
+
|
95
|
+
So far so good, but lets go back to FindUser. Looking at it, we are currently not accounting for
|
96
|
+
errors cases, like what should happen when we can't find an user, or when the connection to the
|
97
|
+
database fails? This depends on what you want to do, but for this example we'll raise a flow failure,
|
98
|
+
and we'll also simplify the code a bit using data helpers:
|
86
99
|
|
87
100
|
```ruby
|
88
|
-
class
|
101
|
+
class FindUser
|
89
102
|
include WFlow::Process
|
103
|
+
|
104
|
+
# helper methods to access attributes under flow.data
|
105
|
+
data_reader :user_id
|
106
|
+
data_accessor :user
|
107
|
+
|
108
|
+
def perform
|
109
|
+
self.user = User.find(user_id)
|
110
|
+
rescue
|
111
|
+
# you can pass whatever you want to the failure! method (or even call it without arguments)
|
112
|
+
# passed value will be available in returned report under failure_log
|
113
|
+
flow.failure!('unable to find user')
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
report = FindUser.run(user_id: 10)
|
118
|
+
|
119
|
+
# check if success
|
120
|
+
unless report.success? # there's also a report.failure?
|
121
|
+
# failure_log is an array that contains all the objects passed to failure!
|
122
|
+
report.failure_log.each do |log|
|
123
|
+
puts log
|
124
|
+
end
|
125
|
+
end
|
90
126
|
```
|
91
127
|
|
92
|
-
|
128
|
+
Invoking failure! will interrupt a workflow immediatly. This means that if you run
|
129
|
+
SendWelcomeEmail for a non existing user it will never run the code under perform (which
|
130
|
+
is a good thing, since there's no one to send the email to). But what if we want to do
|
131
|
+
something more even in case of failure? You can pass a handler for that:
|
93
132
|
|
94
133
|
```ruby
|
95
|
-
|
96
|
-
|
134
|
+
class SendWelcomeEmail
|
135
|
+
include WFlow::Process
|
136
|
+
|
137
|
+
attr_writer :admin_email
|
138
|
+
|
139
|
+
# you can pass a name or a proc as a failure handler, which will be called if one
|
140
|
+
# of the Processes in execute chain raises a flow failure
|
141
|
+
execute FindUser, failure: :on_failure
|
142
|
+
|
143
|
+
# we'll use an if handler (there's also an unless handler), which allows us to control if a execute chain
|
144
|
+
# should be executed or not
|
145
|
+
execute :compose_email, SendMessageToAdmin, -> { flow.failure! }, if: -> { @no_user_found }
|
146
|
+
|
147
|
+
def perform
|
148
|
+
# ...
|
149
|
+
end
|
150
|
+
|
151
|
+
protected
|
97
152
|
|
98
|
-
#
|
99
|
-
|
153
|
+
# failure handler, return false to cancel failure, or true to let Process fail
|
154
|
+
def on_failure
|
155
|
+
@no_user_found = true
|
156
|
+
|
157
|
+
false
|
158
|
+
end
|
159
|
+
|
160
|
+
def compose_email
|
161
|
+
self.admin_email = "we were unable to find user :("
|
162
|
+
end
|
163
|
+
end
|
100
164
|
```
|
101
165
|
|
102
|
-
|
166
|
+
Wow it suddenly become complex, but it reflects a more realistic situation. So what's
|
167
|
+
going on? First we try to find the user, which will raise a flow failure if no user
|
168
|
+
is found. In this case we want to inform the admin that something went wrong, so instead of allowing
|
169
|
+
the flow to be interrupted right away, we return false in the failure handler to cancel failure.
|
170
|
+
After that, the second execute chain will be executed, because @no_user_found is set to true. This
|
171
|
+
execution chain will invoke the method compose_email, SendMessageToAdmin, and than
|
172
|
+
call proc that reraises failure.
|
173
|
+
|
174
|
+
This is some of the features of WFlow, please check [wiki](https://github.com/junhanamaki/w_flow/wiki) for more details.
|
103
175
|
|
104
176
|
## Contributing
|
105
177
|
|
data/lib/w_flow/configuration.rb
CHANGED
data/lib/w_flow/data.rb
CHANGED
data/lib/w_flow/node.rb
CHANGED
@@ -3,115 +3,15 @@ module WFlow
|
|
3
3
|
|
4
4
|
class << self
|
5
5
|
|
6
|
-
attr_reader :
|
7
|
-
:if_condition,
|
8
|
-
:unless_condition,
|
9
|
-
:stop_condition,
|
10
|
-
:failure_condition,
|
11
|
-
:around_handler
|
6
|
+
attr_reader :tasks, :options
|
12
7
|
|
13
|
-
def build(
|
8
|
+
def build(tasks, options)
|
14
9
|
Class.new(self) do |klass|
|
15
|
-
@
|
16
|
-
@
|
17
|
-
@unless_condition = options[:unless]
|
18
|
-
@stop_condition = options[:stop]
|
19
|
-
@failure_condition = options[:failure]
|
20
|
-
@around_handler = options[:around]
|
10
|
+
@tasks = tasks
|
11
|
+
@options = options
|
21
12
|
end
|
22
13
|
end
|
23
14
|
|
24
|
-
def execute?(process)
|
25
|
-
(if_condition.nil? || process_eval(process, if_condition)) &&
|
26
|
-
(unless_condition.nil? || !process_eval(process, unless_condition))
|
27
|
-
end
|
28
|
-
|
29
|
-
def cancel_stop?(process)
|
30
|
-
!stop_condition.nil? && !process_eval(process, stop_condition)
|
31
|
-
end
|
32
|
-
|
33
|
-
def cancel_failure?(process)
|
34
|
-
!failure_condition.nil? && !process_eval(process, failure_condition)
|
35
|
-
end
|
36
|
-
|
37
|
-
def process_eval(process, object, *args)
|
38
|
-
if object.is_a?(String) || object.is_a?(Symbol)
|
39
|
-
process.send(object.to_s, *args)
|
40
|
-
elsif object.is_a?(Proc)
|
41
|
-
process.instance_exec(*args, &object)
|
42
|
-
else
|
43
|
-
raise InvalidArguments, UNKNOWN_EXPRESSION
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
end
|
48
|
-
|
49
|
-
def initialize(owner_process)
|
50
|
-
@owner_process = owner_process
|
51
|
-
@components = self.class.components
|
52
|
-
@around_handler = self.class.around_handler
|
53
|
-
end
|
54
|
-
|
55
|
-
def run(flow)
|
56
|
-
@flow = flow
|
57
|
-
@execution_chains = []
|
58
|
-
|
59
|
-
if @around_handler.nil?
|
60
|
-
execute_components
|
61
|
-
else
|
62
|
-
@around_handler.call(method(:execute_components))
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def finalize
|
67
|
-
@execution_chains.reverse_each do |execution_chain|
|
68
|
-
execution_chain.reverse_each(&:finalize)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def rollback
|
73
|
-
@execution_chains.reverse_each do |execution_chain|
|
74
|
-
execution_chain.reverse_each(&:rollback)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
protected
|
79
|
-
|
80
|
-
def execute_components(options = {})
|
81
|
-
execution_chain = []
|
82
|
-
|
83
|
-
@components.each do |component|
|
84
|
-
report = Supervisor.supervise do
|
85
|
-
if component.is_a?(Class) && component <= Process
|
86
|
-
process_worker = ProcessWorker.new(component)
|
87
|
-
|
88
|
-
execution_chain << process_worker
|
89
|
-
|
90
|
-
process_worker.run_as_child(@flow)
|
91
|
-
else
|
92
|
-
self.class.process_eval(@owner_process, component)
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
if report.failed?
|
97
|
-
execution_chain.reverse_each(&:rollback)
|
98
|
-
execution_chain.reverse_each(&:finalize)
|
99
|
-
|
100
|
-
if options[:failure].nil? || options[:failure].call
|
101
|
-
@flow.log_failure(report.message)
|
102
|
-
return
|
103
|
-
else
|
104
|
-
Supervisor.resignal!(report)
|
105
|
-
end
|
106
|
-
else
|
107
|
-
if report.stopped? && (options[:stop].nil? || !options[:stop].call)
|
108
|
-
@execution_chains << execution_chain
|
109
|
-
Supervisor.resignal!(report)
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
@execution_chains << execution_chain
|
115
15
|
end
|
116
16
|
|
117
17
|
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module WFlow
|
2
|
+
class NodeWorker
|
3
|
+
|
4
|
+
def initialize(owner_process, node_class)
|
5
|
+
@owner_process = owner_process
|
6
|
+
@tasks = node_class.tasks
|
7
|
+
|
8
|
+
options = node_class.options
|
9
|
+
|
10
|
+
@execute_if = options[:if]
|
11
|
+
@execute_unless = options[:unless]
|
12
|
+
@around_proc = options[:around]
|
13
|
+
@confirm_stop = options[:stop]
|
14
|
+
@confirm_failure = options[:failure]
|
15
|
+
end
|
16
|
+
|
17
|
+
def execute?
|
18
|
+
(@execute_if.nil? || process_eval(@execute_if)) &&
|
19
|
+
(@execute_unless.nil? || !process_eval(@execute_unless))
|
20
|
+
end
|
21
|
+
|
22
|
+
def run(flow)
|
23
|
+
@flow = flow
|
24
|
+
@executed_tasks_workers = []
|
25
|
+
|
26
|
+
report = Supervisor.supervise do
|
27
|
+
if @around_proc.nil?
|
28
|
+
execute_tasks
|
29
|
+
else
|
30
|
+
process_eval(@around_proc, method(:execute_tasks))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
if report.failed?
|
35
|
+
rollback
|
36
|
+
finalize
|
37
|
+
|
38
|
+
@executed_tasks_workers.clear
|
39
|
+
|
40
|
+
if signal_failure?
|
41
|
+
Supervisor.resignal!(report)
|
42
|
+
else
|
43
|
+
@flow.log_failure(report.message)
|
44
|
+
end
|
45
|
+
elsif report.stopped? && signal_stop?
|
46
|
+
Supervisor.resignal!(report)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def finalize
|
51
|
+
executed_do(:finalize)
|
52
|
+
end
|
53
|
+
|
54
|
+
def rollback
|
55
|
+
executed_do(:rollback)
|
56
|
+
end
|
57
|
+
|
58
|
+
def process_eval(object, *args)
|
59
|
+
if object.is_a?(String) || object.is_a?(Symbol)
|
60
|
+
@owner_process.send(object.to_s, *args)
|
61
|
+
elsif object.is_a?(Proc)
|
62
|
+
@owner_process.instance_exec(*args, &object)
|
63
|
+
else
|
64
|
+
raise InvalidArguments, UNKNOWN_EXPRESSION
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
protected
|
69
|
+
|
70
|
+
def execute_tasks(options = {})
|
71
|
+
tasks_worker = TasksWorker.new(self, @tasks)
|
72
|
+
|
73
|
+
@executed_tasks_workers << tasks_worker
|
74
|
+
|
75
|
+
tasks_worker.run(@flow, options)
|
76
|
+
end
|
77
|
+
|
78
|
+
def signal_stop?
|
79
|
+
@confirm_stop.nil? || process_eval(@confirm_stop)
|
80
|
+
end
|
81
|
+
|
82
|
+
def signal_failure?
|
83
|
+
@confirm_failure.nil? || process_eval(@confirm_failure)
|
84
|
+
end
|
85
|
+
|
86
|
+
def executed_do(order)
|
87
|
+
@executed_tasks_workers.reverse_each(&order)
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
data/lib/w_flow/process.rb
CHANGED
@@ -46,10 +46,10 @@ module WFlow
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
-
def execute(*
|
50
|
-
options =
|
51
|
-
|
52
|
-
wflow_nodes << Node.build(
|
49
|
+
def execute(*tasks, &block)
|
50
|
+
options = tasks.last.is_a?(Hash) ? tasks.pop : {}
|
51
|
+
tasks << block if block_given?
|
52
|
+
wflow_nodes << Node.build(tasks, options)
|
53
53
|
end
|
54
54
|
|
55
55
|
def run(params = {})
|
@@ -1,5 +1,6 @@
|
|
1
1
|
module WFlow
|
2
2
|
class ProcessWorker
|
3
|
+
|
3
4
|
def initialize(process_class)
|
4
5
|
@process_class = process_class
|
5
6
|
end
|
@@ -28,59 +29,45 @@ module WFlow
|
|
28
29
|
end
|
29
30
|
|
30
31
|
def finalize
|
31
|
-
@
|
32
|
+
@executed_nodes.reverse_each(&:finalize)
|
32
33
|
|
33
34
|
@process.finalize if @setup_completed
|
34
35
|
end
|
35
36
|
|
36
37
|
def rollback
|
37
|
-
@
|
38
|
+
@executed_nodes.reverse_each(&:rollback)
|
38
39
|
|
39
40
|
@process.rollback if @perform_completed
|
40
41
|
end
|
41
42
|
|
42
43
|
protected
|
43
44
|
|
45
|
+
def setup(flow)
|
46
|
+
@flow = flow
|
47
|
+
@process = @process_class.new(flow)
|
48
|
+
|
49
|
+
@executed_nodes = []
|
50
|
+
@setup_completed = false
|
51
|
+
@perform_completed = false
|
52
|
+
end
|
53
|
+
|
44
54
|
def run
|
45
55
|
@process.setup
|
46
56
|
@setup_completed = true
|
47
57
|
|
48
58
|
@process_class.wflow_nodes.each do |node_class|
|
49
|
-
|
50
|
-
|
51
|
-
node = node_class.new(@process)
|
59
|
+
node_worker = NodeWorker.new(@process, node_class)
|
52
60
|
|
53
|
-
|
61
|
+
next unless node_worker.execute?
|
54
62
|
|
55
|
-
|
56
|
-
node.rollback
|
57
|
-
node.finalize
|
63
|
+
@executed_nodes << node_worker
|
58
64
|
|
59
|
-
|
60
|
-
@flow.log_failure(report.message)
|
61
|
-
else
|
62
|
-
Supervisor.resignal!(report)
|
63
|
-
end
|
64
|
-
else
|
65
|
-
@nodes << node
|
66
|
-
|
67
|
-
if report.stopped? && !node_class.cancel_stop?(@process)
|
68
|
-
Supervisor.resignal!(report)
|
69
|
-
end
|
70
|
-
end
|
65
|
+
report = node_worker.run(@flow)
|
71
66
|
end
|
72
67
|
|
73
68
|
@process.perform
|
74
69
|
@perform_completed = true
|
75
70
|
end
|
76
71
|
|
77
|
-
def setup(flow)
|
78
|
-
@flow = flow
|
79
|
-
@process = @process_class.new(flow)
|
80
|
-
@nodes = []
|
81
|
-
@setup_completed = false
|
82
|
-
@perform_completed = false
|
83
|
-
end
|
84
|
-
|
85
72
|
end
|
86
73
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module WFlow
|
2
|
+
class TasksWorker
|
3
|
+
|
4
|
+
def initialize(owner_node, tasks)
|
5
|
+
@owner_node = owner_node
|
6
|
+
@tasks = tasks
|
7
|
+
end
|
8
|
+
|
9
|
+
def run(flow, options = {})
|
10
|
+
@flow = flow
|
11
|
+
@options = options
|
12
|
+
@executed_tasks = []
|
13
|
+
|
14
|
+
@tasks.each do |task|
|
15
|
+
report = Supervisor.supervise { execute_task(task) }
|
16
|
+
|
17
|
+
if report.failed?
|
18
|
+
rollback
|
19
|
+
finalize
|
20
|
+
|
21
|
+
@executed_tasks.clear
|
22
|
+
|
23
|
+
if signal_failure?
|
24
|
+
Supervisor.resignal!(report)
|
25
|
+
else
|
26
|
+
flow.log_failure(report.message)
|
27
|
+
return
|
28
|
+
end
|
29
|
+
else
|
30
|
+
Supervisor.resignal!(report) if report.stopped? && signal_stop?
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def finalize
|
36
|
+
executed_do(:finalize)
|
37
|
+
end
|
38
|
+
|
39
|
+
def rollback
|
40
|
+
executed_do(:rollback)
|
41
|
+
end
|
42
|
+
|
43
|
+
protected
|
44
|
+
|
45
|
+
def execute_task(task)
|
46
|
+
if task.is_a?(Class) && task <= Process
|
47
|
+
process_worker = ProcessWorker.new(task)
|
48
|
+
|
49
|
+
@executed_tasks << process_worker
|
50
|
+
|
51
|
+
process_worker.run_as_child(@flow)
|
52
|
+
else
|
53
|
+
@owner_node.process_eval(task)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def signal_failure?
|
58
|
+
@options[:failure].nil? || @options[:failure].call
|
59
|
+
end
|
60
|
+
|
61
|
+
def signal_stop?
|
62
|
+
@options[:stop].nil? || @options[:stop].call
|
63
|
+
end
|
64
|
+
|
65
|
+
def executed_do(order)
|
66
|
+
@executed_tasks.reverse_each(&order)
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
data/lib/w_flow/version.rb
CHANGED
data/lib/w_flow.rb
CHANGED
data/w_flow.gemspec
CHANGED
@@ -9,8 +9,8 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["junhanamaki"]
|
10
10
|
spec.email = ["jun.hanamaki@gmail.com"]
|
11
11
|
|
12
|
-
spec.summary = %q{A workflow composer based on Single Responsability Principle
|
13
|
-
spec.description = %q{WFlow is a workflow composer that helps in
|
12
|
+
spec.summary = %q{A workflow composer based on Single Responsability Principle}
|
13
|
+
spec.description = %q{WFlow is a workflow composer that helps in code organization by splitting logic into reusable modules, more at https://github.com/junhanamaki/w_flow}
|
14
14
|
spec.homepage = "https://github.com/junhanamaki/w_flow"
|
15
15
|
|
16
16
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
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.12.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-06-
|
11
|
+
date: 2015-06-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -80,8 +80,8 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0.4'
|
83
|
-
description: WFlow is a workflow composer that helps in
|
84
|
-
logic into reusable modules
|
83
|
+
description: WFlow is a workflow composer that helps in code organization by splitting
|
84
|
+
logic into reusable modules, more at https://github.com/junhanamaki/w_flow
|
85
85
|
email:
|
86
86
|
- jun.hanamaki@gmail.com
|
87
87
|
executables: []
|
@@ -100,10 +100,12 @@ files:
|
|
100
100
|
- lib/w_flow/flow.rb
|
101
101
|
- lib/w_flow/flow_report.rb
|
102
102
|
- lib/w_flow/node.rb
|
103
|
+
- lib/w_flow/node_worker.rb
|
103
104
|
- lib/w_flow/process.rb
|
104
105
|
- lib/w_flow/process_worker.rb
|
105
106
|
- lib/w_flow/supervisor.rb
|
106
107
|
- lib/w_flow/supervisor_report.rb
|
108
|
+
- lib/w_flow/tasks_worker.rb
|
107
109
|
- lib/w_flow/version.rb
|
108
110
|
- w_flow.gemspec
|
109
111
|
homepage: https://github.com/junhanamaki/w_flow
|
@@ -129,6 +131,5 @@ rubyforge_project:
|
|
129
131
|
rubygems_version: 2.4.7
|
130
132
|
signing_key:
|
131
133
|
specification_version: 4
|
132
|
-
summary: A workflow composer based on Single Responsability Principle
|
133
|
-
projects
|
134
|
+
summary: A workflow composer based on Single Responsability Principle
|
134
135
|
test_files: []
|