Class: Bugno::Backtrace

Inherits:
Object
  • Object
show all
Defined in:
lib/bugno/backtrace.rb

Constant Summary collapse

MAX_CONTEXT_LENGTH =
4

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(backtrace) ⇒ Backtrace

Returns a new instance of Backtrace.



10
11
12
13
# File 'lib/bugno/backtrace.rb', line 10

def initialize(backtrace)
  @backtrace = backtrace
  @files = {}
end

Instance Attribute Details

#backtraceObject (readonly)

Returns the value of attribute backtrace.



7
8
9
# File 'lib/bugno/backtrace.rb', line 7

def backtrace
  @backtrace
end

#filesObject (readonly)

Returns the value of attribute files.



8
9
10
# File 'lib/bugno/backtrace.rb', line 8

def files
  @files
end

Instance Method Details

#code_data(file_lines, lineno) ⇒ Object



57
58
59
# File 'lib/bugno/backtrace.rb', line 57

def code_data(file_lines, lineno)
  file_lines[lineno - 1]
end

#context_data(file_lines, lineno) ⇒ Object



61
62
63
64
65
66
# File 'lib/bugno/backtrace.rb', line 61

def context_data(file_lines, lineno)
  {
    pre: pre_data(file_lines, lineno),
    post: post_data(file_lines, lineno)
  }
end

#extra_frame_data(filename, lineno) ⇒ Object



36
37
38
39
40
41
42
43
# File 'lib/bugno/backtrace.rb', line 36

def extra_frame_data(filename, lineno)
  file_lines = get_file_lines(filename)

  {
    code: code_data(file_lines, lineno),
    context: context_data(file_lines, lineno)
  }
end

#get_file_lines(filename) ⇒ Object



45
46
47
# File 'lib/bugno/backtrace.rb', line 45

def get_file_lines(filename)
  @files[filename] ||= read_file(filename)
end

#parse_backtraceObject



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/bugno/backtrace.rb', line 15

def parse_backtrace
  @backtrace.map do |line|
    match = line.match(/(.*):(\d+)(?::in `([^']+)')?/)

    return nil unless match

    filename = match[1]
    lineno = match[2].to_i
    method = match[3]&.tr('0-9', '')
    frame_data = {
      code: nil,
      lineno: lineno,
      method: method,
      context: nil,
      filename: filename
    }

    frame_data.merge(extra_frame_data(filename, lineno))
  end
end

#post_data(file_lines, lineno) ⇒ Object



68
69
70
71
72
73
# File 'lib/bugno/backtrace.rb', line 68

def post_data(file_lines, lineno)
  from_line = lineno
  number_of_lines = [from_line + MAX_CONTEXT_LENGTH, file_lines.size].min - from_line

  file_lines[from_line, number_of_lines]
end

#pre_data(file_lines, lineno) ⇒ Object



75
76
77
78
79
80
# File 'lib/bugno/backtrace.rb', line 75

def pre_data(file_lines, lineno)
  to_line = lineno - 2
  from_line = [to_line - MAX_CONTEXT_LENGTH + 1, 0].max

  file_lines[from_line, (to_line - from_line + 1)].select { |line| line && !line.empty? }
end

#read_file(filename) ⇒ Object



49
50
51
52
53
54
55
# File 'lib/bugno/backtrace.rb', line 49

def read_file(filename)
  return unless File.exist?(filename)

  File.read(filename).split("\n")
rescue StandardError
  nil
end