trailblazer-activity 0.4.2 → 0.4.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/CHANGES.md +7 -0
- data/README.md +1 -1
- data/inspeccccccccct.rb +19 -0
- data/lib/trailblazer/activity.rb +2 -1
- data/lib/trailblazer/activity/dsl/helper.rb +8 -0
- data/lib/trailblazer/activity/implementation/build_state.rb +1 -0
- data/lib/trailblazer/activity/implementation/path.rb +2 -34
- data/lib/trailblazer/activity/implementation/plan.rb +36 -0
- data/lib/trailblazer/activity/implementation/railway.rb +3 -3
- data/lib/trailblazer/activity/introspect.rb +20 -7
- data/lib/trailblazer/activity/magnetic.rb +2 -2
- data/lib/trailblazer/activity/magnetic/builder.rb +8 -15
- data/lib/trailblazer/activity/magnetic/builder/normalizer.rb +26 -26
- data/lib/trailblazer/activity/magnetic/builder/path.rb +10 -9
- data/lib/trailblazer/activity/magnetic/builder/railway.rb +4 -5
- data/lib/trailblazer/activity/magnetic/dsl.rb +6 -6
- data/lib/trailblazer/activity/magnetic/{dsl → structure}/alterations.rb +0 -0
- data/lib/trailblazer/activity/magnetic/structure/plus_poles.rb +92 -0
- data/lib/trailblazer/activity/structures.rb +2 -1
- data/lib/trailblazer/activity/task_builder.rb +5 -0
- data/lib/trailblazer/activity/task_wrap.rb +30 -24
- data/lib/trailblazer/activity/version.rb +1 -1
- metadata +6 -4
- data/lib/trailblazer/activity/magnetic/dsl/plus_poles.rb +0 -59
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b12275a2f1dfc9e9c90d7b3df76d2eab01db0964c453d61a23a307296cda2378
|
4
|
+
data.tar.gz: 93b881493ecec9eb50516cb1185ff1129c6fbc5efe478bc429604adae077c552
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7245451409ba95340e9a3ef5e9404df93b3e2f7aa9325fe2132bc45f4f7fbcd49370200dfe9532fb5fa8f4307fdd3f4c6eae480920927e232228361712ac8cef
|
7
|
+
data.tar.gz: a127529dea689958ff467558c6a373b37cfe0e2e2475b99b24f854488b672ff012cb8cccdfc3b02339e1b20e62eecbd92e5148fbe7e80ad5da7b8242e7f2c793
|
data/.travis.yml
CHANGED
data/CHANGES.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
# 0.4.3
|
2
|
+
|
3
|
+
* Make `:outputs` the canonical way to define outputs, and not `:plus_poles`. The latter is computed by the DSL if not passed.
|
4
|
+
* Allow injecting `inspect` implementations into `Introspect` methods.
|
5
|
+
* Add `Nested`.
|
6
|
+
* Add `TaskBuilder::Task#to_s`.
|
7
|
+
|
1
8
|
# 0.4.2
|
2
9
|
|
3
10
|
* `End` is not a `Struct` so we can maintain more state, and are immutable.
|
data/README.md
CHANGED
@@ -4,7 +4,7 @@ The `activity` gem brings a light-weight DSL to define business processes, and t
|
|
4
4
|
|
5
5
|
A process is a set of arbitrary pieces of logic you define, chained together and put into a meaningful context by an activity. Activity lets you focus on the implementation of steps while Trailblazer takes care of the control flow.
|
6
6
|
|
7
|
-
Please find the [full documentation on the Trailblazer website](http://trailblazer.to/
|
7
|
+
Please find the [full documentation on the Trailblazer website](http://trailblazer.to/api-docs). [Note that the docs are WIP.]
|
8
8
|
|
9
9
|
## Example
|
10
10
|
|
data/inspeccccccccct.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
module Inspect
|
3
|
+
def inspect
|
4
|
+
"nice view!"
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
module A
|
9
|
+
extend Inspect
|
10
|
+
|
11
|
+
def self.a
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# jruby 9.1.7
|
16
|
+
puts A.method(:a).inspect #=> #<Method: A.a>
|
17
|
+
# 2.5
|
18
|
+
puts A.method(:a).inspect #=> #<Method: nice view!.a>
|
19
|
+
|
data/lib/trailblazer/activity.rb
CHANGED
@@ -42,7 +42,7 @@ module Trailblazer
|
|
42
42
|
module DSLHelper
|
43
43
|
extend Forwardable
|
44
44
|
def_delegators :@builder, :Path
|
45
|
-
def_delegators DSL::Helper, :Output, :End
|
45
|
+
def_delegators DSL::Helper, :Output, :End, :Nested
|
46
46
|
|
47
47
|
def Path(*args, &block)
|
48
48
|
self[:builder].Path(*args, &block)
|
@@ -95,6 +95,7 @@ require "trailblazer/activity/config"
|
|
95
95
|
require "trailblazer/activity/implementation/build_state"
|
96
96
|
require "trailblazer/activity/implementation/interface"
|
97
97
|
require "trailblazer/activity/implementation/path"
|
98
|
+
require "trailblazer/activity/implementation/plan"
|
98
99
|
require "trailblazer/activity/implementation/railway"
|
99
100
|
require "trailblazer/activity/implementation/fast_track"
|
100
101
|
|
@@ -22,6 +22,7 @@ class Trailblazer::Activity < Module
|
|
22
22
|
return normalizer, options
|
23
23
|
end
|
24
24
|
|
25
|
+
# @api private
|
25
26
|
def self.build_state(normalizer, builder_class:, builder_options: {}, **options)
|
26
27
|
builder, adds, circuit, outputs = State.build(builder_class, normalizer, options.merge(builder_options))
|
27
28
|
|
@@ -11,45 +11,13 @@ module Trailblazer
|
|
11
11
|
{
|
12
12
|
builder_class: Magnetic::Builder::Path, # we use the Activity-based Normalizer
|
13
13
|
normalizer_class: Magnetic::Normalizer,
|
14
|
-
|
14
|
+
default_outputs: Magnetic::Builder::Path.default_outputs,
|
15
15
|
extension: [ Introspect.method(:add_introspection) ],
|
16
16
|
|
17
17
|
extend: [ DSL.def_dsl(:task) ],
|
18
18
|
}
|
19
19
|
end
|
20
|
-
|
21
|
-
def self.Plan()
|
22
|
-
Plan
|
23
|
-
end
|
24
|
-
|
25
|
-
module Plan
|
26
|
-
def self.extended(extended)
|
27
|
-
extended.singleton_class.send :attr_accessor, :record
|
28
|
-
extended.record = []
|
29
|
-
extended.extend(Methods)
|
30
|
-
end
|
31
|
-
|
32
|
-
module Methods
|
33
|
-
def task(*args, &block)
|
34
|
-
record << [:task, args, block]
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def self.merge!(activity, plan)
|
39
|
-
plan.record.each { |(dsl_method, args, block)| activity.send(dsl_method, *args, &block) }
|
40
|
-
activity
|
41
|
-
end
|
42
|
-
|
43
|
-
# Creates a copy of the {activity} module and merges the {Plan} into it.
|
44
|
-
#
|
45
|
-
# @params activity [Activity] The activity to extend
|
46
|
-
# @params plan [Plan] The plan providing additional steps
|
47
|
-
# @return [Activity] A new, merged activity
|
48
|
-
def self.merge(activity, plan)
|
49
|
-
merge!(activity.clone, plan)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
20
|
+
end # Path
|
53
21
|
end
|
54
22
|
end
|
55
23
|
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Trailblazer
|
2
|
+
class Activity::Path < Activity
|
3
|
+
def self.Plan()
|
4
|
+
Plan
|
5
|
+
end
|
6
|
+
|
7
|
+
module Plan
|
8
|
+
def self.extended(extended)
|
9
|
+
extended.singleton_class.send :attr_accessor, :record
|
10
|
+
extended.record = []
|
11
|
+
extended.extend(Methods)
|
12
|
+
end
|
13
|
+
|
14
|
+
module Methods
|
15
|
+
def task(*args, &block)
|
16
|
+
record << [:task, args, block]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.merge!(activity, plan)
|
21
|
+
plan.record.each { |(dsl_method, args, block)| activity.send(dsl_method, *args, &block) }
|
22
|
+
activity
|
23
|
+
end
|
24
|
+
|
25
|
+
# Creates a copy of the {activity} module and merges the {Plan} into it.
|
26
|
+
#
|
27
|
+
# @params activity [Activity] The activity to extend
|
28
|
+
# @params plan [Plan] The plan providing additional steps
|
29
|
+
# @return [Activity] A new, merged activity
|
30
|
+
def self.merge(activity, plan)
|
31
|
+
merge!(activity.clone, plan)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
@@ -8,9 +8,9 @@ module Trailblazer
|
|
8
8
|
class Railway < Activity
|
9
9
|
def self.config
|
10
10
|
Path.config.merge(
|
11
|
-
builder_class:
|
12
|
-
|
13
|
-
extend:
|
11
|
+
builder_class: Magnetic::Builder::Railway,
|
12
|
+
default_outputs: Magnetic::Builder::Railway.default_outputs,
|
13
|
+
extend: [ DSL.def_dsl(:step), DSL.def_dsl(:fail), DSL.def_dsl(:pass) ],
|
14
14
|
)
|
15
15
|
end
|
16
16
|
end
|
@@ -35,6 +35,11 @@ module Trailblazer
|
|
35
35
|
end
|
36
36
|
|
37
37
|
|
38
|
+
def self.inspect_task_builder(task)
|
39
|
+
proc = task.instance_variable_get(:@user_proc)
|
40
|
+
%{#<TaskBuilder{#{proc}}>}
|
41
|
+
end
|
42
|
+
|
38
43
|
# FIXME: clean up that shit below.
|
39
44
|
|
40
45
|
# render
|
@@ -42,14 +47,14 @@ module Trailblazer
|
|
42
47
|
circuit_hash( circuit.to_h[:map], **options )
|
43
48
|
end
|
44
49
|
|
45
|
-
def self.circuit_hash(circuit_hash, show_ids:false)
|
50
|
+
def self.circuit_hash(circuit_hash, show_ids:false, **options)
|
46
51
|
content =
|
47
52
|
circuit_hash.collect do |task, connections|
|
48
53
|
conns = connections.collect do |signal, target|
|
49
|
-
" {#{signal}} => #{
|
54
|
+
" {#{signal}} => #{inspect_with_matcher(target, **options)}"
|
50
55
|
end
|
51
56
|
|
52
|
-
[
|
57
|
+
[ inspect_with_matcher(task, **options), conns.join("\n") ]
|
53
58
|
end
|
54
59
|
|
55
60
|
content = content.join("\n")
|
@@ -60,7 +65,7 @@ module Trailblazer
|
|
60
65
|
|
61
66
|
def self.Ends(activity)
|
62
67
|
end_events = activity.to_h[:end_events]
|
63
|
-
ends = end_events.collect { |evt|
|
68
|
+
ends = end_events.collect { |evt| inspect_end(evt) }.join(",")
|
64
69
|
"[#{ends}]".gsub(/\d\d+/, "")
|
65
70
|
end
|
66
71
|
|
@@ -70,9 +75,17 @@ module Trailblazer
|
|
70
75
|
join("\n").gsub(/0x\w+/, "").gsub(/\d\d+/, "")
|
71
76
|
end
|
72
77
|
|
73
|
-
|
74
|
-
|
78
|
+
# If Ruby had pattern matching, this function wasn't necessary.
|
79
|
+
def self.inspect_with_matcher(task, inspect_task: method(:inspect_task), inspect_end: method(:inspect_end))
|
80
|
+
return inspect_task.(task) unless task.kind_of?(Trailblazer::Activity::End)
|
81
|
+
inspect_end.(task)
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.inspect_task(task)
|
85
|
+
task.inspect
|
86
|
+
end
|
75
87
|
|
88
|
+
def self.inspect_end(task)
|
76
89
|
class_name = strip(task.class)
|
77
90
|
options = task.to_h
|
78
91
|
|
@@ -108,7 +121,7 @@ module Trailblazer
|
|
108
121
|
sequence.collect do |(magnetic_to, task, plus_poles)|
|
109
122
|
pluses = plus_poles.collect { |plus_pole| PlusPole(plus_pole) }
|
110
123
|
|
111
|
-
%{#{magnetic_to.inspect} ==> #{Activity::Introspect.
|
124
|
+
%{#{magnetic_to.inspect} ==> #{Activity::Introspect.inspect_with_matcher(task)}
|
112
125
|
#{pluses.empty? ? " []" : pluses.join("\n")}}
|
113
126
|
end.join("\n")
|
114
127
|
|
@@ -16,8 +16,8 @@ module Trailblazer
|
|
16
16
|
end
|
17
17
|
|
18
18
|
require "trailblazer/activity/magnetic/dsl"
|
19
|
-
require "trailblazer/activity/magnetic/
|
20
|
-
require "trailblazer/activity/magnetic/
|
19
|
+
require "trailblazer/activity/magnetic/structure/plus_poles"
|
20
|
+
require "trailblazer/activity/magnetic/structure/alterations"
|
21
21
|
|
22
22
|
require "trailblazer/activity/schema/dependencies"
|
23
23
|
|
@@ -15,6 +15,7 @@ module Trailblazer
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
+
# Called from Path/Railway/FastTrack, creates the specific {Builder} instance.
|
18
19
|
def self.Builder(implementation, normalizer, builder_options={})
|
19
20
|
builder = implementation.new(normalizer, builder_options.freeze).freeze # e.g. Path.new(...)
|
20
21
|
|
@@ -32,11 +33,14 @@ module Trailblazer
|
|
32
33
|
activity_adds + merged_adds
|
33
34
|
end
|
34
35
|
|
35
|
-
#
|
36
|
+
# DSL method to create a Path within an activity which is embedded.
|
37
|
+
#
|
38
|
+
# Output(:success) => Path() {}
|
36
39
|
def Path(*args)
|
37
40
|
Activity::DSL::Helper.Path(@normalizer, *args)
|
38
41
|
end
|
39
42
|
|
43
|
+
# Public top-level entry point.
|
40
44
|
def insert(name, task, options, &block)
|
41
45
|
normalizer = options[:normalizer] || @normalizer # DISCUSS: do this at a deeper point?
|
42
46
|
|
@@ -50,13 +54,12 @@ module Trailblazer
|
|
50
54
|
private
|
51
55
|
|
52
56
|
# Internal top-level entry point to add task(s) and connections.
|
57
|
+
# High level interface for DSL calls like ::task or ::step.
|
53
58
|
def insert_element(impl, polarizations, task, local_options, connection_options, sequence_options, &block)
|
54
59
|
adds, *returned_options = Builder.adds_for(polarizations, task, local_options, connection_options, sequence_options, &block)
|
55
60
|
end
|
56
61
|
|
57
62
|
# @return Adds
|
58
|
-
# High level interface for DSL calls like ::task or ::step.
|
59
|
-
# TODO: RETURN ALL OPTIONS
|
60
63
|
def self.adds_for(polarizations, task, local_options, connection_options, sequence_options, &block)
|
61
64
|
# go through all wiring options such as Output()=>:color.
|
62
65
|
polarizations_from_user_options, additional_adds = process_dsl_options(connection_options, local_options, &block)
|
@@ -75,7 +78,7 @@ module Trailblazer
|
|
75
78
|
# Low-level interface for DSL calls (e.g. Start, where "you know what you're doing")
|
76
79
|
# @private
|
77
80
|
def self.adds(task, polarizations, options, sequence_options, magnetic_to:nil, id:nil, plus_poles:, **) # DISCUSS: no :id ?
|
78
|
-
magnetic_to, plus_poles = apply_polarizations(
|
81
|
+
magnetic_to, plus_poles = PlusPoles.apply_polarizations(
|
79
82
|
polarizations,
|
80
83
|
magnetic_to,
|
81
84
|
plus_poles,
|
@@ -88,19 +91,9 @@ module Trailblazer
|
|
88
91
|
)
|
89
92
|
end
|
90
93
|
|
91
|
-
# Called once per DSL method call, e.g. ::step.
|
92
|
-
#
|
93
|
-
# The idea is to chain a bunch of PlusPoles transformations (and magnetic_to "transformations")
|
94
|
-
# for each DSL call, and thus realize things like path+railway+fast_track
|
95
|
-
def self.apply_polarizations(polarizations, magnetic_to, plus_poles, options)
|
96
|
-
polarizations.inject([magnetic_to, plus_poles]) do |args, pol|
|
97
|
-
magnetic, plus_poles = pol.(*args, options)
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
94
|
def self.Add(id, task, magnetic_to, plus_poles, options, sequence_options)
|
102
95
|
[
|
103
|
-
[ :add, [id, [ magnetic_to, task, plus_poles
|
96
|
+
[ :add, [id, [ magnetic_to, task, plus_poles ], sequence_options] ],
|
104
97
|
]
|
105
98
|
end
|
106
99
|
end # Builder
|
@@ -1,40 +1,33 @@
|
|
1
1
|
module Trailblazer
|
2
2
|
module Activity::Magnetic
|
3
|
-
#
|
3
|
+
# One {Normalizer} instance is called for every DSL call (step/pass/fail etc.) and normalizes/defaults
|
4
4
|
# the user options, such as setting `:id`, connecting the task's outputs or wrapping the user's
|
5
5
|
# task via {TaskBuilder::Binary} in order to translate true/false to `Right` or `Left`.
|
6
6
|
#
|
7
7
|
# The Normalizer sits in the `@builder`, which receives all DSL calls from the Operation subclass.
|
8
8
|
class Normalizer
|
9
|
-
def self.build(task_builder: Activity::TaskBuilder::Binary,
|
9
|
+
def self.build(task_builder: Activity::TaskBuilder::Binary, default_outputs: Builder::Path.default_outputs, pipeline: Pipeline, extension:[], **options)
|
10
10
|
return new(
|
11
|
-
|
12
|
-
extension:
|
13
|
-
task_builder:
|
14
|
-
pipeline:
|
11
|
+
default_outputs: default_outputs,
|
12
|
+
extension: extension,
|
13
|
+
task_builder: task_builder,
|
14
|
+
pipeline: pipeline,
|
15
15
|
), options
|
16
16
|
end
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
Activity.Output(Activity::Left, :failure) => nil,
|
23
|
-
)
|
24
|
-
end
|
25
|
-
|
26
|
-
def initialize(task_builder:, default_plus_poles:, pipeline:, **options)
|
27
|
-
@task_builder = task_builder
|
28
|
-
@default_plus_poles = default_plus_poles
|
29
|
-
@pipeline = pipeline # TODO: test me.
|
18
|
+
def initialize(task_builder:, default_outputs:, pipeline:, **options)
|
19
|
+
@task_builder = task_builder
|
20
|
+
@default_outputs = default_outputs
|
21
|
+
@pipeline = pipeline # TODO: test me.
|
30
22
|
freeze
|
31
23
|
end
|
32
24
|
|
33
25
|
def call(task, options)
|
34
26
|
ctx = {
|
35
|
-
task:
|
36
|
-
|
37
|
-
|
27
|
+
task: task,
|
28
|
+
options: options,
|
29
|
+
task_builder: @task_builder,
|
30
|
+
default_outputs: @default_outputs,
|
38
31
|
}
|
39
32
|
|
40
33
|
signal, (ctx, ) = @pipeline.( [ctx] )
|
@@ -46,7 +39,7 @@ module Trailblazer
|
|
46
39
|
|
47
40
|
# :default_plus_poles is an injectable option.
|
48
41
|
module Pipeline
|
49
|
-
extend Trailblazer::Activity::Path( normalizer_class: DefaultNormalizer, plus_poles: Builder::Path.
|
42
|
+
extend Trailblazer::Activity::Path( normalizer_class: DefaultNormalizer, plus_poles: PlusPoles.new.merge( Builder::Path.default_outputs.values ) ) # FIXME: the DefaultNormalizer actually doesn't need Left.
|
50
43
|
|
51
44
|
def self.split_options( ctx, task:, options:, ** )
|
52
45
|
keywords = extract_dsl_keywords(options)
|
@@ -84,11 +77,18 @@ module Trailblazer
|
|
84
77
|
end
|
85
78
|
end
|
86
79
|
|
87
|
-
#
|
88
|
-
|
80
|
+
# :outputs passed: I know what I want to have connected.
|
81
|
+
# no :outputs: use default_outputs
|
82
|
+
# ALWAYS connect all outputs to their semantic-color.
|
83
|
+
|
84
|
+
# Create the `plus_poles: <PlusPoles>` tuple where the PlusPoles instance will act as the interface
|
85
|
+
# to rewire or add connections for the DSL.
|
86
|
+
def self.initialize_plus_poles( ctx, local_options:, default_outputs:, ** )
|
87
|
+
outputs = local_options[:outputs] || default_outputs
|
88
|
+
|
89
89
|
ctx[:local_options] =
|
90
90
|
{
|
91
|
-
plus_poles:
|
91
|
+
plus_poles: PlusPoles.initial(outputs),
|
92
92
|
}
|
93
93
|
.merge(local_options)
|
94
94
|
end
|
@@ -96,7 +96,7 @@ module Trailblazer
|
|
96
96
|
task Activity::TaskBuilder::Binary.( method(:normalize_for_macro) ), id: "normalize_for_macro"
|
97
97
|
task Activity::TaskBuilder::Binary.( method(:split_options) ), id: "split_options"
|
98
98
|
task Activity::TaskBuilder::Binary.( method(:normalize_extension_option) ), id: "normalize_extension_option"
|
99
|
-
task Activity::TaskBuilder::Binary.( method(:
|
99
|
+
task Activity::TaskBuilder::Binary.( method(:initialize_plus_poles) ), id: "initialize_plus_poles"
|
100
100
|
# task ->((ctx, _), **) { pp ctx; [Activity::Right, [ctx, _]] }
|
101
101
|
end
|
102
102
|
end # Normalizer
|
@@ -20,15 +20,16 @@ module Trailblazer
|
|
20
20
|
return Path, polarizations, task, options, block
|
21
21
|
end
|
22
22
|
|
23
|
-
|
24
|
-
def self.
|
25
|
-
|
26
|
-
Activity.Output(
|
27
|
-
|
23
|
+
# @private Might be removed.
|
24
|
+
def self.default_outputs
|
25
|
+
{
|
26
|
+
success: Activity.Output(Activity::Right, :success),
|
27
|
+
# failure: Activity.Output(Activity::Left, :failure),
|
28
|
+
}
|
28
29
|
end
|
29
30
|
|
30
31
|
# @return [Adds] list of Adds instances that can be chained or added to an existing sequence.
|
31
|
-
def self.InitialAdds(track_color:raise, end_semantic:raise,
|
32
|
+
def self.InitialAdds(track_color:raise, end_semantic:raise, start_outputs: {success: self.default_outputs[:success]}, track_end: Activity.End(end_semantic), **)
|
32
33
|
|
33
34
|
builder_options={ track_color: track_color, end_semantic: end_semantic }
|
34
35
|
|
@@ -41,7 +42,7 @@ module Trailblazer
|
|
41
42
|
|
42
43
|
id: "Start.default",
|
43
44
|
magnetic_to: [],
|
44
|
-
plus_poles:
|
45
|
+
plus_poles: PlusPoles.initial(start_outputs), # FIXME: this is actually redundant with Normalizer
|
45
46
|
)
|
46
47
|
|
47
48
|
end_adds = adds(
|
@@ -59,14 +60,14 @@ module Trailblazer
|
|
59
60
|
start_adds + end_adds
|
60
61
|
end
|
61
62
|
|
62
|
-
def self.TaskPolarizations(track_color
|
63
|
+
def self.TaskPolarizations(track_color:, type: :task, **)
|
63
64
|
return [EndPolarization.new( track_color: track_color )] if type == :End # DISCUSS: should this dispatch be here?
|
64
65
|
|
65
66
|
[TaskPolarization.new( track_color: track_color )]
|
66
67
|
end
|
67
68
|
|
68
69
|
class TaskPolarization
|
69
|
-
def initialize(
|
70
|
+
def initialize(track_color:)
|
70
71
|
@track_color = track_color
|
71
72
|
end
|
72
73
|
|
@@ -22,11 +22,10 @@ module Trailblazer
|
|
22
22
|
return Railway, Railway.PassPolarizations(@builder_options), task, options, block
|
23
23
|
end
|
24
24
|
|
25
|
-
def self.
|
26
|
-
|
27
|
-
Activity.Output(Activity::
|
28
|
-
|
29
|
-
).freeze
|
25
|
+
def self.default_outputs
|
26
|
+
Path.default_outputs.merge(
|
27
|
+
:failure => Activity.Output(Activity::Left, :failure),
|
28
|
+
)
|
30
29
|
end
|
31
30
|
|
32
31
|
# Adds the End.failure end to the Path sequence.
|
@@ -28,30 +28,30 @@ module Trailblazer
|
|
28
28
|
# options:
|
29
29
|
# { DSL::Output[::Semantic] => target }
|
30
30
|
#
|
31
|
-
def call(id, options,
|
31
|
+
def call(id, options, plus_poles, &block)
|
32
32
|
polarization, adds =
|
33
33
|
options.
|
34
34
|
collect { |key, task|
|
35
35
|
# this method call is the only thing that really matters here. # TODO: make this transformation a bit more obvious.
|
36
|
-
process_tuple(id, key, task,
|
36
|
+
process_tuple(id, key, task, plus_poles, &block)
|
37
37
|
}.
|
38
38
|
inject([[],[]]) { |memo, (polarization, adds)| memo[0]<<polarization; memo[1]<<adds; memo }
|
39
39
|
|
40
40
|
return polarization, adds.flatten(1)
|
41
41
|
end
|
42
42
|
|
43
|
-
def process_tuple(id, output, task,
|
44
|
-
output = output_for(output,
|
43
|
+
def process_tuple(id, output, task, plus_poles, &block)
|
44
|
+
output = output_for(output, plus_poles) if output.kind_of?(DSL::Output::Semantic)
|
45
45
|
|
46
46
|
if task.kind_of?(Activity::End)
|
47
47
|
new_edge = "#{id}-#{output.signal}"
|
48
48
|
|
49
49
|
[
|
50
50
|
Polarization.new( output: output, color: new_edge ),
|
51
|
-
[ [:add, [task.
|
51
|
+
[ [:add, [task.to_h[:semantic], [ [new_edge], task, [] ], group: :end]] ]
|
52
52
|
]
|
53
53
|
elsif task.is_a?(String) # let's say this means an existing step
|
54
|
-
new_edge = "#{output.signal}-#{task}"
|
54
|
+
new_edge = "#{id}-#{output.signal}-#{task}"
|
55
55
|
|
56
56
|
[
|
57
57
|
Polarization.new( output: output, color: new_edge ),
|
File without changes
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module Trailblazer
|
2
|
+
module Activity::Magnetic
|
3
|
+
# A plus pole is associating an Output{:signal, :semantic} to a magnetic :color.
|
4
|
+
#
|
5
|
+
# When it comes to connecting tasks to each other, PlusPoles is the most important object
|
6
|
+
# here. When a task is added via the DSL, a PlusPoles is set up, and the DSL adds polarizations
|
7
|
+
# from the implementation and from the options (e.g. `Outputs(..) => ..`).
|
8
|
+
#
|
9
|
+
# These are then finalized and return the effective plus poles
|
10
|
+
|
11
|
+
# Polarization is one or multiple calls to PlusPoles
|
12
|
+
|
13
|
+
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
# Output(:signal, :semantic) => :color
|
18
|
+
# add / merge
|
19
|
+
# change existing, => color
|
20
|
+
#
|
21
|
+
#
|
22
|
+
# Produces [ PlusPole, PlusPole, ] via `to_a`.
|
23
|
+
#
|
24
|
+
# @privat
|
25
|
+
# @note This is private until we know what we want.
|
26
|
+
class PlusPoles
|
27
|
+
def initialize(plus_poles={})
|
28
|
+
@plus_poles = plus_poles.freeze
|
29
|
+
end
|
30
|
+
|
31
|
+
# merge( Activity::Magnetic.Output(Right, :success) => :success
|
32
|
+
def merge(output_to_color)
|
33
|
+
overrides = ::Hash[ output_to_color.collect { |output, color| [ output.semantic, [output, color] ] } ]
|
34
|
+
PlusPoles.new(@plus_poles.merge(overrides))
|
35
|
+
end
|
36
|
+
|
37
|
+
def reverse_merge(output_to_color)
|
38
|
+
existing_colors = @plus_poles.values.collect { |pole_cfg| pole_cfg.last }
|
39
|
+
|
40
|
+
# filter all outputs with a color that already exists.
|
41
|
+
overrides = output_to_color.find_all { |output, color| !existing_colors.include?(color) }
|
42
|
+
merge(overrides)
|
43
|
+
end
|
44
|
+
|
45
|
+
def reconnect(semantic_to_color)
|
46
|
+
ary = semantic_to_color.collect do |semantic, color|
|
47
|
+
existing_output, _ = @plus_poles[semantic]
|
48
|
+
|
49
|
+
next unless existing_output
|
50
|
+
|
51
|
+
[ Activity.Output(existing_output.signal, existing_output.semantic), color ]
|
52
|
+
end
|
53
|
+
|
54
|
+
merge( ::Hash[ary.compact] )
|
55
|
+
end
|
56
|
+
|
57
|
+
# Compile one {PlusPoles} instance from all a sequence of {Polarization}s.
|
58
|
+
# This is usually called once per `step` DSL call.
|
59
|
+
#
|
60
|
+
# @api private
|
61
|
+
def self.apply_polarizations(polarizations, magnetic_to, plus_poles, options)
|
62
|
+
magnetic_to, plus_poles = polarizations.inject([magnetic_to, plus_poles]) do |args, pol|
|
63
|
+
magnetic_to, plus_poles = pol.(*args, options)
|
64
|
+
end
|
65
|
+
|
66
|
+
return magnetic_to, plus_poles.to_a
|
67
|
+
end
|
68
|
+
|
69
|
+
# The DSL is a series of transformations that yield in tasks with several PlusPole instances each.
|
70
|
+
#
|
71
|
+
# @api private
|
72
|
+
def to_a
|
73
|
+
@plus_poles.values.collect { |output, color| PlusPole.new(output, color) }
|
74
|
+
end
|
75
|
+
|
76
|
+
# Builds PlusPoles from { semantic => Output }, which, surprisingly, is exactly what Activity::outputs looks like.
|
77
|
+
# The plus pole's color is set to the output's semantic.
|
78
|
+
def self.from_outputs(outputs)
|
79
|
+
ary = outputs.collect { |semantic, output| [ output, semantic ] }
|
80
|
+
|
81
|
+
new.merge(::Hash[ary])
|
82
|
+
end
|
83
|
+
|
84
|
+
# FIXME: should this be a hash or whatever?
|
85
|
+
#
|
86
|
+
# @return Hash All {Output}s mapped to their semantic: `{ Output(Right, :success) => :success }`
|
87
|
+
def self.initial(outputs)
|
88
|
+
new.merge(Hash[ outputs.collect { |semantic, output| [output, semantic] } ])
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Trailblazer
|
2
2
|
class Activity < Module # End event is just another callable task.
|
3
|
-
# Builds an Activity::End instance.
|
3
|
+
# Builds an {Activity::End} instance.
|
4
4
|
def self.End(semantic)
|
5
5
|
End.new(semantic: semantic)
|
6
6
|
end
|
@@ -48,6 +48,7 @@
|
|
48
48
|
# semantic: the original "semantic" or role of the signal, such as :success. This usually comes from the activity hosting this output.
|
49
49
|
Output = Struct.new(:signal, :semantic)
|
50
50
|
|
51
|
+
# Builds an {Activity::Output} instance.
|
51
52
|
def self.Output(signal, color)
|
52
53
|
Output.new(signal, color).freeze
|
53
54
|
end
|
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
module Trailblazer
|
2
|
+
class Activity < Module
|
2
3
|
#
|
3
4
|
# Example with tracing:
|
4
5
|
#
|
@@ -8,39 +9,44 @@ class Trailblazer::Activity < Module
|
|
8
9
|
# |-- Call (call actual task) id: "task_wrap.call_task"
|
9
10
|
# |-- Trace.capture_return [optional]
|
10
11
|
# |-- Wrap::End
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
module TaskWrap
|
13
|
+
# The actual activity that implements the taskWrap.
|
14
|
+
def self.initial_activity
|
15
|
+
Module.new do
|
16
|
+
extend Trailblazer::Activity::Path(
|
17
|
+
name: "taskWrap",
|
18
|
+
normalizer_class: Magnetic::DefaultNormalizer,
|
19
|
+
plus_poles: Magnetic::PlusPoles.initial( :success => Magnetic::Builder::Path.default_outputs[:success] ) # DefaultNormalizer doesn't give us default PlusPoles.
|
20
|
+
)
|
16
21
|
|
17
|
-
|
22
|
+
task TaskWrap.method(:call_task), id: "task_wrap.call_task" # ::call_task is defined in task_wrap/call_task.
|
23
|
+
end
|
18
24
|
end
|
19
|
-
end
|
20
|
-
|
21
|
-
# Compute runtime arguments necessary to execute a taskWrap per task of the activity.
|
22
|
-
def self.arguments_for_call(activity, (options, flow_options), **circuit_options)
|
23
|
-
circuit_options = circuit_options.merge(
|
24
|
-
runner: TaskWrap::Runner,
|
25
|
-
wrap_runtime: circuit_options[:wrap_runtime] || {},
|
26
|
-
wrap_static: activity[:wrap_static] || {},
|
27
|
-
)
|
28
25
|
|
29
|
-
|
30
|
-
end
|
31
|
-
|
32
|
-
module NonStatic
|
26
|
+
# Compute runtime arguments necessary to execute a taskWrap per task of the activity.
|
33
27
|
def self.arguments_for_call(activity, (options, flow_options), **circuit_options)
|
34
28
|
circuit_options = circuit_options.merge(
|
35
29
|
runner: TaskWrap::Runner,
|
36
|
-
wrap_runtime: circuit_options[:wrap_runtime] || {},
|
37
|
-
wrap_static:
|
30
|
+
wrap_runtime: circuit_options[:wrap_runtime] || {},
|
31
|
+
wrap_static: activity[:wrap_static] || {},
|
38
32
|
)
|
39
33
|
|
40
34
|
return activity, [ options, flow_options ], circuit_options
|
41
35
|
end
|
42
|
-
end
|
43
36
|
|
44
|
-
|
37
|
+
module NonStatic
|
38
|
+
def self.arguments_for_call(activity, (options, flow_options), **circuit_options)
|
39
|
+
circuit_options = circuit_options.merge(
|
40
|
+
runner: TaskWrap::Runner,
|
41
|
+
wrap_runtime: circuit_options[:wrap_runtime] || {}, # FIXME:this sucks. (was:) this overwrites wrap_runtime from outside.
|
42
|
+
wrap_static: ::Hash.new(TaskWrap.initial_activity), # add a default static wrap.
|
43
|
+
)
|
44
|
+
|
45
|
+
return activity, [ options, flow_options ], circuit_options
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# better: MyClass < Activity(TaskWrap, ...)
|
50
|
+
end
|
45
51
|
end
|
46
52
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trailblazer-activity
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Sutterer
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-02-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hirb
|
@@ -112,6 +112,7 @@ files:
|
|
112
112
|
- NOTES_
|
113
113
|
- README.md
|
114
114
|
- Rakefile
|
115
|
+
- inspeccccccccct.rb
|
115
116
|
- lib/trailblazer-activity.rb
|
116
117
|
- lib/trailblazer/activity.rb
|
117
118
|
- lib/trailblazer/activity/config.rb
|
@@ -121,6 +122,7 @@ files:
|
|
121
122
|
- lib/trailblazer/activity/implementation/fast_track.rb
|
122
123
|
- lib/trailblazer/activity/implementation/interface.rb
|
123
124
|
- lib/trailblazer/activity/implementation/path.rb
|
125
|
+
- lib/trailblazer/activity/implementation/plan.rb
|
124
126
|
- lib/trailblazer/activity/implementation/railway.rb
|
125
127
|
- lib/trailblazer/activity/introspect.rb
|
126
128
|
- lib/trailblazer/activity/magnetic.rb
|
@@ -131,11 +133,11 @@ files:
|
|
131
133
|
- lib/trailblazer/activity/magnetic/builder/path.rb
|
132
134
|
- lib/trailblazer/activity/magnetic/builder/railway.rb
|
133
135
|
- lib/trailblazer/activity/magnetic/dsl.rb
|
134
|
-
- lib/trailblazer/activity/magnetic/dsl/alterations.rb
|
135
|
-
- lib/trailblazer/activity/magnetic/dsl/plus_poles.rb
|
136
136
|
- lib/trailblazer/activity/magnetic/finalizer.rb
|
137
137
|
- lib/trailblazer/activity/magnetic/generate.rb
|
138
138
|
- lib/trailblazer/activity/magnetic/merge.rb
|
139
|
+
- lib/trailblazer/activity/magnetic/structure/alterations.rb
|
140
|
+
- lib/trailblazer/activity/magnetic/structure/plus_poles.rb
|
139
141
|
- lib/trailblazer/activity/present.rb
|
140
142
|
- lib/trailblazer/activity/schema/dependencies.rb
|
141
143
|
- lib/trailblazer/activity/schema/sequence.rb
|
@@ -1,59 +0,0 @@
|
|
1
|
-
module Trailblazer
|
2
|
-
module Activity::Magnetic
|
3
|
-
module DSL
|
4
|
-
# Output(:signal, :semantic) => :color
|
5
|
-
# add / merge
|
6
|
-
# change existing, => color
|
7
|
-
#
|
8
|
-
# Mutable DSL datastructure for managing all PlusPoles for a particular task.
|
9
|
-
#
|
10
|
-
# Produces [ PlusPole, PlusPole, ] via `to_a`.
|
11
|
-
#
|
12
|
-
# @privat
|
13
|
-
# @note This is private until we know what we want.
|
14
|
-
class PlusPoles
|
15
|
-
def initialize(plus_poles={})
|
16
|
-
@plus_poles = plus_poles.freeze
|
17
|
-
end
|
18
|
-
|
19
|
-
# merge( Activity::Magnetic.Output(Right, :success) => :success
|
20
|
-
def merge(output_to_color)
|
21
|
-
overrides = ::Hash[ output_to_color.collect { |output, color| [ output.semantic, [output, color] ] } ]
|
22
|
-
PlusPoles.new(@plus_poles.merge(overrides))
|
23
|
-
end
|
24
|
-
|
25
|
-
def reverse_merge(output_to_color)
|
26
|
-
existing_colors = @plus_poles.values.collect { |pole_cfg| pole_cfg.last }
|
27
|
-
|
28
|
-
overrides = output_to_color.find_all { |output, color| !existing_colors.include?(color) } # filter all outputs with a color that already exists.
|
29
|
-
merge(overrides)
|
30
|
-
end
|
31
|
-
|
32
|
-
def reconnect(semantic_to_color)
|
33
|
-
ary = semantic_to_color.collect do |semantic, color|
|
34
|
-
existing_output, _ = @plus_poles[semantic]
|
35
|
-
|
36
|
-
next unless existing_output
|
37
|
-
|
38
|
-
[ Activity.Output(existing_output.signal, existing_output.semantic), color ]
|
39
|
-
end
|
40
|
-
|
41
|
-
merge( ::Hash[ary.compact] )
|
42
|
-
end
|
43
|
-
|
44
|
-
# The DSL is a series of transformations that yield in tasks with several PlusPole instances each.
|
45
|
-
def to_a
|
46
|
-
@plus_poles.values.collect { |output, color| PlusPole.new(output, color) }
|
47
|
-
end
|
48
|
-
|
49
|
-
# Builds PlusPoles from { semantic => Output }, which, surprisingly, is exactly what Activity::outputs looks like.
|
50
|
-
# The plus pole's color is set to the output's semantic.
|
51
|
-
def self.from_outputs(outputs)
|
52
|
-
ary = outputs.collect { |semantic, output| [ output, semantic ] }
|
53
|
-
|
54
|
-
new.merge(::Hash[ary])
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|