Skip to content

Commit

Permalink
[RequestSource] Move common comment code to helper
Browse files Browse the repository at this point in the history
  • Loading branch information
Hugo Tunius committed Jul 27, 2016
1 parent f1df258 commit 6604c9a
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 97 deletions.
119 changes: 119 additions & 0 deletions lib/danger/helpers/comments_helper.rb
@@ -0,0 +1,119 @@
module Danger
module Helpers
module CommentsHelper
def markdown_parser
@markdown_parser ||= Redcarpet::Markdown.new(Redcarpet::Render::HTML, no_intra_emphasis: true)
end

def parse_tables_from_comment(comment)
comment.split("</table>")
end

def violations_from_table(table)
regex = %r{<td data-sticky="true">(?:<del>)?(.*?)(?:</del>)?\s*</td>}im
table.scan(regex).flatten.map(&:strip)
end

def parse_comment(comment)
tables = parse_tables_from_comment(comment)
violations = {}
tables.each do |table|
next unless table =~ %r{<th width="100%"(.*?)</th>}im
title = Regexp.last_match(1)
kind = table_kind_from_title(title)
next unless kind

violations[kind] = violations_from_table(table)
end

violations.reject { |_, v| v.empty? }
end

def process_markdown(violation)
html = markdown_parser.render(violation.message)
match = html.match(%r{^<p>(.*)</p>$})
# Remove the outer `<p>`, the -5 represents a newline + `</p>`
html = html[3...-5] if html.start_with? "<p>"
Violation.new(html, violation.sticky)
end

def parse_comment(comment)
tables = parse_tables_from_comment(comment)
violations = {}
tables.each do |table|
next unless table =~ %r{<th width="100%"(.*?)</th>}im
title = Regexp.last_match(1)
kind = table_kind_from_title(title)
next unless kind

violations[kind] = violations_from_table(table)
end

violations.reject { |_, v| v.empty? }
end

def table(name, emoji, violations, all_previous_violations)
content = violations.map { |v| process_markdown(v) }.uniq
kind = table_kind_from_title(name)
previous_violations = all_previous_violations[kind] || []
messages = content.map(&:message)
resolved_violations = previous_violations.uniq - messages
count = content.count

{
name: name,
emoji: emoji,
content: content,
resolved: resolved_violations,
count: count
}
end

def table_kind_from_title(title)
if title =~ /error/i
:error
elsif title =~ /warning/i
:warning
elsif title =~ /message/i
:message
end
end

def generate_comment(warnings: [], errors: [], messages: [], markdowns: [], previous_violations: {}, danger_id: 'danger', template: 'github')
require 'erb'

md_template = File.join(Danger.gem_path, "lib/danger/comment_generators/#{template}.md.erb")

# erb: http://www.rrn.dk/rubys-erb-templating-system
# for the extra args: http://stackoverflow.com/questions/4632879/erb-template-removing-the-trailing-line
@tables = [
table("Error", "no_entry_sign", errors, previous_violations),
table("Warning", "warning", warnings, previous_violations),
table("Message", "book", messages, previous_violations)
]
@markdowns = markdowns
@danger_id = danger_id

return ERB.new(File.read(md_template), 0, "-").result(binding)
end

def generate_description(warnings: nil, errors: nil)
if errors.empty? && warnings.empty?
return "All green. #{random_compliment}"
else
message = "⚠ "
message += "#{'Error'.danger_pluralize(errors.count)}. " unless errors.empty?
message += "#{'Warning'.danger_pluralize(warnings.count)}. " unless warnings.empty?
message += "Don't worry, everything is fixable."
return message
end
end

def random_compliment
compliment = ["Well done.", "Congrats.", "Woo!",
"Yay.", "Jolly good show.", "Good on 'ya.", "Nice work."]
compliment.sample
end
end
end
end
99 changes: 6 additions & 93 deletions lib/danger/request_source/github.rb
@@ -1,10 +1,13 @@
# coding: utf-8
require 'octokit'
require 'redcarpet'
require 'danger/helpers/comments_helper'

module Danger
module RequestSources
class GitHub < RequestSource
include Danger::Helpers::CommentsHelper

attr_accessor :pr_json, :issue_json, :support_tokenless_auth

def initialize(ci_source, environment)
Expand Down Expand Up @@ -32,10 +35,6 @@ def client
@client ||= Octokit::Client.new(access_token: @token)
end

def markdown_parser
@markdown_parser ||= Redcarpet::Markdown.new(Redcarpet::Render::HTML, no_intra_emphasis: true)
end

def pr_diff
@pr_diff ||= client.pull_request(ci_source.repo_slug, ci_source.pull_request_id, accept: 'application/vnd.github.v3.diff')
end
Expand Down Expand Up @@ -93,7 +92,8 @@ def update_pull_request!(warnings: [], errors: [], messages: [], markdowns: [],
messages: messages,
markdowns: markdowns,
previous_violations: previous_violations,
danger_id: danger_id)
danger_id: danger_id,
template: 'github')

if editable_issues.empty?
comment_result = client.add_comment(ci_source.repo_slug, ci_source.pull_request_id, body)
Expand All @@ -112,7 +112,7 @@ def update_pull_request!(warnings: [], errors: [], messages: [], markdowns: [],

def submit_pull_request_status!(warnings: [], errors: [], details_url: [])
status = (errors.count.zero? ? 'success' : 'failure')
message = generate_github_description(warnings: warnings, errors: errors)
message = generate_description(warnings: warnings, errors: errors)

latest_pr_commit_ref = self.pr_json[:head][:sha]

Expand Down Expand Up @@ -154,93 +154,6 @@ def delete_old_comments!(except: nil, danger_id: 'danger')
end
end

def random_compliment
compliment = ['Well done.', 'Congrats.', 'Woo!',
'Yay.', 'Jolly good show.', "Good on 'ya.", 'Nice work.']
compliment.sample
end

def generate_github_description(warnings: nil, errors: nil)
if errors.empty? && warnings.empty?
return "All green. #{random_compliment}"
else
message = "⚠ "
message += "#{'Error'.danger_pluralize(errors.count)}. " unless errors.empty?
message += "#{'Warning'.danger_pluralize(warnings.count)}. " unless warnings.empty?
message += "Don't worry, everything is fixable."
return message
end
end

def generate_comment(warnings: [], errors: [], messages: [], markdowns: [], previous_violations: {}, danger_id: 'danger')
require 'erb'

md_template = File.join(Danger.gem_path, 'lib/danger/comment_generators/github.md.erb')

# erb: http://www.rrn.dk/rubys-erb-templating-system
# for the extra args: http://stackoverflow.com/questions/4632879/erb-template-removing-the-trailing-line
@tables = [
table('Error', 'no_entry_sign', errors, previous_violations),
table('Warning', 'warning', warnings, previous_violations),
table('Message', 'book', messages, previous_violations)
]
@markdowns = markdowns
@danger_id = danger_id

return ERB.new(File.read(md_template), 0, '-').result(binding)
end

def table(name, emoji, violations, all_previous_violations)
content = violations.map { |v| process_markdown(v) }.uniq
kind = table_kind_from_title(name)
previous_violations = all_previous_violations[kind] || []
messages = content.map(&:message)
resolved_violations = previous_violations.uniq - messages
count = content.count
{ name: name, emoji: emoji, content: content, resolved: resolved_violations, count: count }
end

def parse_comment(comment)
tables = parse_tables_from_comment(comment)
violations = {}
tables.each do |table|
next unless table =~ %r{<th width="100%"(.*?)</th>}im
title = Regexp.last_match(1)
kind = table_kind_from_title(title)
next unless kind

violations[kind] = violations_from_table(table)
end

violations.reject { |_, v| v.empty? }
end

def violations_from_table(table)
regex = %r{<td data-sticky="true">(?:<del>)?(.*?)(?:</del>)?\s*</td>}im
table.scan(regex).flatten.map(&:strip)
end

def table_kind_from_title(title)
if title =~ /error/i
:error
elsif title =~ /warning/i
:warning
elsif title =~ /message/i
:message
end
end

def parse_tables_from_comment(comment)
comment.split("</table>")
end

def process_markdown(violation)
html = markdown_parser.render(violation.message)
# Remove the outer `<p>`, the -5 represents a newline + `</p>`
html = html[3...-5] if html.start_with? "<p>"
Violation.new(html, violation.sticky)
end

# @return [String] The organisation name, is nil if it can't be detected
def organisation
matched = self.issue_json[:repository_url].match(%r{repos\/(.*)\/})
Expand Down
8 changes: 4 additions & 4 deletions spec/lib/danger/request_sources/github_spec.rb
Expand Up @@ -310,22 +310,22 @@

describe "status message" do
it "Shows a success message when no errors/warnings" do
message = @g.generate_github_description(warnings: [], errors: [])
message = @g.generate_description(warnings: [], errors: [])
expect(message).to start_with("All green.")
end

it "Shows an error messages when there are errors" do
message = @g.generate_github_description(warnings: violations([1, 2, 3]), errors: [])
message = @g.generate_description(warnings: violations([1, 2, 3]), errors: [])
expect(message).to eq("⚠ 3 Warnings. Don't worry, everything is fixable.")
end

it "Shows an error message when errors and warnings" do
message = @g.generate_github_description(warnings: violations([1, 2]), errors: violations([1, 2, 3]))
message = @g.generate_description(warnings: violations([1, 2]), errors: violations([1, 2, 3]))
expect(message).to eq("⚠ 3 Errors. 2 Warnings. Don't worry, everything is fixable.")
end

it "Deals with singualars in messages when errors and warnings" do
message = @g.generate_github_description(warnings: violations([1]), errors: violations([1]))
message = @g.generate_description(warnings: violations([1]), errors: violations([1]))
expect(message).to eq("⚠ 1 Error. 1 Warning. Don't worry, everything is fixable.")
end
end
Expand Down

0 comments on commit 6604c9a

Please sign in to comment.