trailblazer-developer 0.0.6 → 0.0.7
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/LICENSE +9 -0
- data/lib/trailblazer/developer/CHANGES.md +5 -0
- data/lib/trailblazer/developer/render/circuit.rb +1 -1
- data/lib/trailblazer/developer/render/linear.rb +1 -1
- data/lib/trailblazer/developer/trace/present.rb +59 -0
- data/lib/trailblazer/developer/trace.rb +147 -0
- data/lib/trailblazer/developer/version.rb +1 -1
- data/lib/trailblazer/developer/wtf.rb +38 -25
- data/lib/trailblazer/developer.rb +3 -1
- data/trailblazer-developer.gemspec +3 -2
- metadata +11 -8
- data/lib/trailblazer/developer/config.rb +0 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 435373419cdb7bb8f3c3b923585cdd83152774c90cb38b0685cf8ac4bdcc417d
|
4
|
+
data.tar.gz: 9f0a93bf955441a20d0f91f538fd3ad563cfda5a3f45b582dfa4edfd0aa8876d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 983662dc11836f0e42050145b5766c2eaa19d6c1240eb6cfe647c3fe6250a38d32cea7392dfc1ebef56c88ee83f9dee95764dfda7fb8c81703dd30eb84486b4b
|
7
|
+
data.tar.gz: 7591b6a2004491cf86fbe042009e870aafb9f23b904f6e3180b8103b82564d1cdd08761a890db09344af1ffd2564418fafe6f02d174b958dc6f65a104f11eeca
|
data/LICENSE
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
Copyright (c) 2018 Trailblazer GmbH
|
2
|
+
|
3
|
+
Trailblazer is an Open Source project licensed under the terms of
|
4
|
+
the LGPLv3 license. Please see <http://www.gnu.org/licenses/lgpl-3.0.html>
|
5
|
+
for license text.
|
6
|
+
|
7
|
+
Trailblazer PRO has a commercial-friendly license allowing private forks
|
8
|
+
and modifications of Trailblazer. Please see http://trailblazer.to/pro for
|
9
|
+
more detail.
|
@@ -1,3 +1,8 @@
|
|
1
|
+
# 0.0.7
|
2
|
+
|
3
|
+
* Move `Activity::Trace` and `Activity::Present` from `activity` to `developer`.
|
4
|
+
* Remove global configurations and use `flow_options` to override defaults in `wtf?`.
|
5
|
+
|
1
6
|
# 0.0.6
|
2
7
|
|
3
8
|
* Remove ID extraction logic from `Generate`, this is done on the server-side.
|
@@ -15,7 +15,7 @@ module Trailblazer
|
|
15
15
|
module_function
|
16
16
|
|
17
17
|
def call(operation, options = {style: :line})
|
18
|
-
graph =
|
18
|
+
graph = Introspect::Graph(operation)
|
19
19
|
|
20
20
|
rows = graph.collect do |node, i|
|
21
21
|
next if node[:data][:stop_event] # DISCUSS: show this?
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'trailblazer/activity'
|
2
|
+
|
3
|
+
module Trailblazer::Developer
|
4
|
+
module Trace
|
5
|
+
module Present
|
6
|
+
module_function
|
7
|
+
|
8
|
+
INDENTATION = " |".freeze
|
9
|
+
STEP_PREFIX = "-- ".freeze
|
10
|
+
|
11
|
+
def default_renderer(task_node:, **)
|
12
|
+
[ task_node[:level], %{#{task_node[:name]}} ]
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(stack, level: 1, tree: [], renderer: method(:default_renderer), **options)
|
16
|
+
tree(stack.to_a, level, tree: tree, renderer: renderer, **options)
|
17
|
+
end
|
18
|
+
|
19
|
+
def tree(stack, level, tree:, renderer:, **options)
|
20
|
+
tree_for(stack, level, options.merge(tree: tree))
|
21
|
+
|
22
|
+
nodes = tree.each_with_index.map do |task_node, position|
|
23
|
+
renderer.(task_node: task_node, position: position, tree: tree)
|
24
|
+
end
|
25
|
+
|
26
|
+
render_tree_for(nodes)
|
27
|
+
end
|
28
|
+
|
29
|
+
def render_tree_for(nodes)
|
30
|
+
nodes.map { |level, node|
|
31
|
+
indentation = INDENTATION * (level -1)
|
32
|
+
indentation = indentation[0...-1] + "`" if level == 1 || /End./.match(node) # start or end step
|
33
|
+
indentation + STEP_PREFIX + node
|
34
|
+
}.join("\n")
|
35
|
+
end
|
36
|
+
|
37
|
+
def tree_for(stack, level, tree:, **options)
|
38
|
+
stack.each do |lvl| # always a Stack::Task[input, ..., output]
|
39
|
+
input, output, nested = Trace::Level.input_output_nested_for_level(lvl)
|
40
|
+
|
41
|
+
task = input.task
|
42
|
+
|
43
|
+
graph = Introspect::Graph(input.activity)
|
44
|
+
|
45
|
+
name = (node = graph.find { |node| node[:task] == task }) ? node[:id] : task
|
46
|
+
name ||= task # FIXME: bullshit
|
47
|
+
|
48
|
+
tree << { level: level, input: input, output: output, name: name, **options }
|
49
|
+
|
50
|
+
if nested.any? # nesting
|
51
|
+
tree_for(nested, level + 1, options.merge(tree: tree))
|
52
|
+
end
|
53
|
+
|
54
|
+
tree
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
require 'trailblazer/activity'
|
2
|
+
|
3
|
+
module Trailblazer::Developer
|
4
|
+
module Trace
|
5
|
+
|
6
|
+
Activity = Trailblazer::Activity
|
7
|
+
|
8
|
+
class << self
|
9
|
+
# Public entry point to activate tracing when running {activity}.
|
10
|
+
def call(activity, (ctx, flow_options), circuit_options={})
|
11
|
+
activity, (ctx, flow_options), circuit_options = Trace.arguments_for_call( activity, [ctx, flow_options], circuit_options ) # only run once for the entire circuit!
|
12
|
+
|
13
|
+
signal, (ctx, flow_options) = Activity::TaskWrap.invoke(activity, [ctx, flow_options], circuit_options)
|
14
|
+
|
15
|
+
return flow_options[:stack], signal, [ctx, flow_options]
|
16
|
+
end
|
17
|
+
|
18
|
+
alias_method :invoke, :call
|
19
|
+
|
20
|
+
def arguments_for_call(activity, (options, flow_options), **circuit_options)
|
21
|
+
tracing_flow_options = {
|
22
|
+
stack: Trace::Stack.new,
|
23
|
+
}
|
24
|
+
|
25
|
+
tracing_circuit_options = {
|
26
|
+
wrap_runtime: ::Hash.new(Trace.merge_plan), # DISCUSS: this overrides existing {:wrap_runtime}.
|
27
|
+
}
|
28
|
+
|
29
|
+
return activity, [ options, tracing_flow_options.merge(flow_options) ], circuit_options.merge(tracing_circuit_options)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
module_function
|
34
|
+
# Insertions for the trace tasks that capture the arguments just before calling the task,
|
35
|
+
# and before the TaskWrap is finished.
|
36
|
+
#
|
37
|
+
# @private
|
38
|
+
def merge_plan
|
39
|
+
Activity::TaskWrap::Pipeline::Merge.new(
|
40
|
+
[Activity::TaskWrap::Pipeline.method(:insert_before), "task_wrap.call_task", ["task_wrap.capture_args", Trace.method(:capture_args)]],
|
41
|
+
[Activity::TaskWrap::Pipeline.method(:append), nil, ["task_wrap.capture_return", Trace.method(:capture_return)]],
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
# taskWrap step to capture incoming arguments of a step.
|
46
|
+
def capture_args(wrap_config, original_args)
|
47
|
+
original_args = capture_for(wrap_config[:task], *original_args)
|
48
|
+
|
49
|
+
return wrap_config, original_args
|
50
|
+
end
|
51
|
+
|
52
|
+
# taskWrap step to capture outgoing arguments from a step.
|
53
|
+
def capture_return(wrap_config, original_args)
|
54
|
+
(original_options, original_flow_options, _) = original_args[0]
|
55
|
+
|
56
|
+
original_flow_options[:stack] << Entity::Output.new(
|
57
|
+
wrap_config[:task], {}, wrap_config[:return_signal]
|
58
|
+
).freeze
|
59
|
+
|
60
|
+
original_flow_options[:stack].unindent!
|
61
|
+
|
62
|
+
|
63
|
+
return wrap_config, original_args
|
64
|
+
end
|
65
|
+
|
66
|
+
# It's important to understand that {flow[:stack]} is mutated by design. This is needed so
|
67
|
+
# in case of exceptions we still have a "global" trace - unfortunately Ruby doesn't allow
|
68
|
+
# us a better way.
|
69
|
+
def capture_for(task, (ctx, flow), activity:, **circuit_options)
|
70
|
+
flow[:stack].indent!
|
71
|
+
|
72
|
+
flow[:stack] << Entity::Input.new(
|
73
|
+
task, activity, [ctx, ctx.inspect]
|
74
|
+
).freeze
|
75
|
+
|
76
|
+
return [ctx, flow], circuit_options.merge(activity: activity)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Structures used in {capture_args} and {capture_return}.
|
80
|
+
# These get pushed onto one {Level} in a {Stack}.
|
81
|
+
#
|
82
|
+
# Level[
|
83
|
+
# Level[ ==> this is a scalar task
|
84
|
+
# Entity::Input
|
85
|
+
# Entity::Output
|
86
|
+
# ]
|
87
|
+
# Level[ ==> nested task
|
88
|
+
# Entity::Input
|
89
|
+
# Level[
|
90
|
+
# Entity::Input
|
91
|
+
# Entity::Output
|
92
|
+
# ]
|
93
|
+
# Entity::Output
|
94
|
+
# ]
|
95
|
+
# ]
|
96
|
+
Entity = Struct.new(:task, :activity, :data)
|
97
|
+
Entity::Input = Class.new(Entity)
|
98
|
+
Entity::Output = Class.new(Entity)
|
99
|
+
|
100
|
+
class Level < Array
|
101
|
+
def inspect
|
102
|
+
%{<Level>#{super}}
|
103
|
+
end
|
104
|
+
|
105
|
+
# @param level {Trace::Level}
|
106
|
+
def self.input_output_nested_for_level(level)
|
107
|
+
input = level[0]
|
108
|
+
output = level[-1]
|
109
|
+
|
110
|
+
output, nested = output.is_a?(Entity::Output) ? [output, level-[input, output]] : [nil, level[1..-1]]
|
111
|
+
|
112
|
+
return input, output, nested
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# Mutable/stateful per design. We want a (global) stack!
|
117
|
+
class Stack
|
118
|
+
def initialize
|
119
|
+
@nested = Level.new
|
120
|
+
@stack = [ @nested ]
|
121
|
+
end
|
122
|
+
|
123
|
+
def indent!
|
124
|
+
current << indented = Level.new
|
125
|
+
@stack << indented
|
126
|
+
end
|
127
|
+
|
128
|
+
def unindent!
|
129
|
+
@stack.pop
|
130
|
+
end
|
131
|
+
|
132
|
+
def <<(args)
|
133
|
+
current << args
|
134
|
+
end
|
135
|
+
|
136
|
+
def to_a
|
137
|
+
@nested
|
138
|
+
end
|
139
|
+
|
140
|
+
private
|
141
|
+
|
142
|
+
def current
|
143
|
+
@stack.last
|
144
|
+
end
|
145
|
+
end # Stack
|
146
|
+
end
|
147
|
+
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'trailblazer/activity'
|
2
|
-
|
3
1
|
module Trailblazer::Developer
|
4
2
|
module_function
|
5
3
|
|
@@ -14,7 +12,15 @@ module Trailblazer::Developer
|
|
14
12
|
module Wtf
|
15
13
|
module_function
|
16
14
|
|
17
|
-
COLOR_MAP =
|
15
|
+
COLOR_MAP = { pass: :green, fail: :brown }
|
16
|
+
|
17
|
+
SIGNALS_MAP = {
|
18
|
+
'Trailblazer::Activity::Right': :pass,
|
19
|
+
'Trailblazer::Activity::FastTrack::PassFast': :pass,
|
20
|
+
|
21
|
+
'Trailblazer::Activity::Left': :fail,
|
22
|
+
'Trailblazer::Activity::FastTrack::FailFast': :fail,
|
23
|
+
}
|
18
24
|
|
19
25
|
# Run {activity} with tracing enabled and inject a mutable {Stack} instance.
|
20
26
|
# This allows to display the trace even when an exception happened
|
@@ -23,43 +29,50 @@ module Trailblazer::Developer
|
|
23
29
|
|
24
30
|
# this instance gets mutated with every step. unfortunately, there is
|
25
31
|
# no other way in Ruby to keep the trace even when an exception was thrown.
|
26
|
-
stack =
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
)
|
37
|
-
puts Trailblazer::Activity::Trace::Present.(stack, renderer: method(:renderer))
|
38
|
-
|
39
|
-
rescue => exception
|
40
|
-
puts Trailblazer::Activity::Trace::Present.(stack, renderer: method(:renderer))
|
41
|
-
raise(exception)
|
42
|
-
end
|
32
|
+
stack = Trace::Stack.new
|
33
|
+
|
34
|
+
_returned_stack, *returned = Trace.invoke(
|
35
|
+
activity,
|
36
|
+
[
|
37
|
+
ctx,
|
38
|
+
flow_options.merge(stack: stack)
|
39
|
+
],
|
40
|
+
*args
|
41
|
+
)
|
43
42
|
|
44
43
|
returned
|
44
|
+
ensure
|
45
|
+
puts Trace::Present.(
|
46
|
+
stack,
|
47
|
+
renderer: method(:renderer),
|
48
|
+
color_map: COLOR_MAP.merge( flow_options[:color_map] || {} )
|
49
|
+
)
|
45
50
|
end
|
46
51
|
|
47
52
|
def renderer(task_node:, position:, tree:)
|
48
|
-
|
49
|
-
|
53
|
+
name, level, output, color_map = task_node.values_at(:name, :level, :output, :color_map)
|
54
|
+
|
55
|
+
if output.nil? && tree[position.next].nil? # i.e. when exception raised
|
56
|
+
return [ level, %{#{fmt(fmt(name, :red), :bold)}} ]
|
50
57
|
end
|
51
58
|
|
52
|
-
if
|
53
|
-
return [
|
59
|
+
if output.nil? # i.e. on entry/exit point of activity
|
60
|
+
return [ level, %{#{name}} ]
|
54
61
|
end
|
55
62
|
|
56
|
-
[
|
63
|
+
[ level, %{#{fmt( name, color_map[ signal_of(output.data) ] )}} ]
|
57
64
|
end
|
58
65
|
|
59
66
|
def fmt(line, style)
|
67
|
+
return line unless style
|
60
68
|
String.send(style, line)
|
61
69
|
end
|
62
70
|
|
71
|
+
def signal_of(entity_output)
|
72
|
+
entity_klass = entity_output.is_a?(Class) ? entity_output : entity_output.class
|
73
|
+
SIGNALS_MAP[entity_klass.name.to_sym]
|
74
|
+
end
|
75
|
+
|
63
76
|
# Stolen from https://stackoverflow.com/questions/1489183/colorized-ruby-output
|
64
77
|
#
|
65
78
|
# TODO: this is just prototyping
|
@@ -6,8 +6,10 @@ module Trailblazer
|
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
|
-
require "trailblazer/developer/config"
|
10
9
|
require "trailblazer/developer/wtf"
|
10
|
+
require "trailblazer/developer/trace"
|
11
|
+
require "trailblazer/developer/trace/present"
|
12
|
+
require "trailblazer/developer/introspect"
|
11
13
|
require "trailblazer/developer/generate"
|
12
14
|
require "trailblazer/developer/render/circuit"
|
13
15
|
require "trailblazer/developer/render/linear"
|
@@ -10,7 +10,8 @@ Gem::Specification.new do |spec|
|
|
10
10
|
|
11
11
|
spec.summary = "Developer tools for Trailblazer."
|
12
12
|
spec.description = "Developer tools for Trailblazer: debugger, tracing, visual editor integration."
|
13
|
-
spec.homepage = "http://trailblazer.to
|
13
|
+
spec.homepage = "http://trailblazer.to"
|
14
|
+
spec.license = "LGPL-3.0"
|
14
15
|
|
15
16
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
16
17
|
f.match(%r{^(test)/})
|
@@ -23,7 +24,7 @@ Gem::Specification.new do |spec|
|
|
23
24
|
spec.add_development_dependency "rake"
|
24
25
|
spec.add_development_dependency "rubocop"
|
25
26
|
|
26
|
-
spec.add_dependency "trailblazer-activity", ">= 0.
|
27
|
+
spec.add_dependency "trailblazer-activity", ">= 0.10.0"
|
27
28
|
spec.add_dependency "trailblazer-activity-dsl-linear"
|
28
29
|
spec.add_dependency "representable"
|
29
30
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trailblazer-developer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Sutterer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-09-
|
11
|
+
date: 2019-09-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -86,14 +86,14 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 0.
|
89
|
+
version: 0.10.0
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: 0.
|
96
|
+
version: 0.10.0
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: trailblazer-activity-dsl-linear
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -133,6 +133,7 @@ files:
|
|
133
133
|
- ".rubocop.yml"
|
134
134
|
- ".travis.yml"
|
135
135
|
- Gemfile
|
136
|
+
- LICENSE
|
136
137
|
- README.md
|
137
138
|
- Rakefile
|
138
139
|
- bin/console
|
@@ -142,16 +143,18 @@ files:
|
|
142
143
|
- lib/trailblazer/developer/CHANGES.md
|
143
144
|
- lib/trailblazer/developer/activity.rb
|
144
145
|
- lib/trailblazer/developer/client.rb
|
145
|
-
- lib/trailblazer/developer/config.rb
|
146
146
|
- lib/trailblazer/developer/generate.rb
|
147
147
|
- lib/trailblazer/developer/render/circuit.rb
|
148
148
|
- lib/trailblazer/developer/render/linear.rb
|
149
|
+
- lib/trailblazer/developer/trace.rb
|
150
|
+
- lib/trailblazer/developer/trace/present.rb
|
149
151
|
- lib/trailblazer/developer/version.rb
|
150
152
|
- lib/trailblazer/developer/wtf.rb
|
151
153
|
- lib/trailblazer/diagram/bpmn.rb
|
152
154
|
- trailblazer-developer.gemspec
|
153
|
-
homepage: http://trailblazer.to
|
154
|
-
licenses:
|
155
|
+
homepage: http://trailblazer.to
|
156
|
+
licenses:
|
157
|
+
- LGPL-3.0
|
155
158
|
metadata: {}
|
156
159
|
post_install_message:
|
157
160
|
rdoc_options: []
|
@@ -169,7 +172,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
169
172
|
version: '0'
|
170
173
|
requirements: []
|
171
174
|
rubyforge_project:
|
172
|
-
rubygems_version: 2.7.
|
175
|
+
rubygems_version: 2.7.6
|
173
176
|
signing_key:
|
174
177
|
specification_version: 4
|
175
178
|
summary: Developer tools for Trailblazer.
|
@@ -1,30 +0,0 @@
|
|
1
|
-
module Trailblazer::Developer
|
2
|
-
# {config} gives global settings for Developer
|
3
|
-
# Trailblazer::Developer.configure do |config|
|
4
|
-
# config.trace_color_map[Trailblazer::Activity::Right] = :green
|
5
|
-
# config.trace_color_map.default = :green
|
6
|
-
# end
|
7
|
-
|
8
|
-
class << self
|
9
|
-
def configure
|
10
|
-
yield config
|
11
|
-
end
|
12
|
-
|
13
|
-
def config
|
14
|
-
@config ||= Config.new
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
class Config
|
19
|
-
attr_reader :trace_color_map
|
20
|
-
|
21
|
-
def initialize
|
22
|
-
@trace_color_map = {
|
23
|
-
Trailblazer::Activity::Right => :green,
|
24
|
-
Trailblazer::Activity::Left => :brown
|
25
|
-
}
|
26
|
-
|
27
|
-
@trace_color_map.default = :green
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|