danger 8.4.5 → 8.6.1
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/commands/pr.rb +2 -1
- data/lib/danger/comment_generators/vsts_inline.md.erb +17 -0
- data/lib/danger/danger_core/dangerfile.rb +2 -2
- data/lib/danger/danger_core/plugins/dangerfile_git_plugin.rb +1 -1
- data/lib/danger/helpers/comments_helper.rb +3 -2
- data/lib/danger/request_sources/vsts.rb +171 -8
- data/lib/danger/request_sources/vsts_api.rb +32 -0
- data/lib/danger/scm_source/git_repo.rb +2 -1
- data/lib/danger/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 691f7a26ea0a29f107e6f848bdf7450d2043dc15f5c385c136c1a9d818120c3f
|
4
|
+
data.tar.gz: d5f84a85ec8419dbbfbdcb742ffb15b5fe075d3bf1f676859152a0bb7b466633
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b712f8566113397b952ebd93e33d1d42b38d1b1a9d04e678971c35feb46a5bfb057236b0ccffc250560df6b1da001fe31f848024de318850c93ecb6af6eb0994
|
7
|
+
data.tar.gz: c89ab31d3afe5d668046629643d65858d6eeeea3d5f67006170af38e9a8c31673789de472501d37ff923c41fb538193cce767ae9567ef4a9a474aca96cf4aad4
|
data/lib/danger/commands/pr.rb
CHANGED
@@ -0,0 +1,17 @@
|
|
1
|
+
<%- @tables.each do |table| -%>
|
2
|
+
<%- if table[:content].any? || table[:resolved].any? -%>
|
3
|
+
| | |
|
4
|
+
|---|---|
|
5
|
+
<%- table[:content].each do |violation| -%>
|
6
|
+
| <%= @emoji_mapper.map(table[:emoji]) %> | <%= "~~" if table[:resolved] %><%= violation.message %><%= "~~" if table[:resolved] %> |
|
7
|
+
<%- end -%>
|
8
|
+
|
9
|
+
<%- end -%>
|
10
|
+
<%- end -%>
|
11
|
+
|
12
|
+
<%- @markdowns.each do |current| -%>
|
13
|
+
<%= current %>
|
14
|
+
<%# the previous line has to be aligned far to the left, otherwise markdown can break easily %>
|
15
|
+
<%- end -%>
|
16
|
+
|
17
|
+
Generated by :no_entry_sign: [Danger](https://danger.systems/ "generated_by_<%= @danger_id %>")
|
@@ -274,7 +274,7 @@ module Danger
|
|
274
274
|
env.scm.diff_for_folder(".".freeze, from: base_branch, to: head_branch, lookup_top_level: true)
|
275
275
|
end
|
276
276
|
|
277
|
-
def run(base_branch, head_branch, dangerfile_path, danger_id, new_comment, remove_previous_comments)
|
277
|
+
def run(base_branch, head_branch, dangerfile_path, danger_id, new_comment, remove_previous_comments, report_results = true)
|
278
278
|
# Setup internal state
|
279
279
|
init_plugins
|
280
280
|
env.fill_environment_vars
|
@@ -289,7 +289,7 @@ module Danger
|
|
289
289
|
# Push results to the API
|
290
290
|
# Pass along the details of the run to the request source
|
291
291
|
# to send back to the code review site.
|
292
|
-
post_results(danger_id, new_comment, remove_previous_comments)
|
292
|
+
post_results(danger_id, new_comment, remove_previous_comments) if report_results
|
293
293
|
|
294
294
|
# Print results in the terminal
|
295
295
|
print_results
|
@@ -128,7 +128,7 @@ module Danger
|
|
128
128
|
# @return [Git::Diff::DiffFile] from the gem `git`
|
129
129
|
#
|
130
130
|
def diff_for_file(file)
|
131
|
-
(added_files + modified_files).include?(file) ? @git.diff[file] : nil
|
131
|
+
(added_files + modified_files + deleted_files).include?(file) ? @git.diff[file] : nil
|
132
132
|
end
|
133
133
|
|
134
134
|
# @!group Git Metadata
|
@@ -24,7 +24,8 @@ module Danger
|
|
24
24
|
# @param [Bool] Should hide any generated link created
|
25
25
|
#
|
26
26
|
# @return [String] The Markdown compatible link
|
27
|
-
def markdown_link_to_message(message,
|
27
|
+
def markdown_link_to_message(message, hide_link)
|
28
|
+
return "" if hide_link
|
28
29
|
"#{message.file}#L#{message.line}"
|
29
30
|
end
|
30
31
|
|
@@ -147,7 +148,7 @@ module Danger
|
|
147
148
|
|
148
149
|
def generate_description(warnings: nil, errors: nil, template: "github")
|
149
150
|
emoji_mapper = EmojiMapper.new(template)
|
150
|
-
if errors.empty? && warnings.empty?
|
151
|
+
if (errors.nil? || errors.empty?) && (warnings.nil? || warnings.empty?)
|
151
152
|
return ENV['DANGER_SUCCESS_MESSAGE'] || "All green. #{random_compliment}"
|
152
153
|
else
|
153
154
|
message = "#{emoji_mapper.map('warning')} "
|
@@ -43,6 +43,10 @@ module Danger
|
|
43
43
|
@scm ||= GitRepo.new
|
44
44
|
end
|
45
45
|
|
46
|
+
def client
|
47
|
+
@api
|
48
|
+
end
|
49
|
+
|
46
50
|
def host
|
47
51
|
@host ||= @api.host
|
48
52
|
end
|
@@ -76,15 +80,36 @@ module Danger
|
|
76
80
|
return
|
77
81
|
end
|
78
82
|
|
79
|
-
|
83
|
+
regular_violations = regular_violations_group(
|
84
|
+
warnings: warnings,
|
85
|
+
errors: errors,
|
86
|
+
messages: messages,
|
87
|
+
markdowns: markdowns
|
88
|
+
)
|
89
|
+
|
90
|
+
inline_violations = inline_violations_group(
|
91
|
+
warnings: warnings,
|
92
|
+
errors: errors,
|
93
|
+
messages: messages,
|
94
|
+
markdowns: markdowns
|
95
|
+
)
|
96
|
+
|
97
|
+
rest_inline_violations = submit_inline_comments!(**{
|
98
|
+
danger_id: danger_id,
|
99
|
+
previous_violations: {}
|
100
|
+
}.merge(inline_violations))
|
101
|
+
|
102
|
+
main_violations = merge_violations(
|
103
|
+
regular_violations, rest_inline_violations
|
104
|
+
)
|
105
|
+
|
106
|
+
comment = generate_description(warnings: main_violations[:warnings], errors: main_violations[:errors])
|
80
107
|
comment += "\n\n"
|
81
|
-
comment += generate_comment(
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
danger_id: danger_id,
|
87
|
-
template: "vsts")
|
108
|
+
comment += generate_comment(**{
|
109
|
+
previous_violations: {},
|
110
|
+
danger_id: danger_id,
|
111
|
+
template: "vsts"
|
112
|
+
}.merge(main_violations))
|
88
113
|
if new_comment || remove_previous_comments
|
89
114
|
post_new_comment(comment)
|
90
115
|
else
|
@@ -105,6 +130,8 @@ module Danger
|
|
105
130
|
comment_content = comment[:content].nil? ? "" : comment[:content]
|
106
131
|
# Skip the comment if it wasn't posted by danger
|
107
132
|
next unless comment_content.include?("generated_by_#{danger_id}")
|
133
|
+
# Skip the comment if it's an inline comment
|
134
|
+
next unless c[:threadContext].nil?
|
108
135
|
# Updated the danger posted comment
|
109
136
|
@api.update_comment(thread_id, comment_id, new_comment)
|
110
137
|
comment_updated = true
|
@@ -112,6 +139,142 @@ module Danger
|
|
112
139
|
# If no comment was updated, post a new one
|
113
140
|
post_new_comment(new_comment) unless comment_updated
|
114
141
|
end
|
142
|
+
|
143
|
+
def submit_inline_comments!(warnings: [], errors: [], messages: [], markdowns: [], previous_violations: [], danger_id: "danger")
|
144
|
+
# Avoid doing any fetchs if there's no inline comments
|
145
|
+
return {} if (warnings + errors + messages + markdowns).select(&:inline?).empty?
|
146
|
+
|
147
|
+
pr_threads = @api.fetch_last_comments
|
148
|
+
danger_threads = pr_threads.select do |thread|
|
149
|
+
comment = thread[:comments].first
|
150
|
+
comment_content = comment[:content].nil? ? "" : comment[:content]
|
151
|
+
|
152
|
+
next comment_content.include?("generated_by_#{danger_id}")
|
153
|
+
end
|
154
|
+
non_danger_threads = pr_threads - danger_threads
|
155
|
+
|
156
|
+
warnings = submit_inline_comments_for_kind!(:warning, warnings, danger_threads, previous_violations["warning"], danger_id: danger_id)
|
157
|
+
errors = submit_inline_comments_for_kind!(:error, errors, danger_threads, previous_violations["error"], danger_id: danger_id)
|
158
|
+
messages = submit_inline_comments_for_kind!(:message, messages, danger_threads, previous_violations["message"], danger_id: danger_id)
|
159
|
+
markdowns = submit_inline_comments_for_kind!(:markdown, markdowns, danger_threads, [], danger_id: danger_id)
|
160
|
+
|
161
|
+
# submit removes from the array all comments that are still in force
|
162
|
+
# so we strike out all remaining ones
|
163
|
+
danger_threads.each do |thread|
|
164
|
+
violation = violations_from_table(thread[:comments].first[:content]).first
|
165
|
+
if !violation.nil? && violation.sticky
|
166
|
+
body = generate_inline_comment_body("white_check_mark", violation, danger_id: danger_id, resolved: true, template: "github")
|
167
|
+
@api.update_comment(thread[:id], thread[:comments].first[:id], body)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
{
|
172
|
+
warnings: warnings,
|
173
|
+
errors: errors,
|
174
|
+
messages: messages,
|
175
|
+
markdowns: markdowns
|
176
|
+
}
|
177
|
+
end
|
178
|
+
|
179
|
+
def messages_are_equivalent(m1, m2)
|
180
|
+
blob_regexp = %r{blob/[0-9a-z]+/}
|
181
|
+
m1.file == m2.file && m1.line == m2.line &&
|
182
|
+
m1.message.sub(blob_regexp, "") == m2.message.sub(blob_regexp, "")
|
183
|
+
end
|
184
|
+
|
185
|
+
def submit_inline_comments_for_kind!(kind, messages, danger_threads, previous_violations, danger_id: "danger")
|
186
|
+
previous_violations ||= []
|
187
|
+
is_markdown_content = kind == :markdown
|
188
|
+
emoji = { warning: "warning", error: "no_entry_sign", message: "book" }[kind]
|
189
|
+
|
190
|
+
messages.reject do |m|
|
191
|
+
next false unless m.file && m.line
|
192
|
+
|
193
|
+
# Once we know we're gonna submit it, we format it
|
194
|
+
if is_markdown_content
|
195
|
+
body = generate_inline_markdown_body(m, danger_id: danger_id, template: "vsts")
|
196
|
+
else
|
197
|
+
# Hide the inline link behind a span
|
198
|
+
m.message.gsub!("\n", "<br />")
|
199
|
+
m = process_markdown(m, true)
|
200
|
+
body = generate_inline_comment_body(emoji, m, danger_id: danger_id, template: "vsts")
|
201
|
+
# A comment might be in previous_violations because only now it's part of the unified diff
|
202
|
+
# We remove from the array since it won't have a place in the table anymore
|
203
|
+
previous_violations.reject! { |v| messages_are_equivalent(v, m) }
|
204
|
+
end
|
205
|
+
|
206
|
+
matching_threads = danger_threads.select do |comment_data|
|
207
|
+
if comment_data.key?(:threadContext) && !comment_data[:threadContext].nil? &&
|
208
|
+
comment_data[:threadContext][:filePath] == m.file &&
|
209
|
+
comment_data[:threadContext].key?(:rightFileStart) &&
|
210
|
+
comment_data[:threadContext][:rightFileStart][:line] == m.line
|
211
|
+
# Parse it to avoid problems with strikethrough
|
212
|
+
violation = violations_from_table(comment_data[:comments].first[:content]).first
|
213
|
+
if violation
|
214
|
+
messages_are_equivalent(violation, m)
|
215
|
+
else
|
216
|
+
blob_regexp = %r{blob/[0-9a-z]+/}
|
217
|
+
comment_data[:comments].first[:content].sub(blob_regexp, "") == body.sub(blob_regexp, "")
|
218
|
+
end
|
219
|
+
else
|
220
|
+
false
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
if matching_threads.empty?
|
225
|
+
@api.post_inline_comment(body, m.file, m.line)
|
226
|
+
|
227
|
+
# Not reject because this comment has not completed
|
228
|
+
next false
|
229
|
+
else
|
230
|
+
# Remove the surviving comment so we don't strike it out
|
231
|
+
danger_threads.reject! { |c| matching_threads.include? c }
|
232
|
+
|
233
|
+
# Update the comment to remove the strikethrough if present
|
234
|
+
thread = matching_threads.first
|
235
|
+
@api.update_comment(thread[:id], thread[:comments].first[:id], body)
|
236
|
+
end
|
237
|
+
|
238
|
+
# Remove this element from the array
|
239
|
+
next true
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
private
|
244
|
+
|
245
|
+
def regular_violations_group(warnings: [], errors: [], messages: [], markdowns: [])
|
246
|
+
{
|
247
|
+
warnings: warnings.reject(&:inline?),
|
248
|
+
errors: errors.reject(&:inline?),
|
249
|
+
messages: messages.reject(&:inline?),
|
250
|
+
markdowns: markdowns.reject(&:inline?)
|
251
|
+
}
|
252
|
+
end
|
253
|
+
|
254
|
+
def inline_violations_group(warnings: [], errors: [], messages: [], markdowns: [])
|
255
|
+
cmp = proc do |a, b|
|
256
|
+
next -1 unless a.file && a.line
|
257
|
+
next 1 unless b.file && b.line
|
258
|
+
|
259
|
+
next a.line <=> b.line if a.file == b.file
|
260
|
+
next a.file <=> b.file
|
261
|
+
end
|
262
|
+
|
263
|
+
# Sort to group inline comments by file
|
264
|
+
{
|
265
|
+
warnings: warnings.select(&:inline?).sort(&cmp),
|
266
|
+
errors: errors.select(&:inline?).sort(&cmp),
|
267
|
+
messages: messages.select(&:inline?).sort(&cmp),
|
268
|
+
markdowns: markdowns.select(&:inline?).sort(&cmp)
|
269
|
+
}
|
270
|
+
end
|
271
|
+
|
272
|
+
def merge_violations(*violation_groups)
|
273
|
+
violation_groups.inject({}) do |accumulator, group|
|
274
|
+
accumulator.merge(group) { |_, old, fresh| old + fresh }
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
115
278
|
end
|
116
279
|
end
|
117
280
|
end
|
@@ -76,6 +76,38 @@ module Danger
|
|
76
76
|
post(uri, body)
|
77
77
|
end
|
78
78
|
|
79
|
+
def post_inline_comment(text, file, line)
|
80
|
+
uri = URI("#{pr_api_endpoint}/threads?api-version=#{@api_version}")
|
81
|
+
body = {
|
82
|
+
"comments" => [
|
83
|
+
{
|
84
|
+
"parentCommentId" => 0,
|
85
|
+
"content" => text,
|
86
|
+
"commentType" => 1
|
87
|
+
}
|
88
|
+
],
|
89
|
+
"properties" => {
|
90
|
+
"Microsoft.TeamFoundation.Discussion.SupportsMarkdown" => {
|
91
|
+
"type" => "System.Int32",
|
92
|
+
"value" => 1
|
93
|
+
}
|
94
|
+
},
|
95
|
+
"status" => 1,
|
96
|
+
"threadContext" => {
|
97
|
+
"filePath" => file,
|
98
|
+
"rightFileEnd" => {
|
99
|
+
"line" => line + 1,
|
100
|
+
"offset" => 1
|
101
|
+
},
|
102
|
+
"rightFileStart" => {
|
103
|
+
"line" => line,
|
104
|
+
"offset" => 1
|
105
|
+
}
|
106
|
+
}
|
107
|
+
}.to_json
|
108
|
+
post(uri, body)
|
109
|
+
end
|
110
|
+
|
79
111
|
def update_comment(thread, id, new_comment)
|
80
112
|
uri = URI("#{pr_api_endpoint}/threads/#{thread}/comments/#{id}?api-version=#{@api_version}")
|
81
113
|
body = {
|
@@ -55,7 +55,8 @@ module Danger
|
|
55
55
|
def exec(string)
|
56
56
|
require "open3"
|
57
57
|
Dir.chdir(self.folder || ".") do
|
58
|
-
|
58
|
+
git_command = string.split(" ").dup.unshift("git")
|
59
|
+
Open3.popen2(default_env, *git_command) do |_stdin, stdout, _wait_thr|
|
59
60
|
stdout.read.rstrip
|
60
61
|
end
|
61
62
|
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.
|
4
|
+
version: 8.6.1
|
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: 2022-
|
12
|
+
date: 2022-04-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: claide
|
@@ -271,6 +271,7 @@ files:
|
|
271
271
|
- lib/danger/comment_generators/gitlab.md.erb
|
272
272
|
- lib/danger/comment_generators/gitlab_inline.md.erb
|
273
273
|
- lib/danger/comment_generators/vsts.md.erb
|
274
|
+
- lib/danger/comment_generators/vsts_inline.md.erb
|
274
275
|
- lib/danger/core_ext/file_list.rb
|
275
276
|
- lib/danger/core_ext/string.rb
|
276
277
|
- lib/danger/danger_core/dangerfile.rb
|