Class: Nugrant::Helper::Stack

Inherits:
Object
  • Object
show all
Defined in:
lib/nugrant/helper/stack.rb

Constant Summary collapse

@@DEFAULT_MATCHER =
/^(.+):([0-9]+)/

Class Method Summary collapse

Class Method Details

.extract_error_location(entry, options = {}) ⇒ Object

Extract error location information from a stack entry using the matcher received in arguments.

The usual stack entry format is:

> /home/users/joe/work/lib/ruby.rb:4:Error message

This function will extract the file and line information from the stack entry using the matcher. The matcher is expected to have two groups, the first for the file and the second for line.

The results is returned in form of a hash with two keys, :file for the file information and :line for the line information.

If the matcher matched zero group, return {:file => nil, :line => nil}. If the matcher matched one group, return {:file => file, :line => nil}. If the matcher matched two groups, return {:file => file, :line => line}.



76
77
78
79
80
81
82
83
# File 'lib/nugrant/helper/stack.rb', line 76

def self.extract_error_location(entry, options = {})
  matcher = options[:matcher] || @@DEFAULT_MATCHER

  result = matcher.match(entry)
  captures = result ? result.captures : []

  {:file => captures[0], :line => captures[1] ? captures[1].to_i() : nil}
end

.fetch_error_region(stack, options = {}) ⇒ Object



6
7
8
9
10
11
12
13
14
# File 'lib/nugrant/helper/stack.rb', line 6

def self.fetch_error_region(stack, options = {})
  entry = find_entry(stack, options)
  location = extract_error_location(entry, options)

  return (options[:unknown] || "Unknown") if not location[:file] and not location[:line]
  return location[:file] if not location[:line]

  fetch_error_region_from_location(location, options)
end

.fetch_error_region_from_location(location, options = {}) ⇒ Object



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
# File 'lib/nugrant/helper/stack.rb', line 16

def self.fetch_error_region_from_location(location, options = {})
  prefix = options[:prefix] || "   "
  width = options[:width] || 4
  file = File.new(location[:file], "r")
  line = location[:line]

  index = 0

  lines = []
  while (line_string = file.gets())
    index += 1
    next if (line - index).abs > width

    line_prefix = "#{prefix}#{index}:"
    line_prefix += (line == index ? ">>   " : "     ")

    lines << "#{line_prefix}#{line_string}"
  end

  lines.join().chomp()
rescue
  return (options[:unknown] || "Unknown") if not location[:file] and not location[:line]
  return location[:file] if not location[:line]

  "#{location[:file]}:#{location[:line]}"
ensure
  file.close() if file
end

.find_entry(stack, options = {}) ⇒ Object

Search a stack list (as simple string array) for the first entry that match the :matcher.



49
50
51
52
53
54
55
# File 'lib/nugrant/helper/stack.rb', line 49

def self.find_entry(stack, options = {})
  matcher = options[:matcher] || @@DEFAULT_MATCHER

  stack.find do |entry|
    entry =~ matcher
  end
end