class PartyFoul::IssueRenderers::Base
Attributes
Public Class Methods
A new renderer instance for GitHub issues
@param [Exception, Hash]
# File lib/party_foul/issue_renderers/base.rb, line 10 def initialize(exception, env) self.exception = exception self.env = env end
Public Instance Methods
The hash used for building the table in issue body
@return [Hash]
# File lib/party_foul/issue_renderers/base.rb, line 105 def body_options(count = 0) { Exception: exception, 'Last Occurrence' => occurred_at, Count: count + 1 } end
Builds an HTML table from hash
@return [String]
# File lib/party_foul/issue_renderers/base.rb, line 119 def build_table_from_hash(hash) "<table>#{rows_for_table_from_hash(hash)}</table>" end
Renderes the issue comment
Customize by overriding {#comment_options}
# File lib/party_foul/issue_renderers/base.rb, line 45 def comment build_table_from_hash(comment_options) end
The hash used for building the table in the comment body
@return [Hash]
# File lib/party_foul/issue_renderers/base.rb, line 112 def comment_options { 'Occurred At' => occurred_at } end
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.
@return [String]
# File lib/party_foul/issue_renderers/base.rb, line 75 def fingerprint Digest::SHA1.hexdigest(title) end
Provides additional labels using the configured options
@return [Array]
# File lib/party_foul/issue_renderers/base.rb, line 143 def labels if PartyFoul.additional_labels.respond_to? :call PartyFoul.additional_labels.call(self.exception, self.env) || [] else PartyFoul.additional_labels || [] end end
The timestamp when the exception occurred.
@return [String]
# File lib/party_foul/issue_renderers/base.rb, line 98 def occurred_at @occurred_at ||= Time.now.strftime('%B %d, %Y %H:%M:%S %z') end
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
@return [String]
# File lib/party_foul/issue_renderers/base.rb, line 128 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
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.
@return [String]
# File lib/party_foul/issue_renderers/base.rb, line 58 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
Title of the issue with any object ids masked
@return [String]
# File lib/party_foul/issue_renderers/base.rb, line 18 def title if PartyFoul.title_prefix "[#{PartyFoul.title_prefix}] #{masked_title}" else masked_title end end
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.
@return [String]
# File lib/party_foul/issue_renderers/base.rb, line 84 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
Private Instance Methods
# File lib/party_foul/issue_renderers/base.rb, line 153 def app_root Dir.pwd end
# File lib/party_foul/issue_renderers/base.rb, line 157 def bundle_root Bundler.bundle_path.to_s if defined?(Bundler) end
# File lib/party_foul/issue_renderers/base.rb, line 167 def extract_file_name_and_line_number(line) line.match(/#{app_root}\/((.+?):(\d+))/) end
# File lib/party_foul/issue_renderers/base.rb, line 179 def format_line(line) if from_bundler?(line) line.sub(bundle_root, '[bundle]...') else line.sub(app_root, '[app]...') end end
# File lib/party_foul/issue_renderers/base.rb, line 161 def from_bundler?(line) if bundle_root line.match(bundle_root) end end
# File lib/party_foul/issue_renderers/base.rb, line 175 def masked_title raw_title.gsub(/0x(\w+)/, "0xXXXXXX") end
# File lib/party_foul/issue_renderers/base.rb, line 171 def raw_title raise NotImplementedError end