forked from engines/Spaces
/
trace.rb
75 lines (56 loc) · 1.81 KB
/
trace.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
require_relative '../spaces/thing'
I18n.load_path << Dir["#{__dir__}/i18n/*.yaml"]
module Recovery
class Trace < ::Spaces::Thing
attr_accessor :error,
:witnesses,
:verbosity
def t(id = identifier); super(id, **witnesses) ;end
def spout_trace
if verbosity&.include?(:trace)
spout "\n#{array.join("\n")}" unless array.empty?
end
end
def spout_error
if verbosity&.include?(:error)
spout "\n#{error.message}" if error
end
end
def spout_witnesses
if verbosity&.include?(:witnesses) && tw = witnesses
spout "\nWitnesses#{'-' * 11}<<<<"
spout tw.map { |w| "#{w.first}: #{w.last}" }
end
end
def identifier; [:trace, zipped_nodes].join('.') ;end
def zipped_nodes; path_nodes.zip(method_names).map{ |n| n.join('/') } ;end
def path_nodes; array.map(&:trace_path_nodes) ;end
def method_names; array.map(&:trace_method_name) ;end
def array
@array ||= (error&.backtrace || []).select do |s|
s.include? 'Spaces' # FIX: will fail if project name changes
end.reject do |s|
s.include?('method_missing') || s.include?('spaces/constantizing')
end.take(2).reverse.map(&:shortened_trace_line)
end
def initialize(args)
p = args.partition { |k, v| k == :error }.map(&:to_h)
self.error = p.first[:error]
q = p.last.partition { |k, v| k == :verbosity }.map(&:to_h)
self.verbosity = q.first[:verbosity]
self.witnesses = q.last
end
end
end
class String
def shortened_trace_line
split(break_text).last
end
def trace_method_name
split('`').last.split("'").first.gsub(" ", "_")
end
def trace_path_nodes
split('.').first.gsub('/', '::')
end
def break_text; '/ruby/' ;end # FIX: will fail if source code is not under ruby folder
end