danger 8.2.1 → 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/README.md +1 -1
- data/lib/danger/ci_source/azure_pipelines.rb +5 -1
- data/lib/danger/ci_source/buildkite.rb +1 -1
- data/lib/danger/ci_source/codefresh.rb +7 -13
- data/lib/danger/ci_source/codemagic.rb +58 -0
- data/lib/danger/ci_source/gitlab_ci.rb +18 -17
- data/lib/danger/ci_source/jenkins.rb +1 -1
- data/lib/danger/ci_source/local_git_repo.rb +29 -37
- data/lib/danger/ci_source/local_only_git_repo.rb +4 -8
- data/lib/danger/ci_source/support/commits.rb +14 -12
- data/lib/danger/ci_source/support/pull_request_finder.rb +43 -40
- data/lib/danger/ci_source/xcode_cloud.rb +38 -0
- data/lib/danger/commands/dangerfile/init.rb +1 -1
- data/lib/danger/commands/pr.rb +2 -1
- data/lib/danger/comment_generators/gitlab_inline.md.erb +2 -7
- data/lib/danger/comment_generators/vsts_inline.md.erb +17 -0
- data/lib/danger/danger_core/dangerfile.rb +15 -8
- data/lib/danger/danger_core/environment_manager.rb +2 -0
- data/lib/danger/danger_core/plugins/dangerfile_git_plugin.rb +1 -1
- data/lib/danger/danger_core/plugins/dangerfile_github_plugin.rb +8 -0
- data/lib/danger/danger_core/plugins/dangerfile_gitlab_plugin.rb +16 -0
- data/lib/danger/helpers/array_subclass.rb +2 -2
- data/lib/danger/helpers/comments_helper.rb +4 -3
- data/lib/danger/helpers/emoji_mapper.rb +1 -1
- data/lib/danger/plugin_support/plugin.rb +6 -2
- data/lib/danger/request_sources/bitbucket_cloud.rb +0 -1
- data/lib/danger/request_sources/bitbucket_cloud_api.rb +7 -6
- data/lib/danger/request_sources/bitbucket_server.rb +20 -16
- data/lib/danger/request_sources/bitbucket_server_api.rb +17 -9
- data/lib/danger/request_sources/code_insights_api.rb +2 -3
- data/lib/danger/request_sources/github/github.rb +30 -26
- data/lib/danger/request_sources/gitlab.rb +24 -24
- data/lib/danger/request_sources/local_only.rb +1 -2
- data/lib/danger/request_sources/request_source.rb +16 -4
- data/lib/danger/request_sources/vsts.rb +171 -9
- data/lib/danger/request_sources/vsts_api.rb +34 -3
- data/lib/danger/scm_source/git_repo.rb +2 -1
- data/lib/danger/version.rb +1 -1
- metadata +17 -8
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Danger
|
2
4
|
module RequestSources
|
3
5
|
class RequestSource
|
4
|
-
DANGER_REPO_NAME = "danger"
|
6
|
+
DANGER_REPO_NAME = "danger"
|
5
7
|
|
6
|
-
attr_accessor :ci_source, :
|
8
|
+
attr_accessor :ci_source, :scm, :host, :ignored_violations
|
7
9
|
|
8
10
|
def self.env_vars
|
9
11
|
raise "Subclass and overwrite self.env_vars"
|
@@ -23,12 +25,12 @@ module Danger
|
|
23
25
|
end
|
24
26
|
|
25
27
|
def self.source_name
|
26
|
-
to_s.sub("Danger::RequestSources::"
|
28
|
+
to_s.sub("Danger::RequestSources::", "")
|
27
29
|
end
|
28
30
|
|
29
31
|
def self.available_source_names_and_envs
|
30
32
|
available_request_sources.map do |klass|
|
31
|
-
" - #{klass.source_name}: #{klass.env_vars.join(', '
|
33
|
+
" - #{klass.source_name}: #{klass.env_vars.join(', ').yellow}"
|
32
34
|
end
|
33
35
|
end
|
34
36
|
|
@@ -36,6 +38,16 @@ module Danger
|
|
36
38
|
raise "Subclass and overwrite initialize"
|
37
39
|
end
|
38
40
|
|
41
|
+
def inspect
|
42
|
+
inspected = super
|
43
|
+
|
44
|
+
inspected.gsub!(@token, "********") if @token
|
45
|
+
inspected.gsub!(@access_token, "********") if @access_token
|
46
|
+
inspected.gsub!(@bearer_token, "********") if @bearer_token
|
47
|
+
|
48
|
+
inspected
|
49
|
+
end
|
50
|
+
|
39
51
|
# @return [Boolean] whether scm.origins is a valid git repository or not
|
40
52
|
def validates_as_ci?
|
41
53
|
!!self.scm.origins.match(%r{#{Regexp.escape self.host}(:|/)(.+/.+?)(?:\.git)?$})
|
@@ -24,7 +24,6 @@ module Danger
|
|
24
24
|
|
25
25
|
def initialize(ci_source, environment)
|
26
26
|
self.ci_source = ci_source
|
27
|
-
self.environment = environment
|
28
27
|
|
29
28
|
@is_vsts_git = environment["BUILD_REPOSITORY_PROVIDER"] == "TfsGit"
|
30
29
|
|
@@ -44,6 +43,10 @@ module Danger
|
|
44
43
|
@scm ||= GitRepo.new
|
45
44
|
end
|
46
45
|
|
46
|
+
def client
|
47
|
+
@api
|
48
|
+
end
|
49
|
+
|
47
50
|
def host
|
48
51
|
@host ||= @api.host
|
49
52
|
end
|
@@ -77,15 +80,36 @@ module Danger
|
|
77
80
|
return
|
78
81
|
end
|
79
82
|
|
80
|
-
|
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])
|
81
107
|
comment += "\n\n"
|
82
|
-
comment += generate_comment(
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
danger_id: danger_id,
|
88
|
-
template: "vsts")
|
108
|
+
comment += generate_comment(**{
|
109
|
+
previous_violations: {},
|
110
|
+
danger_id: danger_id,
|
111
|
+
template: "vsts"
|
112
|
+
}.merge(main_violations))
|
89
113
|
if new_comment || remove_previous_comments
|
90
114
|
post_new_comment(comment)
|
91
115
|
else
|
@@ -106,6 +130,8 @@ module Danger
|
|
106
130
|
comment_content = comment[:content].nil? ? "" : comment[:content]
|
107
131
|
# Skip the comment if it wasn't posted by danger
|
108
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?
|
109
135
|
# Updated the danger posted comment
|
110
136
|
@api.update_comment(thread_id, comment_id, new_comment)
|
111
137
|
comment_updated = true
|
@@ -113,6 +139,142 @@ module Danger
|
|
113
139
|
# If no comment was updated, post a new one
|
114
140
|
post_new_comment(new_comment) unless comment_updated
|
115
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
|
+
|
116
278
|
end
|
117
279
|
end
|
118
280
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# coding: utf-8
|
2
3
|
|
3
4
|
require "base64"
|
@@ -35,9 +36,7 @@ module Danger
|
|
35
36
|
def inspect
|
36
37
|
inspected = super
|
37
38
|
|
38
|
-
if @token
|
39
|
-
inspected = inspected.sub! @token, "********".freeze
|
40
|
-
end
|
39
|
+
inspected.gsub!(@token, "********") if @token
|
41
40
|
|
42
41
|
inspected
|
43
42
|
end
|
@@ -77,6 +76,38 @@ module Danger
|
|
77
76
|
post(uri, body)
|
78
77
|
end
|
79
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
|
+
|
80
111
|
def update_comment(thread, id, new_comment)
|
81
112
|
uri = URI("#{pr_api_endpoint}/threads/#{thread}/comments/#{id}?api-version=#{@api_version}")
|
82
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,15 +1,15 @@
|
|
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
|
8
8
|
- Juanito Fatas
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2022-04-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: claide
|
@@ -147,16 +147,22 @@ dependencies:
|
|
147
147
|
name: terminal-table
|
148
148
|
requirement: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
|
-
- - "
|
150
|
+
- - ">="
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '1'
|
153
|
+
- - "<"
|
154
|
+
- !ruby/object:Gem::Version
|
155
|
+
version: '4'
|
153
156
|
type: :runtime
|
154
157
|
prerelease: false
|
155
158
|
version_requirements: !ruby/object:Gem::Requirement
|
156
159
|
requirements:
|
157
|
-
- - "
|
160
|
+
- - ">="
|
158
161
|
- !ruby/object:Gem::Version
|
159
162
|
version: '1'
|
163
|
+
- - "<"
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '4'
|
160
166
|
- !ruby/object:Gem::Dependency
|
161
167
|
name: cork
|
162
168
|
requirement: !ruby/object:Gem::Requirement
|
@@ -213,6 +219,7 @@ files:
|
|
213
219
|
- lib/danger/ci_source/cirrus.rb
|
214
220
|
- lib/danger/ci_source/code_build.rb
|
215
221
|
- lib/danger/ci_source/codefresh.rb
|
222
|
+
- lib/danger/ci_source/codemagic.rb
|
216
223
|
- lib/danger/ci_source/codeship.rb
|
217
224
|
- lib/danger/ci_source/concourse.rb
|
218
225
|
- lib/danger/ci_source/dotci.rb
|
@@ -237,6 +244,7 @@ files:
|
|
237
244
|
- lib/danger/ci_source/teamcity.rb
|
238
245
|
- lib/danger/ci_source/travis.rb
|
239
246
|
- lib/danger/ci_source/vsts.rb
|
247
|
+
- lib/danger/ci_source/xcode_cloud.rb
|
240
248
|
- lib/danger/ci_source/xcode_server.rb
|
241
249
|
- lib/danger/clients/rubygems_client.rb
|
242
250
|
- lib/danger/commands/dangerfile/gem.rb
|
@@ -263,6 +271,7 @@ files:
|
|
263
271
|
- lib/danger/comment_generators/gitlab.md.erb
|
264
272
|
- lib/danger/comment_generators/gitlab_inline.md.erb
|
265
273
|
- lib/danger/comment_generators/vsts.md.erb
|
274
|
+
- lib/danger/comment_generators/vsts_inline.md.erb
|
266
275
|
- lib/danger/core_ext/file_list.rb
|
267
276
|
- lib/danger/core_ext/string.rb
|
268
277
|
- lib/danger/danger_core/dangerfile.rb
|
@@ -319,7 +328,7 @@ homepage: https://github.com/danger/danger
|
|
319
328
|
licenses:
|
320
329
|
- MIT
|
321
330
|
metadata: {}
|
322
|
-
post_install_message:
|
331
|
+
post_install_message:
|
323
332
|
rdoc_options: []
|
324
333
|
require_paths:
|
325
334
|
- lib
|
@@ -334,8 +343,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
334
343
|
- !ruby/object:Gem::Version
|
335
344
|
version: '0'
|
336
345
|
requirements: []
|
337
|
-
rubygems_version: 3.1.
|
338
|
-
signing_key:
|
346
|
+
rubygems_version: 3.1.4
|
347
|
+
signing_key:
|
339
348
|
specification_version: 4
|
340
349
|
summary: Like Unit Tests, but for your Team Culture.
|
341
350
|
test_files: []
|