Class: PartyFoul::IssueRenderers::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/party_foul/issue_renderers/base.rb

Direct Known Subclasses

Rack, Rackless

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(exception, env) ⇒ Base

A new renderer instance for GitHub issues

Parameters:

  • (Exception, Hash)


11
12
13
14
# File 'lib/party_foul/issue_renderers/base.rb', line 11

def initialize(exception, env)
  self.exception = exception
  self.env       = env
end

Instance Attribute Details

#envObject

Returns the value of attribute env.



6
7
8
# File 'lib/party_foul/issue_renderers/base.rb', line 6

def env
  @env
end

#exceptionObject

Returns the value of attribute exception.



6
7
8
# File 'lib/party_foul/issue_renderers/base.rb', line 6

def exception
  @exception
end

#shaObject

Returns the value of attribute sha.



6
7
8
# File 'lib/party_foul/issue_renderers/base.rb', line 6

def sha
  @sha
end

Instance Method Details

#bodyString

Renders the issue body

Customize by overriding #body_options

Returns:

  • (String)


32
33
34
35
36
37
38
39
40
# File 'lib/party_foul/issue_renderers/base.rb', line 32

def body
  @body ||= <<-BODY
#{build_table_from_hash(body_options)}

## Stack Trace
<pre>#{stack_trace}</pre>
Fingerprint: `#{fingerprint}`
BODY
end

#body_options(count = 0) ⇒ Hash

The hash used for building the table in issue body

Returns:

  • (Hash)


106
107
108
# File 'lib/party_foul/issue_renderers/base.rb', line 106

def body_options(count = 0)
  { Exception: exception, 'Last Occurrence' => occurred_at, Count: count + 1 }
end

#build_table_from_hash(hash) ⇒ String

Builds an HTML table from hash

Returns:

  • (String)


120
121
122
# File 'lib/party_foul/issue_renderers/base.rb', line 120

def build_table_from_hash(hash)
  "<table>#{rows_for_table_from_hash(hash)}</table>"
end

#commentObject

Renderes the issue comment

Customize by overriding #comment_options



46
47
48
# File 'lib/party_foul/issue_renderers/base.rb', line 46

def comment
  build_table_from_hash(comment_options)
end

#comment_optionsHash

The hash used for building the table in the comment body

Returns:

  • (Hash)


113
114
115
# File 'lib/party_foul/issue_renderers/base.rb', line 113

def comment_options
  { 'Occurred At' => occurred_at }
end

#fingerprintString

A SHA1 hex digested representation of the title. The fingerprint is used to create a unique value in the issue body. This value is used for seraching when matching issues happen again in the future.

Returns:

  • (String)


76
77
78
# File 'lib/party_foul/issue_renderers/base.rb', line 76

def fingerprint
  Digest::SHA1.hexdigest(title)
end

#labelsArray

Provides additional labels using the configured options

Returns:

  • (Array)


144
145
146
147
148
149
150
# File 'lib/party_foul/issue_renderers/base.rb', line 144

def labels
  if PartyFoul.additional_labels.respond_to? :call
    PartyFoul.additional_labels.call(self.exception, self.env) || []
  else
    PartyFoul.additional_labels || []
  end
end

#occurred_atString

The timestamp when the exception occurred.

Returns:

  • (String)


99
100
101
# File 'lib/party_foul/issue_renderers/base.rb', line 99

def occurred_at
  @occurred_at ||= Time.now.strftime('%B %d, %Y %H:%M:%S %z')
end

#rows_for_table_from_hash(hash) ⇒ String

Builds the rows of an HTML table from hash. Keys as Headers cells and Values as Data cells If the Value is a Hash it will be rendered as a table

Returns:

  • (String)


129
130
131
132
133
134
135
136
137
138
139
# File 'lib/party_foul/issue_renderers/base.rb', line 129

def rows_for_table_from_hash(hash)
  hash.inject('') do |rows, row|
    key, value = row
    if row[1].kind_of?(Hash)
      value = build_table_from_hash(row[1])
    else
      value = CGI.escapeHTML(value.to_s)
    end
    rows += "<tr><th>#{key}</th><td>#{value}</td></tr>"
  end
end

#stack_traceString

Compiles the stack trace for use in the issue body. Lines in the stack trace that are part of the application will be rendered as links to the relative file and line on GitHub based upon PartyFoul.web_url, PartyFoul.owner, PartyFoul.repo, and PartyFoul.branch. The branch will be used at the time the exception happens to grab the SHA for that branch at that time for the purpose of linking.

Returns:

  • (String)


59
60
61
62
63
64
65
66
67
68
69
# File 'lib/party_foul/issue_renderers/base.rb', line 59

def stack_trace
  exception.backtrace.map do |line|
    if from_bundler?(line)
      format_line(line)
    elsif (matches = extract_file_name_and_line_number(line))
      "<a href='#{PartyFoul.repo_url}/blob/#{sha}/#{matches[2]}#L#{matches[3]}'>#{format_line(line)}</a>"
    else
      format_line(line)
    end
  end.join("\n")
end

#titleString

Title of the issue with any object ids masked

Returns:

  • (String)


19
20
21
22
23
24
25
# File 'lib/party_foul/issue_renderers/base.rb', line 19

def title
  if PartyFoul.title_prefix
    "[#{PartyFoul.title_prefix}] #{masked_title}"
  else
    masked_title
  end[0..255]
end

#update_body(old_body) ⇒ String

Will update the issue body. The count and the time stamp will both be updated. If the format of the issue body fails to match for whatever reason the issue body will be reset.

Returns:

  • (String)


85
86
87
88
89
90
91
92
93
94
# File 'lib/party_foul/issue_renderers/base.rb', line 85

def update_body(old_body)
  begin
    current_count = old_body.match(/<th>Count<\/th><td>(\d+)<\/td>/)[1].to_i
    old_body.sub!("<th>Count</th><td>#{current_count}</td>", "<th>Count</th><td>#{current_count + 1}</td>")
    old_body.sub!(/<th>Last Occurrence<\/th><td>.+?<\/td>/, "<th>Last Occurrence</th><td>#{occurred_at}</td>")
    old_body
  rescue
    self.body
  end
end