dynflow 0.4.1 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/dynflow/action.rb +27 -4
- data/lib/dynflow/execution_plan.rb +4 -10
- data/lib/dynflow/execution_plan/steps/abstract.rb +2 -0
- data/lib/dynflow/execution_plan/steps/plan_step.rb +4 -0
- data/lib/dynflow/testing/factories.rb +14 -0
- data/lib/dynflow/version.rb +1 -1
- data/test/action_test.rb +1 -3
- data/test/execution_plan_test.rb +6 -6
- data/test/support/code_workflow_example.rb +2 -3
- metadata +2 -2
data/lib/dynflow/action.rb
CHANGED
@@ -21,16 +21,18 @@ module Dynflow
|
|
21
21
|
require 'dynflow/action/cancellable_polling'
|
22
22
|
|
23
23
|
def self.all_children
|
24
|
-
children.inject(children)
|
24
|
+
children.values.inject(children.values) do |children, child|
|
25
|
+
children + child.all_children
|
26
|
+
end
|
25
27
|
end
|
26
28
|
|
27
29
|
def self.inherited(child)
|
28
|
-
children
|
30
|
+
children[child.name] = child
|
29
31
|
super child
|
30
32
|
end
|
31
33
|
|
32
34
|
def self.children
|
33
|
-
@children ||=
|
35
|
+
@children ||= {}
|
34
36
|
end
|
35
37
|
|
36
38
|
def self.middleware
|
@@ -154,6 +156,27 @@ module Dynflow
|
|
154
156
|
execution_plan.steps.fetch(plan_step_id)
|
155
157
|
end
|
156
158
|
|
159
|
+
# @param [Class] filter_class return only actions which are kind of `filter_class`
|
160
|
+
# @return [Array<Action>] of directly planned actions by this action,
|
161
|
+
# returned actions are in Present phase
|
162
|
+
def planned_actions(filter = Action)
|
163
|
+
phase! Present
|
164
|
+
plan_step.
|
165
|
+
planned_steps(execution_plan).
|
166
|
+
map { |s| s.action execution_plan }.
|
167
|
+
select { |a| a.is_a?(filter) }
|
168
|
+
end
|
169
|
+
|
170
|
+
# @param [Class] filter_class return only actions which are kind of `filter_class`
|
171
|
+
# @return [Array<Action>] of all (including indirectly) planned actions by this action,
|
172
|
+
# returned actions are in Present phase
|
173
|
+
def all_planned_actions(filter_class = Action)
|
174
|
+
phase! Present
|
175
|
+
mine = planned_actions
|
176
|
+
(mine + mine.reduce([]) { |arr, action| arr + action.all_planned_actions }).
|
177
|
+
select { |a| a.is_a?(filter_class) }
|
178
|
+
end
|
179
|
+
|
157
180
|
def run_step
|
158
181
|
phase! Present
|
159
182
|
execution_plan.steps.fetch(run_step_id) if run_step_id
|
@@ -283,7 +306,7 @@ module Dynflow
|
|
283
306
|
@execution_plan.switch_flow(Flows::Sequence.new([]), &block)
|
284
307
|
end
|
285
308
|
|
286
|
-
def plan_self(input)
|
309
|
+
def plan_self(input = {})
|
287
310
|
phase! Plan
|
288
311
|
self.input.update input
|
289
312
|
|
@@ -264,18 +264,12 @@ module Dynflow
|
|
264
264
|
plan_total > 0 ? (plan_done / plan_total) : 1
|
265
265
|
end
|
266
266
|
|
267
|
-
#
|
268
|
-
#
|
269
|
-
# @return [Array<Action::Presenter>] presenter of the actions
|
270
|
-
# involved in the plan
|
267
|
+
# @return [Array<Action>] actions in Present phase, consider using
|
268
|
+
# Steps::Abstract#action instead
|
271
269
|
def actions
|
272
270
|
@actions ||= begin
|
273
|
-
action_ids = steps.
|
274
|
-
action_ids.map
|
275
|
-
attributes = world.persistence.adapter.load_action(id, action_id)
|
276
|
-
Action.from_hash(attributes.update(phase: Action::Present, execution_plan: self),
|
277
|
-
world)
|
278
|
-
end
|
271
|
+
action_ids = steps.reduce({}) { |h, (_, s)| h.update s.action_id => s }
|
272
|
+
action_ids.map { |_, step| step.action self }
|
279
273
|
end
|
280
274
|
end
|
281
275
|
|
@@ -86,6 +86,8 @@ module Dynflow
|
|
86
86
|
raise NotImplementedError, "Expected to be implemented in RunStep and FinalizeStep"
|
87
87
|
end
|
88
88
|
|
89
|
+
# @return [Action] in presentation mode, intended for retrieving: progress information,
|
90
|
+
# details, human outputs, etc.
|
89
91
|
def action(execution_plan)
|
90
92
|
attributes = world.persistence.adapter.load_action(execution_plan_id, action_id)
|
91
93
|
Action.from_hash(attributes.update(phase: Action::Present, execution_plan: execution_plan),
|
@@ -20,6 +20,20 @@ module Dynflow
|
|
20
20
|
execution_plan.world)
|
21
21
|
end
|
22
22
|
|
23
|
+
def create_action_presentation(action_class)
|
24
|
+
execution_plan = DummyExecutionPlan.new
|
25
|
+
action_class.new(
|
26
|
+
{ execution_plan: execution_plan,
|
27
|
+
execution_plan_id: execution_plan.id,
|
28
|
+
id: Testing.get_id,
|
29
|
+
phase: Action::Present,
|
30
|
+
plan_step_id: 1,
|
31
|
+
run_step_id: nil,
|
32
|
+
finalize_step_id: nil,
|
33
|
+
input: nil },
|
34
|
+
execution_plan.world)
|
35
|
+
end
|
36
|
+
|
23
37
|
# @return [Action::PlanPhase]
|
24
38
|
def plan_action(plan_action, *args, &block)
|
25
39
|
Match! plan_action.phase, Action::Plan
|
data/lib/dynflow/version.rb
CHANGED
data/test/action_test.rb
CHANGED
@@ -61,9 +61,7 @@ module Dynflow
|
|
61
61
|
end
|
62
62
|
|
63
63
|
let :presenter do
|
64
|
-
execution_plan.
|
65
|
-
action.is_a? Support::CodeWorkflowExample::IncomingIssues
|
66
|
-
end
|
64
|
+
execution_plan.root_plan_step.action execution_plan
|
67
65
|
end
|
68
66
|
|
69
67
|
specify { presenter.class.must_equal Support::CodeWorkflowExample::IncomingIssues }
|
data/test/execution_plan_test.rb
CHANGED
@@ -64,7 +64,7 @@ module Dynflow
|
|
64
64
|
describe 'for error in running phase' do
|
65
65
|
|
66
66
|
before do
|
67
|
-
step_id
|
67
|
+
step_id = execution_plan.run_flow.all_step_ids[2]
|
68
68
|
execution_plan.steps[step_id].set_state :error, true
|
69
69
|
end
|
70
70
|
|
@@ -77,7 +77,7 @@ module Dynflow
|
|
77
77
|
describe 'for pending step in running phase' do
|
78
78
|
|
79
79
|
before do
|
80
|
-
step_id
|
80
|
+
step_id = execution_plan.run_flow.all_step_ids[2]
|
81
81
|
execution_plan.steps[step_id].set_state :pending, true
|
82
82
|
end
|
83
83
|
|
@@ -239,10 +239,10 @@ module Dynflow
|
|
239
239
|
world.plan(Support::CodeWorkflowExample::IncomingIssues, issues_data)
|
240
240
|
end
|
241
241
|
|
242
|
-
it 'provides the access to the actions data via
|
243
|
-
execution_plan.
|
244
|
-
execution_plan.
|
245
|
-
action.phase.must_equal Action::Present
|
242
|
+
it 'provides the access to the actions data via steps #action' do
|
243
|
+
execution_plan.steps.size.must_equal 20
|
244
|
+
execution_plan.steps.each do |_, step|
|
245
|
+
step.action(execution_plan).phase.must_equal Action::Present
|
246
246
|
end
|
247
247
|
end
|
248
248
|
end
|
@@ -24,9 +24,8 @@ module Support
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def summary
|
27
|
-
|
28
|
-
|
29
|
-
end
|
27
|
+
# TODO fix, not a good pattern, it should delegate to IncomingIssue first
|
28
|
+
triages = all_planned_actions(Triage)
|
30
29
|
assignees = triages.map do |triage|
|
31
30
|
triage.output[:classification] &&
|
32
31
|
triage.output[:classification][:assignee]
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dynflow
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-02-
|
12
|
+
date: 2014-02-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|