class Danger::RequestSources::CodeInsightsAPI

Provides ability for Danger to interact with Atlassian’s Code Insights API in order to provide code quality reports along with inline comments for specific lines in specific files.

See https://developer.atlassian.com/server/bitbucket/how-tos/code-insights/ for more details.

Currently this functionality is implemented only for Bitbucket Server request source.

Attributes

host[RW]
logo_url[RW]
password[RW]
report_description[RW]
report_key[RW]
report_title[RW]
username[RW]

Public Class Methods

new(project, slug, environment) click to toggle source
# File lib/danger/request_sources/code_insights_api.rb, line 14
def initialize(project, slug, environment)
  @username = environment["DANGER_BITBUCKETSERVER_USERNAME"] || ""
  @password = environment["DANGER_BITBUCKETSERVER_PASSWORD"] || ""
  @host = environment["DANGER_BITBUCKETSERVER_HOST"] || ""
  @report_key = environment["DANGER_BITBUCKETSERVER_CODE_INSIGHTS_REPORT_KEY"] || ""
  @report_title = environment["DANGER_BITBUCKETSERVER_CODE_INSIGHTS_REPORT_TITLE"] || ""
  @report_description = environment["DANGER_BITBUCKETSERVER_CODE_INSIGHTS_REPORT_DESCRIPTION"] || ""
  @logo_url = environment["DANGER_BITBUCKETSERVER_CODE_INSIGHTS_REPORT_LOGO_URL"] || ""
  @project = project
  @slug = slug
end

Public Instance Methods

annotation_endpoint_at_commit(commit) click to toggle source
# File lib/danger/request_sources/code_insights_api.rb, line 133
def annotation_endpoint_at_commit(commit)
  report_endpoint_at_commit(commit) + "/annotations"
end
delete_report(commit) click to toggle source
# File lib/danger/request_sources/code_insights_api.rb, line 38
def delete_report(commit)
  uri = URI(report_endpoint_at_commit(commit))
  request = Net::HTTP::Delete.new(uri.request_uri, { "Content-Type" => "application/json" })
  request.basic_auth @username, @password
  response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: use_ssl) do |http|
    http.request(request)
  end

  # show failure when server returns an error
  case response
  when Net::HTTPClientError, Net::HTTPServerError
    # HTTP 4xx - 5xx
    abort "\nError deleting report from Code Insights API: #{response.code} (#{response.message}) - #{response.body}\n\n"
  end
end
inspect() click to toggle source
Calls superclass method
# File lib/danger/request_sources/code_insights_api.rb, line 26
def inspect
  inspected = super

  inspected.gsub!(@password, "********") if @password

  inspected
end
post_annotations(commit, inline_warnings, inline_errors, inline_messages) click to toggle source
# File lib/danger/request_sources/code_insights_api.rb, line 86
def post_annotations(commit, inline_warnings, inline_errors, inline_messages)
  uri = URI(annotation_endpoint_at_commit(commit))

  annotations = []

  inline_messages.each do |violation|
    annotations << violation_hash_with_severity(violation, "LOW")
  end

  inline_warnings.each do |violation|
    annotations << violation_hash_with_severity(violation, "MEDIUM")
  end

  inline_errors.each do |violation|
    annotations << violation_hash_with_severity(violation, "HIGH")
  end

  body = { annotations: annotations }.to_json
  request = Net::HTTP::Post.new(uri.request_uri, { "Content-Type" => "application/json" })
  request.basic_auth @username, @password
  request.body = body

  response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: use_ssl) do |http|
    http.request(request)
  end

  # show failure when server returns an error
  case response
  when Net::HTTPClientError, Net::HTTPServerError
    # HTTP 4xx - 5xx
    abort "\nError posting comment to Code Insights API: #{response.code} (#{response.message}) - #{response.body}\n\n"
  end
end
put_report(commit, inline_errors_count) click to toggle source
# File lib/danger/request_sources/code_insights_api.rb, line 63
def put_report(commit, inline_errors_count)
  uri = URI(report_endpoint_at_commit(commit))
  request = Net::HTTP::Put.new(uri.request_uri, { "Content-Type" => "application/json" })
  request.basic_auth @username, @password
  request.body = { "title": @report_title,
                  "details": @report_description,
                  "result": inline_errors_count > 0 ? "FAIL" : "PASS",
                  "reporter": @username,
                  "link": "https://github.com/danger/danger",
                  "logoURL": @logo_url }.to_json

  response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: use_ssl) do |http|
    http.request(request)
  end

  # show failure when server returns an error
  case response
  when Net::HTTPClientError, Net::HTTPServerError
    # HTTP 4xx - 5xx
    abort "\nError putting report to Code Insights API: #{response.code} (#{response.message}) - #{response.body}\n\n"
  end
end
ready?() click to toggle source
# File lib/danger/request_sources/code_insights_api.rb, line 34
def ready?
  !(@report_key.empty? || @report_title.empty? || @report_description.empty? || @username.empty? || @password.empty? || @host.empty?)
end
report_endpoint_at_commit(commit) click to toggle source
# File lib/danger/request_sources/code_insights_api.rb, line 129
def report_endpoint_at_commit(commit)
  "#{@host}/rest/insights/1.0/projects/#{@project}/repos/#{@slug}/commits/#{commit}/reports/#{@report_key}"
end
send_report(commit, inline_warnings, inline_errors, inline_messages) click to toggle source
# File lib/danger/request_sources/code_insights_api.rb, line 54
def send_report(commit, inline_warnings, inline_errors, inline_messages)
  delete_report(commit)
  put_report(commit, inline_errors.count)
  should_post_annotations = !(inline_warnings + inline_errors + inline_messages).empty?
  if should_post_annotations
    post_annotations(commit, inline_warnings, inline_errors, inline_messages)
  end
end
use_ssl() click to toggle source
# File lib/danger/request_sources/code_insights_api.rb, line 137
def use_ssl
  @host.include? "https://"
end
violation_hash_with_severity(violation, severity) click to toggle source
# File lib/danger/request_sources/code_insights_api.rb, line 120
def violation_hash_with_severity(violation, severity)
  annotation = {}
  annotation["message"] = violation.message
  annotation["severity"] = severity
  annotation["path"] = violation.file
  annotation["line"] = violation.line.to_i
  return annotation
end