rshade 0.1.9.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -1
- data/Gemfile +6 -2
- data/Gemfile.lock +10 -1
- data/README.md +19 -3
- data/Rakefile +5 -3
- data/bin/console +4 -3
- data/lib/rshade/config/registry.rb +47 -0
- data/lib/rshade/config/stack_store.rb +58 -0
- data/lib/rshade/config/store.rb +6 -5
- data/lib/rshade/config.rb +4 -3
- data/lib/rshade/core_extensions/object/reveal.rb +34 -5
- data/lib/rshade/event.rb +15 -5
- data/lib/rshade/event_observer.rb +3 -1
- data/lib/rshade/event_processor.rb +12 -11
- data/lib/rshade/event_tree.rb +13 -15
- data/lib/rshade/filter/abstract_filter.rb +3 -1
- data/lib/rshade/filter/default.rb +3 -1
- data/lib/rshade/filter/exclude_path_filter.rb +5 -3
- data/lib/rshade/filter/filter_builder.rb +14 -3
- data/lib/rshade/filter/filter_composition.rb +26 -24
- data/lib/rshade/filter/include_path_filter.rb +5 -1
- data/lib/rshade/filter/variable_filter.rb +4 -1
- data/lib/rshade/formatter/stack/json.rb +51 -0
- data/lib/rshade/formatter/stack/stdout.rb +13 -0
- data/lib/rshade/formatter/stack/string.rb +41 -0
- data/lib/rshade/formatter/trace/file.rb +33 -0
- data/lib/rshade/formatter/trace/html.rb +38 -0
- data/lib/rshade/formatter/trace/json.rb +61 -0
- data/lib/rshade/formatter/trace/stdout.rb +14 -0
- data/lib/rshade/formatter/trace/string.rb +48 -0
- data/lib/rshade/rspec/rspec.rb +7 -6
- data/lib/rshade/serializer/traversal.rb +16 -9
- data/lib/rshade/stack.rb +26 -0
- data/lib/rshade/stack_frame.rb +60 -0
- data/lib/rshade/trace.rb +7 -4
- data/lib/rshade/trace_observable.rb +5 -0
- data/lib/rshade/version.rb +3 -1
- data/lib/rshade.rb +25 -8
- data/rshade.gemspec +24 -21
- metadata +43 -8
- data/lib/rshade/formatter/file.rb +0 -28
- data/lib/rshade/formatter/html.rb +0 -33
- data/lib/rshade/formatter/json.rb +0 -59
- data/lib/rshade/formatter/stdout.rb +0 -10
- data/lib/rshade/formatter/string.rb +0 -36
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RShade
|
2
4
|
module Filter
|
3
5
|
class FilterComposition
|
@@ -5,53 +7,53 @@ module RShade
|
|
5
7
|
AND_OP = :and
|
6
8
|
OR_OP = :or
|
7
9
|
UNARY_OP = :unary
|
8
|
-
attr_reader :
|
10
|
+
attr_reader :value, :left, :right, :parent
|
9
11
|
attr_accessor :parent
|
10
12
|
|
11
13
|
# @param [#call, Enumerable] left
|
12
14
|
# @param [#call, Enumerable] right
|
13
|
-
def initialize(
|
14
|
-
@
|
15
|
+
def initialize(value, left = nil, right = nil)
|
16
|
+
@value = value
|
15
17
|
@left = left
|
16
18
|
@right = right
|
17
19
|
end
|
18
20
|
|
19
21
|
def call(event)
|
20
|
-
case
|
22
|
+
case value
|
21
23
|
when UNARY_OP
|
22
|
-
|
24
|
+
left&.call(event)
|
23
25
|
when AND_OP
|
24
|
-
|
26
|
+
left&.call(event) && right&.call(event)
|
25
27
|
when OR_OP
|
26
|
-
|
27
|
-
r = right&.call(event)
|
28
|
-
# puts "#{left} => #{l} OR #{right} => #{r}"
|
29
|
-
return l || r
|
28
|
+
left&.call(event) || right&.call(event)
|
30
29
|
else
|
31
|
-
|
30
|
+
value.call(event)
|
32
31
|
end
|
33
32
|
end
|
34
33
|
|
35
34
|
def each(&block)
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
yield left
|
40
|
-
end
|
41
|
-
|
42
|
-
if right&.respond_to?(:each)
|
43
|
-
right&.each(&block)
|
44
|
-
else
|
45
|
-
yield right
|
46
|
-
end
|
35
|
+
yield value unless left && right
|
36
|
+
left&.each(&block)
|
37
|
+
right&.each(&block)
|
47
38
|
end
|
48
39
|
|
49
40
|
def config_filter(type, &block)
|
50
41
|
filter = find do |filter|
|
51
42
|
filter.is_a? type
|
52
43
|
end
|
53
|
-
filter
|
44
|
+
filter&.config(&block)
|
45
|
+
end
|
46
|
+
|
47
|
+
# for debug purposes, show each filter and result of evaluation
|
48
|
+
def filter_results(event)
|
49
|
+
each_with_object([]) do |filter, arr|
|
50
|
+
arr << [filter, filter.call(event)]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.build(arr)
|
55
|
+
::RShade::Filter::FilterBuilder.build(arr)
|
54
56
|
end
|
55
57
|
end
|
56
58
|
end
|
57
|
-
end
|
59
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RShade
|
2
4
|
module Filter
|
3
5
|
class IncludePathFilter < AbstractFilter
|
@@ -22,6 +24,7 @@ module RShade
|
|
22
24
|
paths.any? do |path|
|
23
25
|
next str?(path, event_path) if path.is_a? String
|
24
26
|
next regexp?(path, event_path) if path.is_a? Regexp
|
27
|
+
|
25
28
|
false
|
26
29
|
end
|
27
30
|
end
|
@@ -31,6 +34,7 @@ module RShade
|
|
31
34
|
end
|
32
35
|
|
33
36
|
private
|
37
|
+
|
34
38
|
def str?(str, event_path)
|
35
39
|
event_path.include?(str)
|
36
40
|
end
|
@@ -40,4 +44,4 @@ module RShade
|
|
40
44
|
end
|
41
45
|
end
|
42
46
|
end
|
43
|
-
end
|
47
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RShade
|
4
|
+
module Formatter
|
5
|
+
module Stack
|
6
|
+
class Json
|
7
|
+
attr_reader :filepath, :pretty
|
8
|
+
|
9
|
+
def initialize(filepath:, pretty: false)
|
10
|
+
@filepath = filepath
|
11
|
+
@pretty = pretty
|
12
|
+
end
|
13
|
+
|
14
|
+
# @param [Array<RShade::StackFrame>] stack_frames
|
15
|
+
def call(stack_frames)
|
16
|
+
payload = stack_frames.map.with_index do |frame, idx|
|
17
|
+
serialize(idx, frame)
|
18
|
+
end
|
19
|
+
|
20
|
+
File.open(filepath, 'a+') do |file|
|
21
|
+
record = {
|
22
|
+
time: Time.now.getutc,
|
23
|
+
thread_id: Thread.current,
|
24
|
+
thread_list: Thread.list,
|
25
|
+
frames: payload
|
26
|
+
}
|
27
|
+
file.puts(convert_to_json(record, pretty))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def convert_to_json(object, pretty)
|
34
|
+
return JSON.pretty_generate(object) if pretty
|
35
|
+
|
36
|
+
JSON.generate(object)
|
37
|
+
end
|
38
|
+
|
39
|
+
# @param [RShade::StackFrame] frame
|
40
|
+
def serialize(idx, frame)
|
41
|
+
{
|
42
|
+
frame: idx,
|
43
|
+
source_location: "#{frame.source_location[:path]}:#{frame.source_location[:line]}",
|
44
|
+
local_variables: frame.local_vars,
|
45
|
+
receiver_variables: frame.receiver_variables
|
46
|
+
}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RShade
|
4
|
+
module Formatter
|
5
|
+
module Stack
|
6
|
+
class String
|
7
|
+
ROOT_SEP = "---\n"
|
8
|
+
|
9
|
+
def initialize(opts = {}); end
|
10
|
+
|
11
|
+
# @param [RShade::EventProcessor] stack
|
12
|
+
def call(stack)
|
13
|
+
buffer = StringIO.new
|
14
|
+
stack.each_with_index do |frame, idx|
|
15
|
+
if idx.zero?
|
16
|
+
buffer << ROOT_SEP
|
17
|
+
next
|
18
|
+
end
|
19
|
+
next unless frame
|
20
|
+
|
21
|
+
buffer.write line(idx, frame, idx)
|
22
|
+
end
|
23
|
+
buffer.string
|
24
|
+
end
|
25
|
+
|
26
|
+
# @param [RShade::StackFrame] frame
|
27
|
+
def line(line_idx, frame, depth)
|
28
|
+
source_location = ColorizedString["(#{frame.source_location[:path]}:#{frame.source_location[:line]})"].colorize(:green)
|
29
|
+
var_str = frame.local_vars.map do |_, val|
|
30
|
+
var_name = val[:name]
|
31
|
+
var_value = val[:value]
|
32
|
+
var_type = val[:type]
|
33
|
+
"#{var_type} #{var_name} => (#{var_value})"
|
34
|
+
end.join(', ')
|
35
|
+
colorized_var_str = ColorizedString[var_str].colorize(:blue)
|
36
|
+
"#{' ' * depth}[frame: #{line_idx}]#{source_location} => local vars: (#{colorized_var_str})\n"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RShade
|
4
|
+
module Formatter
|
5
|
+
module Trace
|
6
|
+
class File
|
7
|
+
attr_reader :formatter
|
8
|
+
|
9
|
+
FILE_NAME = 'stacktrace.json'
|
10
|
+
|
11
|
+
def initialize(args = {})
|
12
|
+
@formatter = args.fetch(:format, Json)
|
13
|
+
end
|
14
|
+
|
15
|
+
# @param [RShade::EventProcessor] event_store
|
16
|
+
def call(event_store)
|
17
|
+
data = formatter.call(event_store)
|
18
|
+
if formatter == Json
|
19
|
+
write_to_file(JSON.pretty_generate(data))
|
20
|
+
else
|
21
|
+
write_to_file(data.to_s)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def write_to_file(data)
|
26
|
+
::File.open(::File.join(RShade::Config.store_dir, FILE_NAME), 'w+') do |f|
|
27
|
+
f.write data
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module RShade
|
6
|
+
module Formatter
|
7
|
+
module Trace
|
8
|
+
class Html
|
9
|
+
attr_reader :formatter
|
10
|
+
|
11
|
+
FILE_NAME = 'stacktrace.html'
|
12
|
+
TEMPLATE = 'html/template.html.erb'
|
13
|
+
|
14
|
+
def initialize(args = {})
|
15
|
+
@formatter = args.fetch(:formatter, Json)
|
16
|
+
end
|
17
|
+
|
18
|
+
# @param [RShade::EventProcessor] event_store
|
19
|
+
def call(event_store)
|
20
|
+
data = formatter.call(event_store)
|
21
|
+
erb_template = ERB.new(template)
|
22
|
+
content = erb_template.result_with_hash({ json: data.to_json })
|
23
|
+
write_to_file(content)
|
24
|
+
end
|
25
|
+
|
26
|
+
def write_to_file(data)
|
27
|
+
::File.open(::File.join(RShade::Config.store_dir, FILE_NAME), 'w+') do |f|
|
28
|
+
f.write data
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def template
|
33
|
+
@template ||= ::File.read(::File.join(::RShade::Config.root_dir, TEMPLATE))
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RShade
|
4
|
+
module Formatter
|
5
|
+
module Trace
|
6
|
+
class Json
|
7
|
+
attr_reader :event_processor
|
8
|
+
|
9
|
+
# @param [RShade::EventProcessor] event_store
|
10
|
+
def call(event_store)
|
11
|
+
@event_store = event_store
|
12
|
+
flat
|
13
|
+
end
|
14
|
+
|
15
|
+
def flat
|
16
|
+
arr = []
|
17
|
+
event_store.each do |node|
|
18
|
+
arr << item(node.event)
|
19
|
+
end
|
20
|
+
arr.sort_by { |item| item[:level] }
|
21
|
+
end
|
22
|
+
|
23
|
+
def hierarchical
|
24
|
+
hash = {}
|
25
|
+
event_store.each do |node|
|
26
|
+
depth = node.level
|
27
|
+
ref = hash_iterate(hash, depth)
|
28
|
+
ref[:data] = item(node)
|
29
|
+
end
|
30
|
+
sort_hash(hash)
|
31
|
+
end
|
32
|
+
|
33
|
+
def sort_hash(h)
|
34
|
+
{}.tap do |h2|
|
35
|
+
h.sort.each do |k, v|
|
36
|
+
h2[k] = v.is_a?(Hash) ? sort_hash(v) : v
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def hash_iterate(hash, depth)
|
42
|
+
(0..depth).each do |_lvl|
|
43
|
+
hash[:inner] = {} unless hash[:inner]
|
44
|
+
hash = hash[:inner]
|
45
|
+
end
|
46
|
+
hash
|
47
|
+
end
|
48
|
+
|
49
|
+
def item(value)
|
50
|
+
{
|
51
|
+
class: value.klass.to_s,
|
52
|
+
method_name: value.method_name,
|
53
|
+
full_path: "#{value.path}:#{value.lineno}",
|
54
|
+
level: value.depth,
|
55
|
+
vars: value.vars
|
56
|
+
}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RShade
|
4
|
+
module Formatter
|
5
|
+
module Trace
|
6
|
+
class String
|
7
|
+
ROOT_SEP = "---\n"
|
8
|
+
|
9
|
+
def initialize(opts = {}); end
|
10
|
+
|
11
|
+
# @param [RShade::EventProcessor] event_store
|
12
|
+
def call(event_store)
|
13
|
+
buffer = StringIO.new
|
14
|
+
event_store.each_with_index do |node, idx|
|
15
|
+
depth = node.level
|
16
|
+
event = node.value
|
17
|
+
if depth == 1
|
18
|
+
buffer << ROOT_SEP
|
19
|
+
next
|
20
|
+
end
|
21
|
+
next unless event
|
22
|
+
|
23
|
+
buffer.write line(idx, event, node.vlevel)
|
24
|
+
end
|
25
|
+
buffer.string
|
26
|
+
end
|
27
|
+
|
28
|
+
def line(line_idx, value, depth)
|
29
|
+
vars = value.vars
|
30
|
+
returned_value = value.return_value || {}
|
31
|
+
returned_str = "#{returned_value[:type]} #{returned_value[:value]}"
|
32
|
+
returned = ColorizedString["=> |#{returned_str}|"].colorize(:magenta)
|
33
|
+
|
34
|
+
class_method = ColorizedString["#{value.klass}##{value.method_name}"].colorize(:green)
|
35
|
+
full_path = ColorizedString["#{value.path}:#{value.lineno}"].colorize(:blue)
|
36
|
+
line_idx = ColorizedString["[#{line_idx}] "].colorize(:red)
|
37
|
+
var_str = vars.map do |_, val|
|
38
|
+
var_name = val[:name]
|
39
|
+
var_value = val[:value]
|
40
|
+
var_type = val[:type]
|
41
|
+
"#{var_type} #{var_name} => (#{var_value})"
|
42
|
+
end.join(', ')
|
43
|
+
"#{' ' * depth}#{line_idx}#{class_method}(#{var_str}) #{returned} -> #{full_path}\n"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/rshade/rspec/rspec.rb
CHANGED
@@ -1,13 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RShade
|
2
|
-
REPORTS = []
|
4
|
+
REPORTS = [].freeze
|
3
5
|
|
4
6
|
module RSpecHelper
|
5
|
-
def rshade_reveal(options = {})
|
7
|
+
def rshade_reveal(options = {}, &block)
|
6
8
|
raise 'No block given' unless block_given?
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
end
|
9
|
+
|
10
|
+
options.merge!(formatter: Formatter::String) { |_key, v1, _v2| v1 }
|
11
|
+
result = Trace.reveal(options, &block)
|
11
12
|
REPORTS.push result.show
|
12
13
|
end
|
13
14
|
end
|
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RShade
|
2
4
|
module Serializer
|
3
5
|
class Traversal
|
4
6
|
attr_reader :types
|
5
7
|
|
6
|
-
def initialize(custom_types={})
|
8
|
+
def initialize(custom_types = {})
|
7
9
|
@types = default_types.merge(custom_types)
|
8
10
|
end
|
9
11
|
|
@@ -17,31 +19,36 @@ module RShade
|
|
17
19
|
|
18
20
|
def default_types
|
19
21
|
{
|
20
|
-
default:
|
22
|
+
default: lambda(&:to_s),
|
21
23
|
Integer => ->(value) { value },
|
22
24
|
Float => ->(value) { value },
|
23
25
|
Numeric => ->(value) { value },
|
24
26
|
String => ->(value) { value },
|
25
|
-
Hash =>
|
27
|
+
Hash => lambda do |value|
|
26
28
|
hash = {}
|
27
|
-
|
28
|
-
|
29
|
+
begin
|
30
|
+
value.each do |k, v|
|
31
|
+
hash[k] = traverse(v)
|
32
|
+
end
|
33
|
+
rescue Exception => e
|
34
|
+
binding.pry
|
29
35
|
end
|
36
|
+
|
30
37
|
hash
|
31
38
|
end,
|
32
|
-
Array =>
|
39
|
+
Array => lambda do |value|
|
33
40
|
value.map { |item| traverse(item) }
|
34
41
|
end
|
35
42
|
}
|
36
43
|
end
|
37
44
|
|
38
45
|
def traverse(value)
|
39
|
-
klass =
|
46
|
+
klass = Class
|
40
47
|
klass = value.class unless value.is_a?(Class)
|
41
48
|
serializer = types[klass]
|
42
|
-
serializer
|
49
|
+
serializer ||= types[:default]
|
43
50
|
serializer.call(value)
|
44
51
|
end
|
45
52
|
end
|
46
53
|
end
|
47
|
-
end
|
54
|
+
end
|
data/lib/rshade/stack.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RShade
|
4
|
+
class Stack
|
5
|
+
attr_reader :config
|
6
|
+
|
7
|
+
def initialize(config: nil, registry: ::RShade::Config::Registry.instance)
|
8
|
+
@config = config || registry.default_stack_config
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.trace(config: nil)
|
12
|
+
new(config:).trace
|
13
|
+
end
|
14
|
+
|
15
|
+
def trace
|
16
|
+
config.exclude_gems!
|
17
|
+
result = binding.callers.drop(2).map do |bind|
|
18
|
+
frame = StackFrame.from_binding(bind)
|
19
|
+
next nil unless config.filter.call(frame)
|
20
|
+
|
21
|
+
frame
|
22
|
+
end.compact.reverse
|
23
|
+
config.formatter.call(result)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RShade
|
4
|
+
# nodoc
|
5
|
+
class StackFrame
|
6
|
+
attr_reader :hash
|
7
|
+
|
8
|
+
def initialize(hash)
|
9
|
+
@hash = hash
|
10
|
+
end
|
11
|
+
|
12
|
+
%i[source_location source local_vars receiver_variables].each do |method_name|
|
13
|
+
define_method method_name do
|
14
|
+
fetch method_name
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def path
|
19
|
+
source_location[:path]
|
20
|
+
end
|
21
|
+
|
22
|
+
# @param [Binding] binding_frame
|
23
|
+
def self.from_binding(binding_frame)
|
24
|
+
source_location = {
|
25
|
+
path: binding_frame.source_location[0],
|
26
|
+
line: binding_frame.source_location[1]
|
27
|
+
}
|
28
|
+
local_vars = binding_frame.local_variables.each_with_object({}) do |var_name, memo|
|
29
|
+
value = binding_frame.local_variable_get(var_name)
|
30
|
+
type = value.is_a?(Class) ? value : value.class
|
31
|
+
memo[var_name] = {
|
32
|
+
name: var_name,
|
33
|
+
value:,
|
34
|
+
type: type.to_s
|
35
|
+
}
|
36
|
+
end
|
37
|
+
receiver_variables = binding_frame.receiver.instance_variables.each_with_object({}) do |var_name, memo|
|
38
|
+
value = binding_frame.receiver.instance_variable_get(var_name)
|
39
|
+
type = value.is_a?(Class) ? value : value.class
|
40
|
+
memo[var_name] = {
|
41
|
+
name: var_name,
|
42
|
+
value:,
|
43
|
+
type: type.to_s
|
44
|
+
}
|
45
|
+
end
|
46
|
+
hash = { source_location:, local_vars:, source: {}, receiver_variables: }
|
47
|
+
new(hash)
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_s
|
51
|
+
"#{source_location} - #{local_vars} - #{source}"
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def fetch(key)
|
57
|
+
@hash[key]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/rshade/trace.rb
CHANGED
@@ -1,14 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RShade
|
2
4
|
class Trace
|
3
5
|
attr_reader :config, :event_store
|
4
|
-
|
6
|
+
|
5
7
|
# @param [RShade::Config,RShade::Config::Store] config
|
6
8
|
def initialize(config)
|
7
9
|
@config = fetch_config(config)
|
8
10
|
@event_store = EventTree.new
|
9
11
|
end
|
10
12
|
|
11
|
-
def self.reveal(config=nil, &block)
|
13
|
+
def self.reveal(config = nil, &block)
|
12
14
|
new(config).reveal(&block)
|
13
15
|
end
|
14
16
|
|
@@ -16,7 +18,7 @@ module RShade
|
|
16
18
|
processor = EventProcessor.new(event_store, config)
|
17
19
|
observer = EventObserver.new(config, processor)
|
18
20
|
observable = RShade::TraceObservable.new([observer], config)
|
19
|
-
observable.reveal
|
21
|
+
observable.reveal(&block)
|
20
22
|
self
|
21
23
|
end
|
22
24
|
|
@@ -25,8 +27,9 @@ module RShade
|
|
25
27
|
end
|
26
28
|
|
27
29
|
private
|
30
|
+
|
28
31
|
def fetch_config(config)
|
29
|
-
config
|
32
|
+
config ||= ::RShade::Config.default
|
30
33
|
config = config.value if config.is_a?(::RShade::Config)
|
31
34
|
config
|
32
35
|
end
|
@@ -1,7 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RShade
|
2
4
|
class TraceObservable
|
3
5
|
include Observable
|
4
6
|
attr_reader :trace_p
|
7
|
+
|
5
8
|
CALL_EVENTS = Set[:call, :c_call, :b_call]
|
6
9
|
RETURN_EVENTS = Set[:return, :c_return, :b_return]
|
7
10
|
|
@@ -27,6 +30,7 @@ module RShade
|
|
27
30
|
end
|
28
31
|
|
29
32
|
private
|
33
|
+
|
30
34
|
# more info https://rubyapi.org/3.1/o/tracepoint
|
31
35
|
# @param [TracePoint] tp
|
32
36
|
def process(tp)
|
@@ -34,6 +38,7 @@ module RShade
|
|
34
38
|
event = Event.from_trace_point(tp)
|
35
39
|
return notify_observers(event, :enter) if CALL_EVENTS.include?(tp.event)
|
36
40
|
return notify_observers(event, :leave) if RETURN_EVENTS.include?(tp.event)
|
41
|
+
|
37
42
|
notify_observers(event, :other)
|
38
43
|
end
|
39
44
|
end
|
data/lib/rshade/version.rb
CHANGED