trailblazer-developer 0.0.10 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e6a577980533d74f29b616b2b5d3d85026a8d7ca20f096a9d9af463e30994fe3
4
- data.tar.gz: '03894756cc87b350bd9d0c71ee7c22cc951e7302869e20a95c8facd21d585c84'
3
+ metadata.gz: 1bd9598d12d74fcd1dcbe20a50d53642ee2fe9ca8aad9648332630dee4b8fb7a
4
+ data.tar.gz: bc6b62c30541f118e756d72646da251cdbc2eef1d95dcb806c22aca10c1b64d3
5
5
  SHA512:
6
- metadata.gz: b03caa6b40f5e45acc588999dc43b891b9f0f4d9ced50261acbe3919c1d89d4feb24c7ba9a4dd7924b10f72b87fb32d775d8a1ed000d8a6dea33da02b15fd5b6
7
- data.tar.gz: 6a8aa191f8132ffb968cdf0256985a4bbc5ea916a6240d94baac3a50a621e8b9a0b8e38aec84cf4ba336f32cecdafa5c31bd1a271da2074ce32c64d09e778e72
6
+ metadata.gz: ce2bc17462233a132411006e1bcb0d2b992e8e378faef8293d2be1d2916c691aba17def994644d7ae1428f65302d8d6496dc0fe583e484c036015415d9e4349e
7
+ data.tar.gz: f621040bab0043a71332f8a5ff325aae117612ba105116c527b57b4caacdeb52e067a2d8b5d5f6fadd5d290231fbb1c07ca1a036635d17d13a92d52c3e702629
data/README.md CHANGED
@@ -4,7 +4,7 @@ _Developer tools for Trailblazers._
4
4
 
5
5
  ## Documentation
6
6
 
7
- Find the complete documentation on the project website: [http://trb.to/2.1#developer]
7
+ Find the complete documentation on the project website: [http://2019.trailblazer.to/2.1/docs/developer.html]
8
8
 
9
9
  ## Summary
10
10
 
@@ -7,8 +7,11 @@ module Trailblazer
7
7
  end
8
8
 
9
9
  require "trailblazer/developer/wtf"
10
+ require "trailblazer/developer/wtf/renderer"
10
11
  require "trailblazer/developer/trace"
11
12
  require "trailblazer/developer/trace/present"
13
+ require "trailblazer/developer/trace/focusable"
14
+ require "trailblazer/developer/trace/inspector"
12
15
  require "trailblazer/developer/generate"
13
16
  require "trailblazer/developer/render/circuit"
14
17
  require "trailblazer/developer/render/linear"
@@ -1,3 +1,9 @@
1
+ # 0.0.11
2
+
3
+ * Allow injecting custom data collector in Trace API, to collect custom input/output ctx of task nodes.
4
+ * Allow focusing on specfic steps and ctx variables in Dev.wtf?
5
+ * Allow custom inspection while tracing using Inspector definations
6
+
1
7
  # 0.0.10
2
8
 
3
9
  * Make Generate::Pipeline an activity for better customization/extendability.
@@ -17,16 +17,23 @@ module Trailblazer::Developer
17
17
 
18
18
  alias_method :invoke, :call
19
19
 
20
- def arguments_for_call(activity, (options, flow_options), **circuit_options)
21
- tracing_flow_options = {
20
+ def arguments_for_call(activity, (options, original_flow_options), **original_circuit_options)
21
+ default_flow_options = {
22
22
  stack: Trace::Stack.new,
23
+
24
+ input_data_collector: Trace.method(:default_input_data_collector),
25
+ output_data_collector: Trace.method(:default_output_data_collector),
23
26
  }
24
27
 
25
- tracing_circuit_options = {
28
+ flow_options = { **default_flow_options, **Hash( original_flow_options ) }
29
+
30
+ default_circuit_options = {
26
31
  wrap_runtime: ::Hash.new(Trace.merge_plan), # DISCUSS: this overrides existing {:wrap_runtime}.
27
32
  }
28
33
 
29
- return activity, [ options, tracing_flow_options.merge(flow_options) ], circuit_options.merge(tracing_circuit_options)
34
+ circuit_options = { **original_circuit_options, **default_circuit_options }
35
+
36
+ return activity, [ options, flow_options ], circuit_options
30
37
  end
31
38
  end
32
39
 
@@ -42,38 +49,45 @@ module Trailblazer::Developer
42
49
  )
43
50
  end
44
51
 
52
+ # It's important to understand that {flow[:stack]} is mutated by design. This is needed so
53
+ # in case of exceptions we still have a "global" trace - unfortunately Ruby doesn't allow
54
+ # us a better way.
45
55
  # 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)
56
+ def capture_args(wrap_config, ((ctx, flow), circuit_options))
57
+ flow[:stack].indent!
48
58
 
49
- return wrap_config, original_args
59
+ flow[:stack] << Entity::Input.new(
60
+ wrap_config[:task],
61
+ circuit_options[:activity],
62
+ flow[:input_data_collector].call(wrap_config, [ctx, flow], circuit_options)
63
+ ).freeze
64
+
65
+ return wrap_config, [[ctx, flow], circuit_options]
50
66
  end
51
67
 
52
68
  # 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]
69
+ def capture_return(wrap_config, ((ctx, flow), circuit_options))
70
+ flow[:stack] << Entity::Output.new(
71
+ wrap_config[:task],
72
+ {},
73
+ flow[:output_data_collector].call(wrap_config, [ctx, flow], circuit_options)
58
74
  ).freeze
59
75
 
60
- original_flow_options[:stack].unindent!
76
+ flow[:stack].unindent!
61
77
 
62
-
63
- return wrap_config, original_args
78
+ return wrap_config, [[ctx, flow], circuit_options]
64
79
  end
65
80
 
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!
81
+ def default_input_data_collector(wrap_config, (ctx, _), circuit_options)
82
+ graph = Trailblazer::Activity::Introspect::Graph(circuit_options[:activity])
83
+ task = wrap_config[:task]
84
+ name = (node = graph.find { |node| node[:task] == task }) ? node[:id] : task
71
85
 
72
- flow[:stack] << Entity::Input.new(
73
- task, activity, [ctx, ctx.inspect]
74
- ).freeze
86
+ { ctx: ctx, task_name: name }
87
+ end
75
88
 
76
- return [ctx, flow], circuit_options.merge(activity: activity)
89
+ def default_output_data_collector(wrap_config, (ctx, _), _)
90
+ { ctx: ctx, signal: wrap_config[:return_signal] }
77
91
  end
78
92
 
79
93
  # Structures used in {capture_args} and {capture_return}.
@@ -115,6 +129,8 @@ module Trailblazer::Developer
115
129
 
116
130
  # Mutable/stateful per design. We want a (global) stack!
117
131
  class Stack
132
+ attr_reader :top
133
+
118
134
  def initialize
119
135
  @nested = Level.new
120
136
  @stack = [ @nested ]
@@ -129,8 +145,10 @@ module Trailblazer::Developer
129
145
  @stack.pop
130
146
  end
131
147
 
132
- def <<(args)
133
- current << args
148
+ def <<(entity)
149
+ @top = entity
150
+
151
+ current << entity
134
152
  end
135
153
 
136
154
  def to_a
@@ -0,0 +1,75 @@
1
+ require 'hirb'
2
+
3
+ module Trailblazer
4
+ module Developer
5
+ module Trace
6
+
7
+ module Focusable
8
+ module_function
9
+
10
+ # Get inspect of {focus_on.variables} or current {ctx}
11
+ def capture_variables_from(ctx, focus_on:, inspector: Trace::Inspector, **flow_options)
12
+ # ctx keys to be captured, for example [:current_user, :model, ....]
13
+ variables = (selected = focus_on[:variables]).any? ? selected : ctx.keys
14
+
15
+ variables.each_with_object({}) do |variable, result|
16
+ if variable.is_a?(Proc) # To allow deep key access from ctx
17
+ result[:Custom] = inspector.(variable.call(ctx), **flow_options)
18
+ else
19
+ result[variable] = inspector.(ctx[variable], **flow_options)
20
+ end
21
+ end
22
+ end
23
+
24
+ # Generate Hirb's vertical table nodes from captured ctx of each step
25
+ # |-- some step name
26
+ # | |-- ********** Input **********
27
+ # message: "WTF!"
28
+ # seq: []
29
+ # | `-- ********** Output **********
30
+ # message: "WTF!"
31
+ # seq: [:a]
32
+ def tree_nodes_for(level, input:, output:, **options)
33
+ input_output_nodes = { Input: input, Output: output }.compact.collect do |table_header, entity|
34
+ next unless Array( entity.data[:focused_variables] ).any?
35
+
36
+ table = vertical_table_for(entity.data[:focused_variables], table_header: table_header)
37
+ Present::TreeNodes::Node.new(level + 1, table, input, output, options).freeze
38
+ end
39
+
40
+ input_output_nodes.compact
41
+ end
42
+
43
+ # @private
44
+ def vertical_table_for(focused_variables, table_header:)
45
+ patched_vertical_table.render(
46
+ Array[ focused_variables ],
47
+ description: nil,
48
+ table_header: table_header, # Custom option, not from Hirb
49
+ )
50
+ end
51
+
52
+ # Overrding `Hirb::Helpers::VerticalTable#render_rows` because there is no option
53
+ # to customize vertical table's row header :(
54
+ # We need it to print if given entity is Input/Output
55
+ #
56
+ # @private
57
+ def patched_vertical_table
58
+ table = Class.new(Hirb::Helpers::VerticalTable)
59
+
60
+ table.send(:define_method, :render_rows) do
61
+ longest_header = Hirb::String.size (@headers.values.sort_by {|e| Hirb::String.size(e) }.last || '')
62
+ stars = "*" * [(longest_header + (longest_header / 2)), 3].max
63
+
64
+ @rows.map do |row|
65
+ "#{stars} #{@options[:table_header]} #{stars}\n" +
66
+ @fields.map{ |f| "#{Hirb::String.rjust(@headers[f], longest_header)}: #{row[f]}" }.join("\n")
67
+ end
68
+ end
69
+
70
+ table
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,48 @@
1
+ module Trailblazer
2
+ module Developer
3
+ module Trace
4
+
5
+ # This module does the inspection of given `ctx` with deep traversal.
6
+ # It only gets called when focusing is going on (i.e. focus_on API).
7
+ module Inspector
8
+ module_function
9
+
10
+ def call(value, default_inspector: method(:default_inspector), **)
11
+ return hash_inspector(value, default_inspector: default_inspector) if value.is_a?(Hash)
12
+ return array_inspector(value, default_inspector: default_inspector) if value.is_a?(Array)
13
+
14
+ default_inspector.(value)
15
+ end
16
+
17
+ def hash_inspector(value, default_inspector:)
18
+ Hash[
19
+ value.collect do |key, nested_value|
20
+ [key, call(nested_value, default_inspector: default_inspector)]
21
+ end
22
+ ]
23
+ end
24
+
25
+ def array_inspector(value, default_inspector:)
26
+ value.collect do |nested_value|
27
+ call(nested_value, default_inspector: default_inspector)
28
+ end
29
+ end
30
+
31
+ # To avoid additional query that AR::Relation#inspect makes,
32
+ # we're calling AR::Relation#to_sql to get plain SQL string instead.
33
+ def activerecord_relation_inspector(value)
34
+ { query: value.to_sql }
35
+ end
36
+
37
+ def default_inspector(value)
38
+ if defined?(ActiveRecord) && value.is_a?(ActiveRecord::Relation)
39
+ return activerecord_relation_inspector(value)
40
+ end
41
+
42
+ value.inspect
43
+ end
44
+ end
45
+
46
+ end
47
+ end
48
+ end
@@ -1,15 +1,12 @@
1
- require 'trailblazer/activity'
1
+ require 'hirb'
2
2
 
3
3
  module Trailblazer::Developer
4
4
  module Trace
5
5
  module Present
6
6
  module_function
7
7
 
8
- INDENTATION = " |".freeze
9
- STEP_PREFIX = "-- ".freeze
10
-
11
8
  def default_renderer(task_node:, **)
12
- [ task_node[:level], %{#{task_node[:name]}} ]
9
+ [ task_node.level, %{#{task_node.value}} ]
13
10
  end
14
11
 
15
12
  def call(stack, level: 1, tree: [], renderer: method(:default_renderer), **options)
@@ -23,29 +20,14 @@ module Trailblazer::Developer
23
20
  renderer.(task_node: task_node, position: position, tree: tree)
24
21
  end
25
22
 
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")
23
+ Hirb::Console.format_output(nodes, class: :tree, type: :directory, multi_line_nodes: true)
35
24
  end
36
25
 
37
26
  def tree_for(stack, level, tree:, **options)
38
27
  stack.each do |lvl| # always a Stack::Task[input, ..., output]
39
28
  input, output, nested = Trace::Level.input_output_nested_for_level(lvl)
40
29
 
41
- task = input.task
42
-
43
- graph = Trailblazer::Activity::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 }
30
+ tree.push(*TreeNodes.for(level, options.merge(input: input, output: output)))
49
31
 
50
32
  if nested.any? # nesting
51
33
  tree_for(nested, level + 1, options.merge(tree: tree))
@@ -54,6 +36,26 @@ module Trailblazer::Developer
54
36
  tree
55
37
  end
56
38
  end
39
+
40
+ module TreeNodes
41
+ Node = Struct.new(:level, :value, :input, :output, :options) do
42
+ # Allow access to any custom key from options, eg. color_map
43
+ def method_missing(name, *)
44
+ options[name]
45
+ end
46
+ end
47
+
48
+ module_function
49
+
50
+ def for(level, input:, output:, **options)
51
+ nodes = Array[ Node.new(level, input.data[:task_name], input, output, options).freeze ]
52
+
53
+ focused_nodes = Trace::Focusable.tree_nodes_for(level, input: input, output: output, **options)
54
+ nodes += focused_nodes if focused_nodes.length > 0
55
+
56
+ nodes
57
+ end
58
+ end
57
59
  end
58
60
  end
59
61
  end
@@ -1,7 +1,7 @@
1
1
  module Trailblazer
2
2
  module Version
3
3
  module Developer
4
- VERSION = "0.0.10"
4
+ VERSION = "0.0.11"
5
5
  end
6
6
  end
7
7
  end
@@ -12,95 +12,70 @@ module Trailblazer::Developer
12
12
  module Wtf
13
13
  module_function
14
14
 
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
- }
24
-
25
15
  # Run {activity} with tracing enabled and inject a mutable {Stack} instance.
26
16
  # This allows to display the trace even when an exception happened
27
- def invoke(activity, (ctx, flow_options), *args)
28
- flow_options ||= {} # Ruby sucks.
29
-
30
- # this instance gets mutated with every step. unfortunately, there is
31
- # no other way in Ruby to keep the trace even when an exception was thrown.
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
17
+ def invoke(activity, (ctx, flow_options), *circuit_options)
18
+ activity, (ctx, flow_options), circuit_options = Wtf.arguments_for_trace(
19
+ activity, [ctx, flow_options], *circuit_options
41
20
  )
42
21
 
43
- returned
22
+ _returned_stack, signal, (ctx, flow_options) = Trace.invoke(
23
+ activity, [ctx, flow_options], *circuit_options
24
+ )
25
+
26
+ return signal, [ctx, flow_options], circuit_options
44
27
  ensure
45
28
  puts Trace::Present.(
46
- stack,
47
- renderer: method(:renderer),
48
- color_map: COLOR_MAP.merge( flow_options[:color_map] || {} )
29
+ flow_options[:stack],
30
+ renderer: Wtf::Renderer,
31
+ color_map: Wtf::Renderer::DEFAULT_COLOR_MAP.merge( flow_options[:color_map] || {} ),
49
32
  )
50
33
  end
51
34
 
52
- def renderer(task_node:, position:, tree:)
53
- name, level, output, color_map = task_node.values_at(:name, :level, :output, :color_map)
35
+ def arguments_for_trace(activity, (ctx, original_flow_options), **circuit_options)
36
+ default_flow_options = {
37
+ # this instance gets mutated with every step. unfortunately, there is
38
+ # no other way in Ruby to keep the trace even when an exception was thrown.
39
+ stack: Trace::Stack.new,
54
40
 
55
- if output.nil? && tree[position.next].nil? # i.e. when exception raised
56
- return [ level, %{#{fmt(fmt(name, :red), :bold)}} ]
57
- end
41
+ input_data_collector: method(:trace_input_data_collector),
42
+ output_data_collector: method(:trace_output_data_collector),
43
+ }
58
44
 
59
- if output.nil? # i.e. on entry/exit point of activity
60
- return [ level, %{#{name}} ]
61
- end
45
+ # Merge default options with flow_options as an order of precedence
46
+ flow_options = { **default_flow_options, **Hash( original_flow_options ) }
62
47
 
63
- [ level, %{#{fmt( name, color_map[ signal_of(output.data) ] )}} ]
64
- end
48
+ # Normalize `focus_on` param to
49
+ # 1. Wrap step and variable names into an array if not already
50
+ flow_options[:focus_on] = {
51
+ steps: Array( flow_options.dig(:focus_on, :steps) ),
52
+ variables: Array( flow_options.dig(:focus_on, :variables) ),
53
+ }
65
54
 
66
- def fmt(line, style)
67
- return line unless style
68
- String.send(style, line)
55
+ return activity, [ ctx, flow_options ], circuit_options
69
56
  end
70
57
 
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]
58
+ # Overring default input and output data collectors to collect/capture
59
+ # 1. inspect of focusable variables for given focusable step
60
+ def trace_input_data_collector(wrap_config, (ctx, flow_options), circuit_options)
61
+ data = Trace.default_input_data_collector(wrap_config, [ctx, flow_options], circuit_options)
62
+
63
+ if flow_options[:focus_on][:steps].include?(data[:task_name])
64
+ data[:focused_variables] = Trace::Focusable.capture_variables_from(ctx, **flow_options)
65
+ end
66
+
67
+ data
74
68
  end
75
69
 
76
- # Stolen from https://stackoverflow.com/questions/1489183/colorized-ruby-output
77
- #
78
- # TODO: this is just prototyping
79
- module String
80
- module_function
81
- def black(str); "\e[30m#{str}\e[0m" end
82
- def red(str); "\e[31m#{str}\e[0m" end
83
- def green(str); "\e[32m#{str}\e[0m" end
84
- def brown(str); "\e[33m#{str}\e[0m" end
85
- def blue(str); "\e[34m#{str}\e[0m" end
86
- def magenta(str); "\e[35m#{str}\e[0m" end
87
- def cyan(str); "\e[36m#{str}\e[0m" end
88
- def gray(str); "\e[37m#{str}\e[0m" end
89
-
90
- def bg_black(str); "\e[40m#{str}\e[0m" end
91
- def bg_red(str); "\e[41m#{str}\e[0m" end
92
- def bg_green(str); "\e[42m#{str}\e[0m" end
93
- def bg_brown(str); "\e[43m#{str}\e[0m" end
94
- def bg_blue(str); "\e[44m#{str}\e[0m" end
95
- def bg_magenta(str); "\e[45m#{str}\e[0m" end
96
- def bg_cyan(str); "\e[46m#{str}\e[0m" end
97
- def bg_gray(str); "\e[47m#{str}\e[0m" end
98
-
99
- def bold(str); "\e[1m#{str}\e[22m" end
100
- def italic(str); "\e[3m#{str}\e[23m" end
101
- def underline(str); "\e[4m#{str}\e[24m" end
102
- def blink(str); "\e[5m#{str}\e[25m" end
103
- def reverse_color(str); "\e[7m#{str}\e[27m" end
70
+ def trace_output_data_collector(wrap_config, (ctx, flow_options), circuit_options)
71
+ data = Trace.default_output_data_collector(wrap_config, [ctx, flow_options], circuit_options)
72
+
73
+ input = flow_options[:stack].top
74
+ if flow_options[:focus_on][:steps].include?(input.data[:task_name])
75
+ data[:focused_variables] = Trace::Focusable.capture_variables_from(ctx, **flow_options)
76
+ end
77
+
78
+ data
104
79
  end
105
80
  end
106
81
  end
@@ -0,0 +1,78 @@
1
+ module Trailblazer::Developer
2
+ module Wtf
3
+
4
+ module Renderer
5
+ DEFAULT_COLOR_MAP = { pass: :green, fail: :brown }
6
+
7
+ SIGNALS_MAP = {
8
+ :'Trailblazer::Activity::Right' => :pass,
9
+ :'Trailblazer::Activity::FastTrack::PassFast' => :pass,
10
+
11
+ :'Trailblazer::Activity::Left' => :fail,
12
+ :'Trailblazer::Activity::FastTrack::FailFast' => :fail,
13
+ }
14
+
15
+ module_function
16
+
17
+ # tree: Array of Trace::TreeNodes::Node
18
+ # task_node - current Trace::TreeNodes::Node to render
19
+ # position - task_node's position in tree
20
+ def call(tree:, task_node:, position:)
21
+ value = value_for(tree, task_node, position)
22
+ [task_node.level, value]
23
+ end
24
+
25
+ def value_for(tree, task_node, position)
26
+ if task_node.output.nil? && tree[position.next].nil? # i.e. when exception raised
27
+ return %{#{fmt(fmt(task_node.value, :red), :bold)}}
28
+ end
29
+
30
+ if task_node.output.nil? # i.e. on entry/exit point of activity
31
+ return %{#{task_node.value}}
32
+ end
33
+
34
+ %{#{fmt(task_node.value, task_node.color_map[ signal_of(task_node) ])}}
35
+ end
36
+
37
+ def fmt(line, style)
38
+ return line unless style
39
+ String.send(style, line)
40
+ end
41
+
42
+ def signal_of(task_node)
43
+ entity_signal = task_node.output.data[:signal]
44
+ entity_klass = entity_signal.is_a?(Class) ? entity_signal : entity_signal.class
45
+
46
+ SIGNALS_MAP[entity_klass.name.to_sym]
47
+ end
48
+
49
+ # Stolen from https://stackoverflow.com/questions/1489183/colorized-ruby-output
50
+ #
51
+ # TODO: this is just prototyping
52
+ module String
53
+ module_function
54
+ def black(str); "\e[30m#{str}\e[0m" end
55
+ def red(str); "\e[31m#{str}\e[0m" end
56
+ def green(str); "\e[32m#{str}\e[0m" end
57
+ def brown(str); "\e[33m#{str}\e[0m" end
58
+ def blue(str); "\e[34m#{str}\e[0m" end
59
+ def magenta(str); "\e[35m#{str}\e[0m" end
60
+ def cyan(str); "\e[36m#{str}\e[0m" end
61
+ def gray(str); "\e[37m#{str}\e[0m" end
62
+
63
+ def bg_black(str); "\e[40m#{str}\e[0m" end
64
+ def bg_red(str); "\e[41m#{str}\e[0m" end
65
+ def bg_green(str); "\e[42m#{str}\e[0m" end
66
+ def bg_brown(str); "\e[43m#{str}\e[0m" end
67
+ def bg_blue(str); "\e[44m#{str}\e[0m" end
68
+ def bg_magenta(str); "\e[45m#{str}\e[0m" end
69
+ def bg_cyan(str); "\e[46m#{str}\e[0m" end
70
+ def bg_gray(str); "\e[47m#{str}\e[0m" end
71
+
72
+ def bold(str); "\e[1m#{str}\e[22m" end
73
+ def italic(str); "\e[3m#{str}\e[23m" end
74
+ def underline(str); "\e[4m#{str}\e[24m" end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -27,4 +27,5 @@ Gem::Specification.new do |spec|
27
27
  spec.add_dependency "trailblazer-activity", ">= 0.10.0", "< 1.0.0"
28
28
  spec.add_dependency "trailblazer-activity-dsl-linear"
29
29
  spec.add_dependency "representable"
30
+ spec.add_dependency "hirb"
30
31
  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.10
4
+ version: 0.0.11
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-11-20 00:00:00.000000000 Z
11
+ date: 2020-03-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -128,6 +128,20 @@ dependencies:
128
128
  - - ">="
129
129
  - !ruby/object:Gem::Version
130
130
  version: '0'
131
+ - !ruby/object:Gem::Dependency
132
+ name: hirb
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ type: :runtime
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
131
145
  description: 'Developer tools for Trailblazer: debugger, tracing, visual editor integration.'
132
146
  email:
133
147
  - apotonick@gmail.com
@@ -152,9 +166,12 @@ files:
152
166
  - lib/trailblazer/developer/render/circuit.rb
153
167
  - lib/trailblazer/developer/render/linear.rb
154
168
  - lib/trailblazer/developer/trace.rb
169
+ - lib/trailblazer/developer/trace/focusable.rb
170
+ - lib/trailblazer/developer/trace/inspector.rb
155
171
  - lib/trailblazer/developer/trace/present.rb
156
172
  - lib/trailblazer/developer/version.rb
157
173
  - lib/trailblazer/developer/wtf.rb
174
+ - lib/trailblazer/developer/wtf/renderer.rb
158
175
  - lib/trailblazer/diagram/bpmn.rb
159
176
  - trailblazer-developer.gemspec
160
177
  homepage: http://trailblazer.to
@@ -176,8 +193,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
176
193
  - !ruby/object:Gem::Version
177
194
  version: '0'
178
195
  requirements: []
179
- rubyforge_project:
180
- rubygems_version: 2.7.3
196
+ rubygems_version: 3.0.6
181
197
  signing_key:
182
198
  specification_version: 4
183
199
  summary: Developer tools for Trailblazer.