Class: Danger::RequestSources::CodeInsightsAPI

Inherits:
Object
  • Object
show all
Defined in:
lib/danger/request_sources/code_insights_api.rb

Overview

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.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(project, slug, environment) ⇒ CodeInsightsAPI

Returns a new instance of CodeInsightsAPI.



14
15
16
17
18
19
20
21
22
23
24
# 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

Instance Attribute Details

#hostObject

Returns the value of attribute host.



12
13
14
# File 'lib/danger/request_sources/code_insights_api.rb', line 12

def host
  @host
end

#logo_urlObject

Returns the value of attribute logo_url.



12
13
14
# File 'lib/danger/request_sources/code_insights_api.rb', line 12

def logo_url
  @logo_url
end

#passwordObject

Returns the value of attribute password.



12
13
14
# File 'lib/danger/request_sources/code_insights_api.rb', line 12

def password
  @password
end

#report_descriptionObject

Returns the value of attribute report_description.



12
13
14
# File 'lib/danger/request_sources/code_insights_api.rb', line 12

def report_description
  @report_description
end

#report_keyObject

Returns the value of attribute report_key.



12
13
14
# File 'lib/danger/request_sources/code_insights_api.rb', line 12

def report_key
  @report_key
end

#report_titleObject

Returns the value of attribute report_title.



12
13
14
# File 'lib/danger/request_sources/code_insights_api.rb', line 12

def report_title
  @report_title
end

#usernameObject

Returns the value of attribute username.



12
13
14
# File 'lib/danger/request_sources/code_insights_api.rb', line 12

def username
  @username
end

Instance Method Details

#annotation_endpoint_at_commit(commit) ⇒ Object



137
138
139
# File 'lib/danger/request_sources/code_insights_api.rb', line 137

def annotation_endpoint_at_commit(commit)
  report_endpoint_at_commit(commit) + "/annotations"
end

#delete_report(commit) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/danger/request_sources/code_insights_api.rb', line 40

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

#inspectObject



26
27
28
29
30
31
32
33
34
# File 'lib/danger/request_sources/code_insights_api.rb', line 26

def inspect
  inspected = super

  if @password
    inspected = inspected.sub! @password, "********".freeze
  end

  inspected
end

#post_annotations(commit, inline_warnings, inline_errors, inline_messages) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/danger/request_sources/code_insights_api.rb', line 90

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) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/danger/request_sources/code_insights_api.rb', line 66

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?Boolean

Returns:

  • (Boolean)


36
37
38
# File 'lib/danger/request_sources/code_insights_api.rb', line 36

def ready?
  !(@report_key.empty? || @report_title.empty? || @report_description.empty? || @username.empty? || @password.empty? || @host.empty?)
end

#report_endpoint_at_commit(commit) ⇒ Object



133
134
135
# File 'lib/danger/request_sources/code_insights_api.rb', line 133

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) ⇒ Object



57
58
59
60
61
62
63
64
# File 'lib/danger/request_sources/code_insights_api.rb', line 57

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_sslObject



141
142
143
# File 'lib/danger/request_sources/code_insights_api.rb', line 141

def use_ssl
  @host.include? "https://"
end

#violation_hash_with_severity(violation, severity) ⇒ Object



124
125
126
127
128
129
130
131
# File 'lib/danger/request_sources/code_insights_api.rb', line 124

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