From 6604c9ada41e9bf2baacd464a080c9de054646f7 Mon Sep 17 00:00:00 2001 From: Hugo Tunius Date: Mon, 27 Jun 2016 17:29:01 +0200 Subject: [PATCH] [RequestSource] Move common comment code to helper --- lib/danger/helpers/comments_helper.rb | 119 ++++++++++++++++++ lib/danger/request_source/github.rb | 99 +-------------- .../lib/danger/request_sources/github_spec.rb | 8 +- 3 files changed, 129 insertions(+), 97 deletions(-) create mode 100644 lib/danger/helpers/comments_helper.rb diff --git a/lib/danger/helpers/comments_helper.rb b/lib/danger/helpers/comments_helper.rb new file mode 100644 index 000000000..6c54cb98a --- /dev/null +++ b/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("") + end + + def violations_from_table(table) + regex = %r{(?:)?(.*?)(?:)?\s*}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{}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{^

(.*)

$}) + # Remove the outer `

`, the -5 represents a newline + `

` + html = html[3...-5] if html.start_with? "

" + 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{}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 diff --git a/lib/danger/request_source/github.rb b/lib/danger/request_source/github.rb index dda439b4f..597e64f89 100644 --- a/lib/danger/request_source/github.rb +++ b/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) @@ -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 @@ -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) @@ -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] @@ -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{}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{(?:)?(.*?)(?:)?\s*}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("") - end - - def process_markdown(violation) - html = markdown_parser.render(violation.message) - # Remove the outer `

`, the -5 represents a newline + `

` - html = html[3...-5] if html.start_with? "

" - 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\/(.*)\/}) diff --git a/spec/lib/danger/request_sources/github_spec.rb b/spec/lib/danger/request_sources/github_spec.rb index 960e3f624..6b896b90e 100644 --- a/spec/lib/danger/request_sources/github_spec.rb +++ b/spec/lib/danger/request_sources/github_spec.rb @@ -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