danger 8.0.3 → 8.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/danger/ci_source/bitrise.rb +19 -6
- data/lib/danger/ci_source/concourse.rb +61 -0
- data/lib/danger/ci_source/github_actions.rb +2 -1
- data/lib/danger/ci_source/teamcity.rb +2 -0
- data/lib/danger/core_ext/file_list.rb +1 -1
- data/lib/danger/danger_core/plugins/dangerfile_gitlab_plugin.rb +17 -0
- data/lib/danger/helpers/comments_helper.rb +1 -1
- data/lib/danger/request_sources/bitbucket_server.rb +73 -9
- data/lib/danger/request_sources/code_insights_api.rb +147 -0
- data/lib/danger/request_sources/github/github.rb +4 -4
- data/lib/danger/request_sources/gitlab.rb +52 -8
- data/lib/danger/version.rb +1 -1
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a23a15079e019e675afdc325babf115a1a6f38ddbd06a5ba11dd93243ea1dfa0
|
4
|
+
data.tar.gz: 380335b8eb423be1096f3b25b3f2602d24d7288b70deb69e8b9991e6dcf09d16
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2d68ba968f860e6b4631536548d23279677645d20e7cb5d9567c73222a87128c027664e72f176bca01a31adbbbc2b8f123f5f20997e005a428cc2321e979d023
|
7
|
+
data.tar.gz: 10ab5f0cb6c3810e0f4520724854a3a8e3e4aeef35c252ed7a3ac729a2407c73df382a6cb98b1682170efd215bc495a11a312fa1d47f5d1b546632bd415b8d0f
|
@@ -50,16 +50,29 @@ module Danger
|
|
50
50
|
self.repo_url = env["GIT_REPOSITORY_URL"]
|
51
51
|
|
52
52
|
matcher_url = self.repo_url
|
53
|
+
self.repo_slug = repo_slug_from(self.repo_url)
|
54
|
+
end
|
53
55
|
|
54
|
-
|
55
|
-
if
|
56
|
-
|
56
|
+
def repo_slug_from(url)
|
57
|
+
if url =~ URI::regexp
|
58
|
+
# Try to parse the URL as a valid URI. This should cover the cases of http/https/ssh URLs.
|
59
|
+
begin
|
60
|
+
uri = URI.parse(url)
|
61
|
+
return uri.path.sub(/^(\/)/,'').sub(/(.git)$/,'')
|
62
|
+
rescue URI::InvalidURIError
|
63
|
+
# In case URL could not be parsed fallback to git URL parsing.
|
64
|
+
repo_slug_asgiturl(url)
|
65
|
+
end
|
66
|
+
else
|
67
|
+
# In case URL could not be parsed fallback to git URL parsing. git@github.com:organization/repo.git
|
68
|
+
repo_slug_asgiturl(url)
|
57
69
|
end
|
70
|
+
end
|
58
71
|
|
72
|
+
def repo_slug_asgiturl(url)
|
73
|
+
matcher_url = url
|
59
74
|
repo_matches = matcher_url.match(%r{([\/:])(([^\/]+\/)+[^\/]+?)(\.git$|$)})[2]
|
60
|
-
|
61
|
-
self.repo_slug = repo_matches unless repo_matches.nil?
|
62
|
-
|
75
|
+
return repo_matches unless repo_matches.nil?
|
63
76
|
end
|
64
77
|
end
|
65
78
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require "git"
|
2
|
+
require "danger/request_sources/local_only"
|
3
|
+
|
4
|
+
module Danger
|
5
|
+
# Concourse CI Integration
|
6
|
+
#
|
7
|
+
# https://concourse-ci.org/
|
8
|
+
#
|
9
|
+
# ### CI Setup
|
10
|
+
#
|
11
|
+
# With Concourse, you run the docker images yourself, so you will want to add `yarn danger ci` within one of your build jobs.
|
12
|
+
#
|
13
|
+
# ``` shell
|
14
|
+
# build:
|
15
|
+
# image: golang
|
16
|
+
# commands:
|
17
|
+
# - ...
|
18
|
+
# - yarn danger ci
|
19
|
+
# ```
|
20
|
+
#
|
21
|
+
# ### Environment Variable Setup
|
22
|
+
#
|
23
|
+
# As this is self-hosted, you will need to add the `CONCOURSE` environment variable `export CONCOURSE=true` to your build environment,
|
24
|
+
# as well as setting environment variables for `PULL_REQUEST_ID` and `REPO_SLUG`. Assuming you are using the github pull request resource
|
25
|
+
# https://github.com/jtarchie/github-pullrequest-resource the id of the PR can be accessed from `git config --get pullrequest.id`.
|
26
|
+
#
|
27
|
+
# ### Token Setup
|
28
|
+
#
|
29
|
+
# Once again as this is self-hosted, you will need to add `DANGER_GITHUB_API_TOKEN` environment variable to the build environment.
|
30
|
+
# The suggested method of storing the token is within the vault - https://concourse-ci.org/creds.html
|
31
|
+
|
32
|
+
class Concourse < CI
|
33
|
+
def self.validates_as_ci?(env)
|
34
|
+
env.key? "CONCOURSE"
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.validates_as_pr?(env)
|
38
|
+
exists = ["PULL_REQUEST_ID", "REPO_SLUG"].all? { |x| env[x] && !env[x].empty? }
|
39
|
+
exists && env["PULL_REQUEST_ID"].to_i > 0
|
40
|
+
end
|
41
|
+
|
42
|
+
def supported_request_sources
|
43
|
+
@supported_request_sources ||= [
|
44
|
+
Danger::RequestSources::GitHub,
|
45
|
+
Danger::RequestSources::GitLab,
|
46
|
+
Danger::RequestSources::BitbucketServer,
|
47
|
+
Danger::RequestSources::BitbucketCloud
|
48
|
+
]
|
49
|
+
end
|
50
|
+
|
51
|
+
def initialize(env)
|
52
|
+
self.repo_slug = env["REPO_SLUG"]
|
53
|
+
|
54
|
+
if env["PULL_REQUEST_ID"].to_i > 0
|
55
|
+
self.pull_request_id = env["PULL_REQUEST_ID"]
|
56
|
+
end
|
57
|
+
self.repo_url = GitRepo.new.origins
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
@@ -27,6 +27,8 @@ module Danger
|
|
27
27
|
# branch="%teamcity.build.branch%"
|
28
28
|
# export GITHUB_PULL_REQUEST_ID=(${branch//\// })
|
29
29
|
# ```
|
30
|
+
# Or if you are using the pull request feature you can set an environment parameter called `GITHUB_PULL_REQUEST_ID`
|
31
|
+
# to the value of: `%teamcity.pullRequest.number`
|
30
32
|
#
|
31
33
|
# #### GitLab
|
32
34
|
#
|
@@ -9,7 +9,7 @@ module Danger
|
|
9
9
|
def include?(pattern)
|
10
10
|
self.each do |current|
|
11
11
|
unless current.nil?
|
12
|
-
return true if File.fnmatch(pattern, current) || pattern == current
|
12
|
+
return true if File.fnmatch(pattern, current, File::FNM_EXTGLOB) || pattern == current
|
13
13
|
end
|
14
14
|
end
|
15
15
|
return false
|
@@ -227,6 +227,23 @@ module Danger
|
|
227
227
|
paths.first(paths.count - 1).join(", ") + " & " + paths.last
|
228
228
|
end
|
229
229
|
|
230
|
+
# @!group Gitlab Misc
|
231
|
+
# Use to ignore inline messages which lay outside a diff's range, thereby not posting the comment.
|
232
|
+
# You can set hash to change behavior per each kinds. (ex. `{warning: true, error: false}`)
|
233
|
+
# @param [Bool] or [Hash<Symbol, Bool>] dismiss
|
234
|
+
# Ignore out of range inline messages, defaults to `true`
|
235
|
+
#
|
236
|
+
# @return [void]
|
237
|
+
def dismiss_out_of_range_messages(dismiss = true)
|
238
|
+
if dismiss.kind_of?(Hash)
|
239
|
+
@gitlab.dismiss_out_of_range_messages = dismiss
|
240
|
+
elsif dismiss.kind_of?(TrueClass)
|
241
|
+
@gitlab.dismiss_out_of_range_messages = true
|
242
|
+
elsif dismiss.kind_of?(FalseClass)
|
243
|
+
@gitlab.dismiss_out_of_range_messages = false
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
230
247
|
%i(title body author labels json diff).each do |suffix|
|
231
248
|
alias_method "pr_#{suffix}".to_sym, "mr_#{suffix}".to_sym
|
232
249
|
end
|
@@ -11,7 +11,7 @@ module Danger
|
|
11
11
|
include Danger::Helpers::CommentsParsingHelper
|
12
12
|
|
13
13
|
def markdown_parser(text)
|
14
|
-
Kramdown::Document.new(text, input: "GFM")
|
14
|
+
Kramdown::Document.new(text, input: "GFM", smart_quotes: %w[apos apos quot quot])
|
15
15
|
end
|
16
16
|
|
17
17
|
# !@group Extension points
|
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
require "danger/helpers/comments_helper"
|
4
4
|
require "danger/request_sources/bitbucket_server_api"
|
5
|
+
require "danger/request_sources/code_insights_api"
|
6
|
+
require_relative "request_source"
|
5
7
|
|
6
8
|
module Danger
|
7
9
|
module RequestSources
|
@@ -17,12 +19,21 @@ module Danger
|
|
17
19
|
]
|
18
20
|
end
|
19
21
|
|
22
|
+
def self.optional_env_vars
|
23
|
+
["DANGER_BITBUCKETSERVER_CODE_INSIGHTS_REPORT_KEY",
|
24
|
+
"DANGER_BITBUCKETSERVER_CODE_INSIGHTS_REPORT_TITLE",
|
25
|
+
"DANGER_BITBUCKETSERVER_CODE_INSIGHTS_REPORT_DESCRIPTION",
|
26
|
+
"DANGER_BITBUCKETSERVER_CODE_INSIGHTS_REPORT_LOGO_URL"
|
27
|
+
]
|
28
|
+
end
|
29
|
+
|
20
30
|
def initialize(ci_source, environment)
|
21
31
|
self.ci_source = ci_source
|
22
32
|
self.environment = environment
|
23
33
|
|
24
34
|
project, slug = ci_source.repo_slug.split("/")
|
25
35
|
@api = BitbucketServerAPI.new(project, slug, ci_source.pull_request_id, environment)
|
36
|
+
@code_insights = CodeInsightsAPI.new(project, slug, environment)
|
26
37
|
end
|
27
38
|
|
28
39
|
def validates_as_ci?
|
@@ -73,16 +84,42 @@ module Danger
|
|
73
84
|
def update_pull_request!(warnings: [], errors: [], messages: [], markdowns: [], danger_id: "danger", new_comment: false, remove_previous_comments: false)
|
74
85
|
delete_old_comments(danger_id: danger_id) if !new_comment || remove_previous_comments
|
75
86
|
|
76
|
-
|
87
|
+
# If configured, send a Code Insights API to provide the PR with a quality report
|
88
|
+
# which includes inline code violations found by Danger as Annotations.
|
89
|
+
# If no inline violations occurred, an empty, successful (green) report will be sent.
|
90
|
+
if @code_insights.ready?
|
91
|
+
inline_violations = inline_violations_group(warnings: warnings, errors: errors, messages: messages)
|
92
|
+
inline_warnings = inline_violations[:warnings] || []
|
93
|
+
inline_errors = inline_violations[:errors] || []
|
94
|
+
inline_messages = inline_violations[:messages] || []
|
95
|
+
|
96
|
+
head_commit = self.pr_json[:fromRef][:latestCommit]
|
97
|
+
@code_insights.send_report(head_commit,
|
98
|
+
inline_warnings,
|
99
|
+
inline_errors,
|
100
|
+
inline_messages)
|
101
|
+
end
|
102
|
+
|
103
|
+
# If we're sending inline comments separately via Code Insights,
|
104
|
+
# the main body comment should contain only generic, non-file specific messages.
|
105
|
+
if @code_insights.ready?
|
106
|
+
main_violations = main_violations_group(warnings: warnings, errors: errors, messages: messages)
|
107
|
+
warnings = main_violations[:warnings] || []
|
108
|
+
errors = main_violations[:errors] || []
|
109
|
+
messages = main_violations[:messages] || []
|
110
|
+
markdowns = main_violations[:markdowns] || []
|
111
|
+
end
|
112
|
+
|
113
|
+
comment = generate_description(warnings: warnings,
|
114
|
+
errors: errors)
|
77
115
|
comment += "\n\n"
|
78
116
|
comment += generate_comment(warnings: warnings,
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
117
|
+
errors: errors,
|
118
|
+
messages: messages,
|
119
|
+
markdowns: markdowns,
|
120
|
+
previous_violations: {},
|
121
|
+
danger_id: danger_id,
|
122
|
+
template: "bitbucket_server")
|
86
123
|
@api.post_comment(comment)
|
87
124
|
end
|
88
125
|
|
@@ -91,7 +128,34 @@ module Danger
|
|
91
128
|
@api.delete_comment(c[:id], c[:version]) if c[:text] =~ /generated_by_#{danger_id}/
|
92
129
|
end
|
93
130
|
end
|
94
|
-
|
131
|
+
|
132
|
+
def main_violations_group(warnings: [], errors: [], messages: [], markdowns: [])
|
133
|
+
{
|
134
|
+
warnings: warnings.reject(&:inline?),
|
135
|
+
errors: errors.reject(&:inline?),
|
136
|
+
messages: messages.reject(&:inline?),
|
137
|
+
markdowns: markdowns.reject(&:inline?)
|
138
|
+
}
|
139
|
+
end
|
140
|
+
|
141
|
+
def inline_violations_group(warnings: [], errors: [], messages: [], markdowns: [])
|
142
|
+
cmp = proc do |a, b|
|
143
|
+
next -1 unless a.file && a.line
|
144
|
+
next 1 unless b.file && b.line
|
145
|
+
|
146
|
+
next a.line <=> b.line if a.file == b.file
|
147
|
+
next a.file <=> b.file
|
148
|
+
end
|
149
|
+
|
150
|
+
# Sort to group inline comments by file
|
151
|
+
{
|
152
|
+
warnings: warnings.select(&:inline?).sort(&cmp),
|
153
|
+
errors: errors.select(&:inline?).sort(&cmp),
|
154
|
+
messages: messages.select(&:inline?).sort(&cmp),
|
155
|
+
markdowns: markdowns.select(&:inline?).sort(&cmp)
|
156
|
+
}
|
157
|
+
end
|
158
|
+
|
95
159
|
def update_pr_build_status(status, build_job_link, description)
|
96
160
|
changeset = self.pr_json[:fromRef][:latestCommit]
|
97
161
|
# Support for older versions of Bitbucket Server
|
@@ -0,0 +1,147 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Danger
|
4
|
+
module RequestSources
|
5
|
+
#
|
6
|
+
# Provides ability for Danger to interact with Atlassian's Code Insights API in order to provide code quality
|
7
|
+
# reports along with inline comments for specific lines in specific files.
|
8
|
+
# See https://developer.atlassian.com/server/bitbucket/how-tos/code-insights/ for more details.
|
9
|
+
#
|
10
|
+
# Currently this functionality is implemented only for Bitbucket Server request source.
|
11
|
+
class CodeInsightsAPI
|
12
|
+
attr_accessor :username, :password, :host, :report_key, :report_title, :report_description, :logo_url
|
13
|
+
|
14
|
+
def initialize(project, slug, environment)
|
15
|
+
@username = environment["DANGER_BITBUCKETSERVER_USERNAME"] || ""
|
16
|
+
@password = environment["DANGER_BITBUCKETSERVER_PASSWORD"] || ""
|
17
|
+
@host = environment["DANGER_BITBUCKETSERVER_HOST"] || ""
|
18
|
+
@report_key = environment["DANGER_BITBUCKETSERVER_CODE_INSIGHTS_REPORT_KEY"] || ""
|
19
|
+
@report_title = environment["DANGER_BITBUCKETSERVER_CODE_INSIGHTS_REPORT_TITLE"] || ""
|
20
|
+
@report_description = environment["DANGER_BITBUCKETSERVER_CODE_INSIGHTS_REPORT_DESCRIPTION"] || ""
|
21
|
+
@logo_url = environment["DANGER_BITBUCKETSERVER_CODE_INSIGHTS_REPORT_LOGO_URL"] || ""
|
22
|
+
@project = project
|
23
|
+
@slug = slug
|
24
|
+
end
|
25
|
+
|
26
|
+
def inspect
|
27
|
+
inspected = super
|
28
|
+
|
29
|
+
if @password
|
30
|
+
inspected = inspected.sub! @password, "********".freeze
|
31
|
+
end
|
32
|
+
|
33
|
+
inspected
|
34
|
+
end
|
35
|
+
|
36
|
+
def ready?
|
37
|
+
!(@report_key.empty? || @report_title.empty? || @report_description.empty? || @username.empty? || @password.empty? || @host.empty?)
|
38
|
+
end
|
39
|
+
|
40
|
+
def delete_report(commit)
|
41
|
+
uri = URI(report_endpoint_at_commit(commit))
|
42
|
+
request = Net::HTTP::Delete.new(uri.request_uri, {"Content-Type" => "application/json"})
|
43
|
+
request.basic_auth @username, @password
|
44
|
+
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: use_ssl) do |http|
|
45
|
+
http.request(request)
|
46
|
+
end
|
47
|
+
|
48
|
+
# show failure when server returns an error
|
49
|
+
case response
|
50
|
+
when Net::HTTPClientError, Net::HTTPServerError
|
51
|
+
# HTTP 4xx - 5xx
|
52
|
+
abort "\nError deleting report from Code Insights API: #{response.code} (#{response.message}) - #{response.body}\n\n"
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
def send_report(commit, inline_warnings, inline_errors, inline_messages)
|
58
|
+
delete_report(commit)
|
59
|
+
put_report(commit, inline_errors.count)
|
60
|
+
should_post_annotations = !(inline_warnings + inline_errors + inline_messages).empty?
|
61
|
+
if should_post_annotations
|
62
|
+
post_annotations(commit, inline_warnings, inline_errors, inline_messages)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def put_report(commit, inline_errors_count)
|
67
|
+
uri = URI(report_endpoint_at_commit(commit))
|
68
|
+
request = Net::HTTP::Put.new(uri.request_uri, {"Content-Type" => "application/json"})
|
69
|
+
request.basic_auth @username, @password
|
70
|
+
request.body = {"title": @report_title,
|
71
|
+
"details": @report_description,
|
72
|
+
"result": (inline_errors_count > 0) ? "FAIL" : "PASS",
|
73
|
+
"reporter": @username,
|
74
|
+
"link": "https://github.com/danger/danger",
|
75
|
+
"logoURL": @logo_url
|
76
|
+
}.to_json
|
77
|
+
|
78
|
+
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: use_ssl) do |http|
|
79
|
+
http.request(request)
|
80
|
+
end
|
81
|
+
|
82
|
+
# show failure when server returns an error
|
83
|
+
case response
|
84
|
+
when Net::HTTPClientError, Net::HTTPServerError
|
85
|
+
# HTTP 4xx - 5xx
|
86
|
+
abort "\nError putting report to Code Insights API: #{response.code} (#{response.message}) - #{response.body}\n\n"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def post_annotations(commit, inline_warnings, inline_errors, inline_messages)
|
91
|
+
uri = URI(annotation_endpoint_at_commit(commit))
|
92
|
+
|
93
|
+
annotations = []
|
94
|
+
|
95
|
+
inline_messages.each do |violation|
|
96
|
+
annotations << violation_hash_with_severity(violation, "LOW")
|
97
|
+
end
|
98
|
+
|
99
|
+
inline_warnings.each do |violation|
|
100
|
+
annotations << violation_hash_with_severity(violation, "MEDIUM")
|
101
|
+
end
|
102
|
+
|
103
|
+
inline_errors.each do |violation|
|
104
|
+
annotations << violation_hash_with_severity(violation, "HIGH")
|
105
|
+
end
|
106
|
+
|
107
|
+
body = {annotations: annotations}.to_json
|
108
|
+
request = Net::HTTP::Post.new(uri.request_uri, {"Content-Type" => "application/json"})
|
109
|
+
request.basic_auth @username, @password
|
110
|
+
request.body = body
|
111
|
+
|
112
|
+
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: use_ssl) do |http|
|
113
|
+
http.request(request)
|
114
|
+
end
|
115
|
+
|
116
|
+
# show failure when server returns an error
|
117
|
+
case response
|
118
|
+
when Net::HTTPClientError, Net::HTTPServerError
|
119
|
+
# HTTP 4xx - 5xx
|
120
|
+
abort "\nError posting comment to Code Insights API: #{response.code} (#{response.message}) - #{response.body}\n\n"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def violation_hash_with_severity(violation, severity)
|
125
|
+
annotation = {}
|
126
|
+
annotation["message"] = violation.message
|
127
|
+
annotation["severity"] = severity
|
128
|
+
annotation["path"] = violation.file
|
129
|
+
annotation["line"] = violation.line.to_i
|
130
|
+
return annotation
|
131
|
+
end
|
132
|
+
|
133
|
+
def report_endpoint_at_commit(commit)
|
134
|
+
"#{@host}/rest/insights/1.0/projects/#{@project}/repos/#{@slug}/commits/#{commit}/reports/#{@report_key}"
|
135
|
+
end
|
136
|
+
|
137
|
+
def annotation_endpoint_at_commit(commit)
|
138
|
+
report_endpoint_at_commit(commit) + "/annotations"
|
139
|
+
end
|
140
|
+
|
141
|
+
def use_ssl
|
142
|
+
@host.include? "https://"
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
@@ -171,10 +171,10 @@ module Danger
|
|
171
171
|
markdowns: markdowns
|
172
172
|
)
|
173
173
|
|
174
|
-
rest_inline_violations = submit_inline_comments!({
|
174
|
+
rest_inline_violations = submit_inline_comments!(**{
|
175
175
|
danger_id: danger_id,
|
176
176
|
previous_violations: previous_violations
|
177
|
-
}.merge(
|
177
|
+
}.merge(inline_violations))
|
178
178
|
|
179
179
|
main_violations = merge_violations(
|
180
180
|
regular_violations, rest_inline_violations
|
@@ -189,11 +189,11 @@ module Danger
|
|
189
189
|
|
190
190
|
# If there are still violations to show
|
191
191
|
if main_violations_sum.any?
|
192
|
-
body = generate_comment({
|
192
|
+
body = generate_comment(**{
|
193
193
|
template: "github",
|
194
194
|
danger_id: danger_id,
|
195
195
|
previous_violations: previous_violations
|
196
|
-
}.merge(
|
196
|
+
}.merge(main_violations))
|
197
197
|
|
198
198
|
comment_result =
|
199
199
|
if should_create_new_comment
|
@@ -8,7 +8,7 @@ module Danger
|
|
8
8
|
module RequestSources
|
9
9
|
class GitLab < RequestSource
|
10
10
|
include Danger::Helpers::CommentsHelper
|
11
|
-
attr_accessor :mr_json, :commits_json
|
11
|
+
attr_accessor :mr_json, :commits_json, :dismiss_out_of_range_messages
|
12
12
|
|
13
13
|
FIRST_GITLAB_GEM_WITH_VERSION_CHECK = Gem::Version.new("4.6.0")
|
14
14
|
FIRST_VERSION_WITH_INLINE_COMMENTS = Gem::Version.new("10.8.0")
|
@@ -24,6 +24,7 @@ module Danger
|
|
24
24
|
def initialize(ci_source, environment)
|
25
25
|
self.ci_source = ci_source
|
26
26
|
self.environment = environment
|
27
|
+
self.dismiss_out_of_range_messages = false
|
27
28
|
|
28
29
|
@token = @environment["DANGER_GITLAB_API_TOKEN"]
|
29
30
|
end
|
@@ -205,7 +206,7 @@ module Danger
|
|
205
206
|
markdowns: markdowns
|
206
207
|
)
|
207
208
|
|
208
|
-
rest_inline_violations = submit_inline_comments!({
|
209
|
+
rest_inline_violations = submit_inline_comments!(**{
|
209
210
|
danger_id: danger_id,
|
210
211
|
previous_violations: previous_violations
|
211
212
|
}.merge(inline_violations))
|
@@ -223,7 +224,7 @@ module Danger
|
|
223
224
|
|
224
225
|
# If there are still violations to show
|
225
226
|
if main_violations_sum.any?
|
226
|
-
body = generate_comment({
|
227
|
+
body = generate_comment(**{
|
227
228
|
template: "gitlab",
|
228
229
|
danger_id: danger_id,
|
229
230
|
previous_violations: previous_violations
|
@@ -302,6 +303,16 @@ module Danger
|
|
302
303
|
nil # TODO: Implement this
|
303
304
|
end
|
304
305
|
|
306
|
+
def dismiss_out_of_range_messages_for(kind)
|
307
|
+
if self.dismiss_out_of_range_messages.kind_of?(Hash) && self.dismiss_out_of_range_messages[kind]
|
308
|
+
self.dismiss_out_of_range_messages[kind]
|
309
|
+
elsif self.dismiss_out_of_range_messages == true
|
310
|
+
self.dismiss_out_of_range_messages
|
311
|
+
else
|
312
|
+
false
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
305
316
|
# @return [String] A URL to the specific file, ready to be downloaded
|
306
317
|
def file_url(organisation: nil, repository: nil, branch: nil, path: nil)
|
307
318
|
branch ||= 'master'
|
@@ -397,10 +408,9 @@ module Danger
|
|
397
408
|
|
398
409
|
messages.reject do |m|
|
399
410
|
next false unless m.file && m.line
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
411
|
+
# Reject if it's out of range and in dismiss mode
|
412
|
+
next true if dismiss_out_of_range_messages_for(kind) && is_out_of_range(mr_changes.changes, m)
|
413
|
+
|
404
414
|
# Once we know we're gonna submit it, we format it
|
405
415
|
if is_markdown_content
|
406
416
|
body = generate_inline_markdown_body(m, danger_id: danger_id, template: "gitlab")
|
@@ -473,7 +483,6 @@ module Danger
|
|
473
483
|
range_header_regexp = /@@ -(?<old>[0-9]+)(,([0-9]+))? \+(?<new>[0-9]+)(,([0-9]+))? @@.*/
|
474
484
|
|
475
485
|
change = changes.find { |c| c["new_path"] == message.file }
|
476
|
-
|
477
486
|
# If there is no changes or rename only or deleted, return nil.
|
478
487
|
return nil if change.nil? || change["diff"].empty? || change["deleted_file"]
|
479
488
|
|
@@ -520,6 +529,41 @@ module Danger
|
|
520
529
|
line: current_old_line - current_new_line + message.line.to_i
|
521
530
|
}
|
522
531
|
end
|
532
|
+
|
533
|
+
def is_out_of_range(changes, message)
|
534
|
+
change = changes.find { |c| c["new_path"] == message.file }
|
535
|
+
# If there is no changes or rename only or deleted, return out of range.
|
536
|
+
return true if change.nil? || change["diff"].empty? || change["deleted_file"]
|
537
|
+
|
538
|
+
# If new file then return in range
|
539
|
+
return false if change["new_file"]
|
540
|
+
|
541
|
+
addition_lines = generate_addition_lines(change["diff"])
|
542
|
+
return false if addition_lines.include?(message.line.to_i)
|
543
|
+
|
544
|
+
return true
|
545
|
+
end
|
546
|
+
|
547
|
+
def generate_addition_lines(diff)
|
548
|
+
range_header_regexp = /@@ -(?<old>[0-9]+)(,([0-9]+))? \+(?<new>[0-9]+)(,([0-9]+))? @@.*/
|
549
|
+
addition_lines = []
|
550
|
+
line_number = 0
|
551
|
+
diff.each_line do |line|
|
552
|
+
if line.match range_header_regexp
|
553
|
+
line = line.split('+').last
|
554
|
+
line = line.split(' ').first
|
555
|
+
range_string = line.split(',')
|
556
|
+
line_number = range_string[0].to_i - 1
|
557
|
+
elsif line.start_with?('+')
|
558
|
+
addition_lines.push(line_number)
|
559
|
+
elsif line.start_with?('-')
|
560
|
+
line_number=line_number-1
|
561
|
+
end
|
562
|
+
line_number=line_number+1
|
563
|
+
end
|
564
|
+
addition_lines
|
565
|
+
end
|
566
|
+
|
523
567
|
end
|
524
568
|
end
|
525
569
|
end
|
data/lib/danger/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: danger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 8.0
|
4
|
+
version: 8.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Orta Therox
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2020-
|
12
|
+
date: 2020-10-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: claide
|
@@ -107,14 +107,14 @@ dependencies:
|
|
107
107
|
requirements:
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: '2.
|
110
|
+
version: '2.3'
|
111
111
|
type: :runtime
|
112
112
|
prerelease: false
|
113
113
|
version_requirements: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
115
|
- - "~>"
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: '2.
|
117
|
+
version: '2.3'
|
118
118
|
- !ruby/object:Gem::Dependency
|
119
119
|
name: kramdown-parser-gfm
|
120
120
|
requirement: !ruby/object:Gem::Requirement
|
@@ -214,6 +214,7 @@ files:
|
|
214
214
|
- lib/danger/ci_source/code_build.rb
|
215
215
|
- lib/danger/ci_source/codefresh.rb
|
216
216
|
- lib/danger/ci_source/codeship.rb
|
217
|
+
- lib/danger/ci_source/concourse.rb
|
217
218
|
- lib/danger/ci_source/dotci.rb
|
218
219
|
- lib/danger/ci_source/drone.rb
|
219
220
|
- lib/danger/ci_source/github_actions.rb
|
@@ -301,6 +302,7 @@ files:
|
|
301
302
|
- lib/danger/request_sources/bitbucket_cloud_api.rb
|
302
303
|
- lib/danger/request_sources/bitbucket_server.rb
|
303
304
|
- lib/danger/request_sources/bitbucket_server_api.rb
|
305
|
+
- lib/danger/request_sources/code_insights_api.rb
|
304
306
|
- lib/danger/request_sources/github/github.rb
|
305
307
|
- lib/danger/request_sources/github/github_review.rb
|
306
308
|
- lib/danger/request_sources/github/github_review_resolver.rb
|