dependabot-common 0.119.2 → 0.120.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/dependabot/clients/azure.rb +31 -9
- data/lib/dependabot/file_parsers/base/dependency_set.rb +0 -3
- data/lib/dependabot/git_commit_checker.rb +2 -0
- data/lib/dependabot/metadata_finders/base/changelog_finder.rb +2 -0
- data/lib/dependabot/metadata_finders/base/changelog_pruner.rb +0 -2
- data/lib/dependabot/pull_request_creator.rb +16 -3
- data/lib/dependabot/pull_request_creator/azure.rb +6 -6
- data/lib/dependabot/pull_request_creator/branch_namer.rb +0 -2
- data/lib/dependabot/pull_request_creator/github.rb +40 -8
- data/lib/dependabot/pull_request_creator/labeler.rb +4 -0
- data/lib/dependabot/pull_request_creator/message_builder.rb +15 -260
- data/lib/dependabot/pull_request_creator/message_builder/link_and_mention_sanitizer.rb +0 -2
- data/lib/dependabot/pull_request_creator/message_builder/metadata_presenter.rb +270 -0
- data/lib/dependabot/pull_request_creator/pr_name_prefixer.rb +2 -0
- data/lib/dependabot/shared_helpers.rb +2 -0
- data/lib/dependabot/version.rb +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8a591ed018e9734955f64c0f830dd403c103706b4ffe9f9db18c5eb9c701061d
|
|
4
|
+
data.tar.gz: 86c1b8b7d36005ec164c35016144cf60a00027c1e95e5943fb0199ae2b4772ba
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '02211953c4f4ca35f549629a4196a18ef875cb4aa9a67e06af8f56c564cd9dcd5e2322c5c3e8fa2a57e7517c90e6a3806c93c4ecea8e2ae6d2befc04167da875'
|
|
7
|
+
data.tar.gz: 31b207db8ee1fe5a2b36f598b3082a044b7e01de990f06c37d3864fa591982804e1b0921243613b0754dabcf5b01cff914dac4f56beac5418e1d636f81ca6064
|
|
@@ -28,6 +28,7 @@ module Dependabot
|
|
|
28
28
|
def initialize(source, credentials)
|
|
29
29
|
@source = source
|
|
30
30
|
@credentials = credentials
|
|
31
|
+
@auth_header = auth_header_for(credentials&.fetch("token", nil))
|
|
31
32
|
end
|
|
32
33
|
|
|
33
34
|
def fetch_commit(_repo, branch)
|
|
@@ -152,8 +153,9 @@ module Dependabot
|
|
|
152
153
|
"/pushes?api-version=5.0", content.to_json)
|
|
153
154
|
end
|
|
154
155
|
|
|
156
|
+
# rubocop:disable Metrics/ParameterLists
|
|
155
157
|
def create_pull_request(pr_name, source_branch, target_branch,
|
|
156
|
-
pr_description, labels)
|
|
158
|
+
pr_description, labels, work_item = nil)
|
|
157
159
|
# Azure DevOps only support descriptions up to 4000 characters
|
|
158
160
|
# https://developercommunity.visualstudio.com/content/problem/608770/remove-4000-character-limit-on-pull-request-descri.html
|
|
159
161
|
azure_max_length = 3999
|
|
@@ -162,13 +164,15 @@ module Dependabot
|
|
|
162
164
|
truncate_length = azure_max_length - truncated_msg.length
|
|
163
165
|
pr_description = pr_description[0..truncate_length] + truncated_msg
|
|
164
166
|
end
|
|
167
|
+
# rubocop:enable Metrics/ParameterLists
|
|
165
168
|
|
|
166
169
|
content = {
|
|
167
170
|
sourceRefName: "refs/heads/" + source_branch,
|
|
168
171
|
targetRefName: "refs/heads/" + target_branch,
|
|
169
172
|
title: pr_name,
|
|
170
173
|
description: pr_description,
|
|
171
|
-
labels: labels.map { |label| { name: label } }
|
|
174
|
+
labels: labels.map { |label| { name: label } },
|
|
175
|
+
workItemRefs: [{ id: work_item }]
|
|
172
176
|
}
|
|
173
177
|
|
|
174
178
|
post(source.api_endpoint +
|
|
@@ -180,8 +184,9 @@ module Dependabot
|
|
|
180
184
|
def get(url)
|
|
181
185
|
response = Excon.get(
|
|
182
186
|
url,
|
|
183
|
-
|
|
184
|
-
|
|
187
|
+
headers: auth_header,
|
|
188
|
+
user: credentials&.fetch("username", nil),
|
|
189
|
+
password: credentials&.fetch("password", nil),
|
|
185
190
|
idempotent: true,
|
|
186
191
|
**SharedHelpers.excon_defaults
|
|
187
192
|
)
|
|
@@ -193,12 +198,14 @@ module Dependabot
|
|
|
193
198
|
def post(url, json)
|
|
194
199
|
response = Excon.post(
|
|
195
200
|
url,
|
|
196
|
-
headers:
|
|
197
|
-
|
|
198
|
-
|
|
201
|
+
headers: auth_header.merge(
|
|
202
|
+
{
|
|
203
|
+
"Content-Type" => "application/json"
|
|
204
|
+
}
|
|
205
|
+
),
|
|
199
206
|
body: json,
|
|
200
|
-
user: credentials&.fetch("username"),
|
|
201
|
-
password: credentials&.fetch("password"),
|
|
207
|
+
user: credentials&.fetch("username", nil),
|
|
208
|
+
password: credentials&.fetch("password", nil),
|
|
202
209
|
idempotent: true,
|
|
203
210
|
**SharedHelpers.excon_defaults
|
|
204
211
|
)
|
|
@@ -209,6 +216,21 @@ module Dependabot
|
|
|
209
216
|
|
|
210
217
|
private
|
|
211
218
|
|
|
219
|
+
def auth_header_for(token)
|
|
220
|
+
return {} unless token
|
|
221
|
+
|
|
222
|
+
if token.include?(":")
|
|
223
|
+
encoded_token = Base64.encode64(token).delete("\n")
|
|
224
|
+
{ "Authorization" => "Basic #{encoded_token}" }
|
|
225
|
+
elsif Base64.decode64(token).ascii_only? &&
|
|
226
|
+
Base64.decode64(token).include?(":")
|
|
227
|
+
{ "Authorization" => "Basic #{token.delete("\n")}" }
|
|
228
|
+
else
|
|
229
|
+
{ "Authorization" => "Bearer #{token}" }
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
attr_reader :auth_header
|
|
212
234
|
attr_reader :credentials
|
|
213
235
|
attr_reader :source
|
|
214
236
|
end
|
|
@@ -60,7 +60,6 @@ module Dependabot
|
|
|
60
60
|
dependencies.find { |d| d.name&.downcase == name&.downcase }
|
|
61
61
|
end
|
|
62
62
|
|
|
63
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
|
64
63
|
def combined_dependency(old_dep, new_dep)
|
|
65
64
|
package_manager = old_dep.package_manager
|
|
66
65
|
v_cls = Utils.version_class_for_package_manager(package_manager)
|
|
@@ -89,8 +88,6 @@ module Dependabot
|
|
|
89
88
|
subdependency_metadata: subdependency_metadata
|
|
90
89
|
)
|
|
91
90
|
end
|
|
92
|
-
|
|
93
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
|
94
91
|
end
|
|
95
92
|
end
|
|
96
93
|
end
|
|
@@ -86,6 +86,7 @@ module Dependabot
|
|
|
86
86
|
raise Dependabot::GitDependencyReferenceNotFound, dependency.name
|
|
87
87
|
end
|
|
88
88
|
|
|
89
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
|
89
90
|
def local_tag_for_latest_version
|
|
90
91
|
tags =
|
|
91
92
|
local_tags.
|
|
@@ -114,6 +115,7 @@ module Dependabot
|
|
|
114
115
|
tag_sha: tag.tag_sha
|
|
115
116
|
}
|
|
116
117
|
end
|
|
118
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
|
117
119
|
|
|
118
120
|
def git_repo_reachable?
|
|
119
121
|
local_upload_pack
|
|
@@ -143,6 +143,7 @@ module Dependabot
|
|
|
143
143
|
select_best_changelog(files)
|
|
144
144
|
end
|
|
145
145
|
|
|
146
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
|
146
147
|
def select_best_changelog(files)
|
|
147
148
|
CHANGELOG_NAMES.each do |name|
|
|
148
149
|
candidates = files.select { |f| f.name =~ /#{name}/i }
|
|
@@ -163,6 +164,7 @@ module Dependabot
|
|
|
163
164
|
|
|
164
165
|
nil
|
|
165
166
|
end
|
|
167
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
|
166
168
|
|
|
167
169
|
def tag_for_new_version
|
|
168
170
|
@tag_for_new_version ||=
|
|
@@ -21,7 +21,6 @@ module Dependabot
|
|
|
21
21
|
!old_version_changelog_line.nil?
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
|
25
24
|
def pruned_text
|
|
26
25
|
changelog_lines = changelog_text.split("\n")
|
|
27
26
|
|
|
@@ -51,7 +50,6 @@ module Dependabot
|
|
|
51
50
|
|
|
52
51
|
changelog_lines.slice(slice_range).join("\n").sub(/\n*\z/, "")
|
|
53
52
|
end
|
|
54
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
|
55
53
|
|
|
56
54
|
private
|
|
57
55
|
|
|
@@ -17,13 +17,23 @@ module Dependabot
|
|
|
17
17
|
class RepoDisabled < StandardError; end
|
|
18
18
|
class NoHistoryInCommon < StandardError; end
|
|
19
19
|
|
|
20
|
+
# AnnotationError is raised if a PR was created, but failed annotation
|
|
21
|
+
class AnnotationError < StandardError
|
|
22
|
+
attr_reader :cause, :pull_request
|
|
23
|
+
def initialize(cause, pull_request)
|
|
24
|
+
super(cause.message)
|
|
25
|
+
@cause = cause
|
|
26
|
+
@pull_request = pull_request
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
20
30
|
attr_reader :source, :dependencies, :files, :base_commit,
|
|
21
31
|
:credentials, :pr_message_header, :pr_message_footer,
|
|
22
32
|
:custom_labels, :author_details, :signature_key,
|
|
23
33
|
:commit_message_options, :vulnerabilities_fixed,
|
|
24
34
|
:reviewers, :assignees, :milestone, :branch_name_separator,
|
|
25
35
|
:branch_name_prefix, :github_redirection_service,
|
|
26
|
-
:custom_headers
|
|
36
|
+
:custom_headers, :provider_metadata
|
|
27
37
|
|
|
28
38
|
def initialize(source:, base_commit:, dependencies:, files:, credentials:,
|
|
29
39
|
pr_message_header: nil, pr_message_footer: nil,
|
|
@@ -33,7 +43,8 @@ module Dependabot
|
|
|
33
43
|
branch_name_separator: "/", branch_name_prefix: "dependabot",
|
|
34
44
|
label_language: false, automerge_candidate: false,
|
|
35
45
|
github_redirection_service: "github-redirect.dependabot.com",
|
|
36
|
-
custom_headers: nil, require_up_to_date_base: false
|
|
46
|
+
custom_headers: nil, require_up_to_date_base: false,
|
|
47
|
+
provider_metadata: {})
|
|
37
48
|
@dependencies = dependencies
|
|
38
49
|
@source = source
|
|
39
50
|
@base_commit = base_commit
|
|
@@ -56,6 +67,7 @@ module Dependabot
|
|
|
56
67
|
@github_redirection_service = github_redirection_service
|
|
57
68
|
@custom_headers = custom_headers
|
|
58
69
|
@require_up_to_date_base = require_up_to_date_base
|
|
70
|
+
@provider_metadata = provider_metadata
|
|
59
71
|
|
|
60
72
|
check_dependencies_have_previous_version
|
|
61
73
|
end
|
|
@@ -142,7 +154,8 @@ module Dependabot
|
|
|
142
154
|
pr_description: message_builder.pr_message,
|
|
143
155
|
pr_name: message_builder.pr_name,
|
|
144
156
|
author_details: author_details,
|
|
145
|
-
labeler: labeler
|
|
157
|
+
labeler: labeler,
|
|
158
|
+
work_item: provider_metadata&.fetch(:work_item, nil)
|
|
146
159
|
)
|
|
147
160
|
end
|
|
148
161
|
|
|
@@ -8,11 +8,11 @@ module Dependabot
|
|
|
8
8
|
class Azure
|
|
9
9
|
attr_reader :source, :branch_name, :base_commit, :credentials,
|
|
10
10
|
:files, :commit_message, :pr_description, :pr_name,
|
|
11
|
-
:author_details, :labeler
|
|
11
|
+
:author_details, :labeler, :work_item
|
|
12
12
|
|
|
13
13
|
def initialize(source:, branch_name:, base_commit:, credentials:,
|
|
14
14
|
files:, commit_message:, pr_description:, pr_name:,
|
|
15
|
-
author_details:, labeler:)
|
|
15
|
+
author_details:, labeler:, work_item: nil)
|
|
16
16
|
@source = source
|
|
17
17
|
@branch_name = branch_name
|
|
18
18
|
@base_commit = base_commit
|
|
@@ -23,6 +23,7 @@ module Dependabot
|
|
|
23
23
|
@pr_name = pr_name
|
|
24
24
|
@author_details = author_details
|
|
25
25
|
@labeler = labeler
|
|
26
|
+
@work_item = work_item
|
|
26
27
|
end
|
|
27
28
|
|
|
28
29
|
def create
|
|
@@ -46,9 +47,7 @@ module Dependabot
|
|
|
46
47
|
end
|
|
47
48
|
|
|
48
49
|
def branch_exists?
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
@branch_ref
|
|
50
|
+
azure_client_for_source.branch(branch_name)
|
|
52
51
|
rescue ::Azure::Error::NotFound
|
|
53
52
|
false
|
|
54
53
|
end
|
|
@@ -79,7 +78,8 @@ module Dependabot
|
|
|
79
78
|
branch_name,
|
|
80
79
|
source.branch || default_branch,
|
|
81
80
|
pr_description,
|
|
82
|
-
labeler.labels_for_pr
|
|
81
|
+
labeler.labels_for_pr,
|
|
82
|
+
work_item
|
|
83
83
|
)
|
|
84
84
|
end
|
|
85
85
|
|
|
@@ -116,7 +116,6 @@ module Dependabot
|
|
|
116
116
|
gsub(",", "-and-")
|
|
117
117
|
end
|
|
118
118
|
|
|
119
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
|
120
119
|
def new_version(dependency)
|
|
121
120
|
# Version looks like a git SHA and we could be updating to a specific
|
|
122
121
|
# ref in which case we return that otherwise we return a shorthand sha
|
|
@@ -135,7 +134,6 @@ module Dependabot
|
|
|
135
134
|
dependency.version
|
|
136
135
|
end
|
|
137
136
|
end
|
|
138
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
|
139
137
|
|
|
140
138
|
def previous_ref(dependency)
|
|
141
139
|
previous_refs = dependency.previous_requirements.map do |r|
|
|
@@ -7,6 +7,7 @@ require "dependabot/pull_request_creator"
|
|
|
7
7
|
require "dependabot/pull_request_creator/commit_signer"
|
|
8
8
|
module Dependabot
|
|
9
9
|
class PullRequestCreator
|
|
10
|
+
# rubocop:disable Metrics/ClassLength
|
|
10
11
|
class Github
|
|
11
12
|
attr_reader :source, :branch_name, :base_commit, :credentials,
|
|
12
13
|
:files, :pr_description, :pr_name, :commit_message,
|
|
@@ -41,7 +42,7 @@ module Dependabot
|
|
|
41
42
|
return if require_up_to_date_base? && !base_commit_is_up_to_date?
|
|
42
43
|
|
|
43
44
|
create_annotated_pull_request
|
|
44
|
-
rescue Octokit::Error => e
|
|
45
|
+
rescue AnnotationError, Octokit::Error => e
|
|
45
46
|
handle_error(e)
|
|
46
47
|
end
|
|
47
48
|
|
|
@@ -51,6 +52,7 @@ module Dependabot
|
|
|
51
52
|
@require_up_to_date_base
|
|
52
53
|
end
|
|
53
54
|
|
|
55
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
|
54
56
|
def branch_exists?(name)
|
|
55
57
|
git_metadata_fetcher.ref_names.include?(name)
|
|
56
58
|
rescue Dependabot::GitDependenciesNotReachable => e
|
|
@@ -66,6 +68,7 @@ module Dependabot
|
|
|
66
68
|
retrying = true
|
|
67
69
|
retry
|
|
68
70
|
end
|
|
71
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
|
69
72
|
|
|
70
73
|
def unmerged_pull_request_exists?
|
|
71
74
|
pull_requests_for_branch.reject(&:merged).any?
|
|
@@ -109,7 +112,11 @@ module Dependabot
|
|
|
109
112
|
pull_request = create_pull_request
|
|
110
113
|
return unless pull_request
|
|
111
114
|
|
|
112
|
-
|
|
115
|
+
begin
|
|
116
|
+
annotate_pull_request(pull_request)
|
|
117
|
+
rescue StandardError => e
|
|
118
|
+
raise AnnotationError.new(e, pull_request)
|
|
119
|
+
end
|
|
113
120
|
|
|
114
121
|
pull_request
|
|
115
122
|
end
|
|
@@ -415,24 +422,49 @@ module Dependabot
|
|
|
415
422
|
end
|
|
416
423
|
|
|
417
424
|
def handle_error(err)
|
|
418
|
-
case err
|
|
425
|
+
cause = case err
|
|
426
|
+
when AnnotationError
|
|
427
|
+
err.cause
|
|
428
|
+
else
|
|
429
|
+
err
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
case cause
|
|
419
433
|
when Octokit::Forbidden
|
|
420
|
-
|
|
421
|
-
|
|
434
|
+
if err.message.include?("disabled")
|
|
435
|
+
raise_custom_error err, RepoDisabled, err.message
|
|
436
|
+
elsif err.message.include?("archived")
|
|
437
|
+
raise_custom_error err, RepoArchived, err.message
|
|
438
|
+
end
|
|
422
439
|
|
|
423
440
|
raise err
|
|
424
441
|
when Octokit::NotFound
|
|
425
442
|
raise err if repo_exists?
|
|
426
443
|
|
|
427
|
-
|
|
444
|
+
raise_custom_error err, RepoNotFound, err.message
|
|
428
445
|
when Octokit::UnprocessableEntity
|
|
429
|
-
|
|
446
|
+
if err.message.include?("no history in common")
|
|
447
|
+
raise_custom_error err, NoHistoryInCommon, err.message
|
|
448
|
+
end
|
|
430
449
|
|
|
431
|
-
raise
|
|
450
|
+
raise err
|
|
432
451
|
else
|
|
433
452
|
raise err
|
|
434
453
|
end
|
|
435
454
|
end
|
|
455
|
+
|
|
456
|
+
def raise_custom_error(base_err, type, message)
|
|
457
|
+
case base_err
|
|
458
|
+
when AnnotationError
|
|
459
|
+
raise AnnotationError.new(
|
|
460
|
+
type.new(message),
|
|
461
|
+
base_err.pull_request
|
|
462
|
+
)
|
|
463
|
+
else
|
|
464
|
+
raise type, message
|
|
465
|
+
end
|
|
466
|
+
end
|
|
436
467
|
end
|
|
468
|
+
# rubocop:enable Metrics/ClassLength
|
|
437
469
|
end
|
|
438
470
|
end
|
|
@@ -113,6 +113,7 @@ module Dependabot
|
|
|
113
113
|
end.min
|
|
114
114
|
end
|
|
115
115
|
|
|
116
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
|
116
117
|
def version(dep)
|
|
117
118
|
return dep.version if version_class.correct?(dep.version)
|
|
118
119
|
|
|
@@ -127,7 +128,9 @@ module Dependabot
|
|
|
127
128
|
|
|
128
129
|
version_from_ref
|
|
129
130
|
end
|
|
131
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
|
130
132
|
|
|
133
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
|
131
134
|
def previous_version(dep)
|
|
132
135
|
version_str = dep.previous_version
|
|
133
136
|
return version_str if version_class.correct?(version_str)
|
|
@@ -144,6 +147,7 @@ module Dependabot
|
|
|
144
147
|
|
|
145
148
|
version_from_ref
|
|
146
149
|
end
|
|
150
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
|
147
151
|
|
|
148
152
|
def create_default_dependencies_label_if_required
|
|
149
153
|
return if custom_labels
|
|
@@ -10,6 +10,7 @@ require "dependabot/pull_request_creator"
|
|
|
10
10
|
module Dependabot
|
|
11
11
|
class PullRequestCreator
|
|
12
12
|
class MessageBuilder
|
|
13
|
+
require_relative "message_builder/metadata_presenter"
|
|
13
14
|
require_relative "message_builder/issue_linker"
|
|
14
15
|
require_relative "message_builder/link_and_mention_sanitizer"
|
|
15
16
|
require_relative "pr_name_prefixer"
|
|
@@ -312,240 +313,38 @@ module Dependabot
|
|
|
312
313
|
end.join
|
|
313
314
|
end
|
|
314
315
|
|
|
315
|
-
def metadata_cascades_for_dep(
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
msg += commits_cascade(dep)
|
|
324
|
-
msg += maintainer_changes_cascade(dep)
|
|
325
|
-
msg += break_tag unless msg == ""
|
|
326
|
-
"\n" + sanitize_links_and_mentions(msg, unsafe: true)
|
|
327
|
-
end
|
|
328
|
-
|
|
329
|
-
def vulnerabilities_cascade(dep)
|
|
330
|
-
fixed_vulns = vulnerabilities_fixed[dep.name]
|
|
331
|
-
return "" unless fixed_vulns&.any?
|
|
332
|
-
|
|
333
|
-
msg = ""
|
|
334
|
-
fixed_vulns.each { |v| msg += serialized_vulnerability_details(v) }
|
|
335
|
-
msg = sanitize_template_tags(msg)
|
|
336
|
-
msg = sanitize_links_and_mentions(msg)
|
|
337
|
-
|
|
338
|
-
build_details_tag(summary: "Vulnerabilities fixed", body: msg)
|
|
339
|
-
end
|
|
340
|
-
|
|
341
|
-
def release_cascade(dep)
|
|
342
|
-
return "" unless releases_text(dep) && releases_url(dep)
|
|
343
|
-
|
|
344
|
-
msg = "*Sourced from [#{dep.display_name}'s releases]"\
|
|
345
|
-
"(#{releases_url(dep)}).*\n\n"
|
|
346
|
-
msg +=
|
|
347
|
-
begin
|
|
348
|
-
release_note_lines = releases_text(dep).split("\n").first(50)
|
|
349
|
-
release_note_lines = release_note_lines.map { |line| "> #{line}\n" }
|
|
350
|
-
if release_note_lines.count == 50
|
|
351
|
-
release_note_lines << truncated_line
|
|
352
|
-
end
|
|
353
|
-
release_note_lines.join
|
|
354
|
-
end
|
|
355
|
-
msg = link_issues(text: msg, dependency: dep)
|
|
356
|
-
msg = fix_relative_links(
|
|
357
|
-
text: msg,
|
|
358
|
-
base_url: source_url(dep) + "/blob/HEAD/"
|
|
359
|
-
)
|
|
360
|
-
msg = sanitize_template_tags(msg)
|
|
361
|
-
msg = sanitize_links_and_mentions(msg)
|
|
362
|
-
|
|
363
|
-
build_details_tag(summary: "Release notes", body: msg)
|
|
364
|
-
end
|
|
365
|
-
|
|
366
|
-
def changelog_cascade(dep)
|
|
367
|
-
return "" unless changelog_url(dep) && changelog_text(dep)
|
|
368
|
-
|
|
369
|
-
msg = "*Sourced from "\
|
|
370
|
-
"[#{dep.display_name}'s changelog](#{changelog_url(dep)}).*\n\n"
|
|
371
|
-
msg +=
|
|
372
|
-
begin
|
|
373
|
-
changelog_lines = changelog_text(dep).split("\n").first(50)
|
|
374
|
-
changelog_lines = changelog_lines.map { |line| "> #{line}\n" }
|
|
375
|
-
changelog_lines << truncated_line if changelog_lines.count == 50
|
|
376
|
-
changelog_lines.join
|
|
377
|
-
end
|
|
378
|
-
msg = link_issues(text: msg, dependency: dep)
|
|
379
|
-
msg = fix_relative_links(text: msg, base_url: changelog_url(dep))
|
|
380
|
-
msg = sanitize_template_tags(msg)
|
|
381
|
-
msg = sanitize_links_and_mentions(msg)
|
|
382
|
-
|
|
383
|
-
build_details_tag(summary: "Changelog", body: msg)
|
|
384
|
-
end
|
|
385
|
-
|
|
386
|
-
def upgrade_guide_cascade(dep)
|
|
387
|
-
return "" unless upgrade_url(dep) && upgrade_text(dep)
|
|
388
|
-
|
|
389
|
-
msg = "*Sourced from "\
|
|
390
|
-
"[#{dep.display_name}'s upgrade guide]"\
|
|
391
|
-
"(#{upgrade_url(dep)}).*\n\n"
|
|
392
|
-
msg +=
|
|
393
|
-
begin
|
|
394
|
-
upgrade_lines = upgrade_text(dep).split("\n").first(50)
|
|
395
|
-
upgrade_lines = upgrade_lines.map { |line| "> #{line}\n" }
|
|
396
|
-
upgrade_lines << truncated_line if upgrade_lines.count == 50
|
|
397
|
-
upgrade_lines.join
|
|
398
|
-
end
|
|
399
|
-
msg = link_issues(text: msg, dependency: dep)
|
|
400
|
-
msg = fix_relative_links(text: msg, base_url: upgrade_url(dep))
|
|
401
|
-
msg = sanitize_template_tags(msg)
|
|
402
|
-
msg = sanitize_links_and_mentions(msg)
|
|
403
|
-
|
|
404
|
-
build_details_tag(summary: "Upgrade guide", body: msg)
|
|
405
|
-
end
|
|
406
|
-
|
|
407
|
-
def commits_cascade(dep)
|
|
408
|
-
return "" unless commits_url(dep) && commits(dep)
|
|
409
|
-
|
|
410
|
-
msg = ""
|
|
411
|
-
|
|
412
|
-
commits(dep).reverse.first(10).each do |commit|
|
|
413
|
-
title = commit[:message].strip.split("\n").first
|
|
414
|
-
title = title.slice(0..76) + "..." if title && title.length > 80
|
|
415
|
-
title = title&.gsub(/(?<=[^\w.-])([_*`~])/, '\\1')
|
|
416
|
-
sha = commit[:sha][0, 7]
|
|
417
|
-
msg += "- [`#{sha}`](#{commit[:html_url]}) #{title}\n"
|
|
418
|
-
end
|
|
419
|
-
|
|
420
|
-
msg = msg.gsub(/\<.*?\>/) { |tag| "\\#{tag}" }
|
|
421
|
-
|
|
422
|
-
msg +=
|
|
423
|
-
if commits(dep).count > 10
|
|
424
|
-
"- Additional commits viewable in "\
|
|
425
|
-
"[compare view](#{commits_url(dep)})\n"
|
|
426
|
-
else
|
|
427
|
-
"- See full diff in [compare view](#{commits_url(dep)})\n"
|
|
428
|
-
end
|
|
429
|
-
msg = link_issues(text: msg, dependency: dep)
|
|
430
|
-
msg = sanitize_links_and_mentions(msg)
|
|
431
|
-
|
|
432
|
-
build_details_tag(summary: "Commits", body: msg)
|
|
433
|
-
end
|
|
434
|
-
|
|
435
|
-
def maintainer_changes_cascade(dep)
|
|
436
|
-
return "" unless maintainer_changes(dep)
|
|
437
|
-
|
|
438
|
-
build_details_tag(
|
|
439
|
-
summary: "Maintainer changes",
|
|
440
|
-
body: sanitize_links_and_mentions(maintainer_changes(dep)) + "\n"
|
|
441
|
-
)
|
|
442
|
-
end
|
|
443
|
-
|
|
444
|
-
def build_details_tag(summary:, body:)
|
|
445
|
-
# Azure DevOps does not support <details> tag (https://developercommunity.visualstudio.com/content/problem/608769/add-support-for-in-markdown.html)
|
|
446
|
-
# CodeCommit does not support the <details> tag (no url available)
|
|
447
|
-
if source_provider_supports_html?
|
|
448
|
-
msg = "<details>\n<summary>#{summary}</summary>\n\n"
|
|
449
|
-
msg += body
|
|
450
|
-
msg + "</details>\n"
|
|
451
|
-
else
|
|
452
|
-
"\n\##{summary}\n\n#{body}"
|
|
453
|
-
end
|
|
454
|
-
end
|
|
455
|
-
|
|
456
|
-
def source_provider_supports_html?
|
|
457
|
-
!%w(azure codecommit).include?(source.provider)
|
|
458
|
-
end
|
|
459
|
-
|
|
460
|
-
def serialized_vulnerability_details(details)
|
|
461
|
-
msg = vulnerability_source_line(details)
|
|
462
|
-
|
|
463
|
-
if details["title"]
|
|
464
|
-
msg += "> **#{details['title'].lines.map(&:strip).join(' ')}**\n"
|
|
465
|
-
end
|
|
466
|
-
|
|
467
|
-
if (description = details["description"])
|
|
468
|
-
description.strip.lines.first(20).each { |line| msg += "> #{line}" }
|
|
469
|
-
msg += truncated_line if description.strip.lines.count > 20
|
|
470
|
-
end
|
|
471
|
-
|
|
472
|
-
msg += "\n" unless msg.end_with?("\n")
|
|
473
|
-
msg += "> \n"
|
|
474
|
-
msg += vulnerability_version_range_lines(details)
|
|
475
|
-
msg + "\n"
|
|
476
|
-
end
|
|
477
|
-
|
|
478
|
-
def vulnerability_source_line(details)
|
|
479
|
-
if details["source_url"] && details["source_name"]
|
|
480
|
-
"*Sourced from [#{details['source_name']}]"\
|
|
481
|
-
"(#{details['source_url']}).*\n\n"
|
|
482
|
-
elsif details["source_name"]
|
|
483
|
-
"*Sourced from #{details['source_name']}.*\n\n"
|
|
484
|
-
else
|
|
485
|
-
""
|
|
486
|
-
end
|
|
487
|
-
end
|
|
488
|
-
|
|
489
|
-
def vulnerability_version_range_lines(details)
|
|
490
|
-
msg = ""
|
|
491
|
-
%w(patched_versions unaffected_versions affected_versions).each do |tp|
|
|
492
|
-
type = tp.split("_").first.capitalize
|
|
493
|
-
next unless details[tp]
|
|
494
|
-
|
|
495
|
-
versions_string = details[tp].any? ? details[tp].join("; ") : "none"
|
|
496
|
-
versions_string = versions_string.gsub(/(?<!\\)~/, '\~')
|
|
497
|
-
msg += "> #{type} versions: #{versions_string}\n"
|
|
498
|
-
end
|
|
499
|
-
msg
|
|
500
|
-
end
|
|
501
|
-
|
|
502
|
-
def truncated_line
|
|
503
|
-
# Tables can spill out of truncated details, so we close them
|
|
504
|
-
"></tr></table> ... (truncated)\n"
|
|
505
|
-
end
|
|
506
|
-
|
|
507
|
-
def releases_url(dependency)
|
|
508
|
-
metadata_finder(dependency).releases_url
|
|
509
|
-
end
|
|
510
|
-
|
|
511
|
-
def releases_text(dependency)
|
|
512
|
-
metadata_finder(dependency).releases_text
|
|
316
|
+
def metadata_cascades_for_dep(dependency)
|
|
317
|
+
MetadataPresenter.new(
|
|
318
|
+
dependency: dependency,
|
|
319
|
+
source: source,
|
|
320
|
+
metadata_finder: metadata_finder(dependency),
|
|
321
|
+
vulnerabilities_fixed: vulnerabilities_fixed[dependency.name],
|
|
322
|
+
github_redirection_service: github_redirection_service
|
|
323
|
+
).to_s
|
|
513
324
|
end
|
|
514
325
|
|
|
515
326
|
def changelog_url(dependency)
|
|
516
327
|
metadata_finder(dependency).changelog_url
|
|
517
328
|
end
|
|
518
329
|
|
|
519
|
-
def changelog_text(dependency)
|
|
520
|
-
metadata_finder(dependency).changelog_text
|
|
521
|
-
end
|
|
522
|
-
|
|
523
|
-
def upgrade_url(dependency)
|
|
524
|
-
metadata_finder(dependency).upgrade_guide_url
|
|
525
|
-
end
|
|
526
|
-
|
|
527
|
-
def upgrade_text(dependency)
|
|
528
|
-
metadata_finder(dependency).upgrade_guide_text
|
|
529
|
-
end
|
|
530
|
-
|
|
531
330
|
def commits_url(dependency)
|
|
532
331
|
metadata_finder(dependency).commits_url
|
|
533
332
|
end
|
|
534
333
|
|
|
535
|
-
def
|
|
536
|
-
metadata_finder(dependency).
|
|
334
|
+
def homepage_url(dependency)
|
|
335
|
+
metadata_finder(dependency).homepage_url
|
|
537
336
|
end
|
|
538
337
|
|
|
539
|
-
def
|
|
540
|
-
metadata_finder(dependency).
|
|
338
|
+
def releases_url(dependency)
|
|
339
|
+
metadata_finder(dependency).releases_url
|
|
541
340
|
end
|
|
542
341
|
|
|
543
342
|
def source_url(dependency)
|
|
544
343
|
metadata_finder(dependency).source_url
|
|
545
344
|
end
|
|
546
345
|
|
|
547
|
-
def
|
|
548
|
-
metadata_finder(dependency).
|
|
346
|
+
def upgrade_url(dependency)
|
|
347
|
+
metadata_finder(dependency).upgrade_guide_url
|
|
549
348
|
end
|
|
550
349
|
|
|
551
350
|
def metadata_finder(dependency)
|
|
@@ -567,7 +366,6 @@ module Dependabot
|
|
|
567
366
|
)
|
|
568
367
|
end
|
|
569
368
|
|
|
570
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
|
571
369
|
def previous_version(dependency)
|
|
572
370
|
# If we don't have a previous version, we *may* still be able to figure
|
|
573
371
|
# one out if a ref was provided and has been changed (in which case the
|
|
@@ -590,7 +388,6 @@ module Dependabot
|
|
|
590
388
|
dependency.previous_version
|
|
591
389
|
end
|
|
592
390
|
end
|
|
593
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
|
594
391
|
|
|
595
392
|
def new_version(dependency)
|
|
596
393
|
if dependency.version.match?(/^[0-9a-f]{40}$/)
|
|
@@ -658,48 +455,6 @@ module Dependabot
|
|
|
658
455
|
raise "No new requirement!"
|
|
659
456
|
end
|
|
660
457
|
|
|
661
|
-
def link_issues(text:, dependency:)
|
|
662
|
-
IssueLinker.
|
|
663
|
-
new(source_url: source_url(dependency)).
|
|
664
|
-
link_issues(text: text)
|
|
665
|
-
end
|
|
666
|
-
|
|
667
|
-
def fix_relative_links(text:, base_url:)
|
|
668
|
-
text.gsub(/\[.*?\]\([^)]+\)/) do |link|
|
|
669
|
-
next link if link.include?("://")
|
|
670
|
-
|
|
671
|
-
relative_path = link.match(/\((.*?)\)/).captures.last
|
|
672
|
-
base = base_url.split("://").last.gsub(%r{[^/]*$}, "")
|
|
673
|
-
path = File.join(base, relative_path)
|
|
674
|
-
absolute_path =
|
|
675
|
-
base_url.sub(
|
|
676
|
-
%r{(?<=://).*$},
|
|
677
|
-
Pathname.new(path).cleanpath.to_s
|
|
678
|
-
)
|
|
679
|
-
link.gsub(relative_path, absolute_path)
|
|
680
|
-
end
|
|
681
|
-
end
|
|
682
|
-
|
|
683
|
-
def sanitize_links_and_mentions(text, unsafe: false)
|
|
684
|
-
return text unless source.provider == "github"
|
|
685
|
-
|
|
686
|
-
LinkAndMentionSanitizer.
|
|
687
|
-
new(github_redirection_service: github_redirection_service).
|
|
688
|
-
sanitize_links_and_mentions(text: text, unsafe: unsafe)
|
|
689
|
-
end
|
|
690
|
-
|
|
691
|
-
def sanitize_template_tags(text)
|
|
692
|
-
text.gsub(/\<.*?\>/) do |tag|
|
|
693
|
-
tag_contents = tag.match(/\<(.*?)\>/).captures.first.strip
|
|
694
|
-
|
|
695
|
-
# Unclosed calls to template overflow out of the blockquote block,
|
|
696
|
-
# wrecking the rest of our PRs. Other tags don't share this problem.
|
|
697
|
-
next "\\#{tag}" if tag_contents.start_with?("template")
|
|
698
|
-
|
|
699
|
-
tag
|
|
700
|
-
end
|
|
701
|
-
end
|
|
702
|
-
|
|
703
458
|
def ref_changed?(dependency)
|
|
704
459
|
previous_ref(dependency) != new_ref(dependency)
|
|
705
460
|
end
|
|
@@ -58,7 +58,6 @@ module Dependabot
|
|
|
58
58
|
end
|
|
59
59
|
end
|
|
60
60
|
|
|
61
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
|
62
61
|
def sanitize_links(doc)
|
|
63
62
|
doc.walk do |node|
|
|
64
63
|
if node.type == :link && node.url.match?(GITHUB_REF_REGEX)
|
|
@@ -81,7 +80,6 @@ module Dependabot
|
|
|
81
80
|
end
|
|
82
81
|
end
|
|
83
82
|
end
|
|
84
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
|
85
83
|
|
|
86
84
|
def replace_github_host(text)
|
|
87
85
|
text.gsub(
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "dependabot/pull_request_creator/message_builder"
|
|
4
|
+
|
|
5
|
+
module Dependabot
|
|
6
|
+
class PullRequestCreator
|
|
7
|
+
class MessageBuilder
|
|
8
|
+
class MetadataPresenter
|
|
9
|
+
extend Forwardable
|
|
10
|
+
|
|
11
|
+
attr_reader :dependency, :source, :metadata_finder,
|
|
12
|
+
:vulnerabilities_fixed, :github_redirection_service
|
|
13
|
+
|
|
14
|
+
def_delegators :metadata_finder,
|
|
15
|
+
:changelog_url,
|
|
16
|
+
:changelog_text,
|
|
17
|
+
:commits_url,
|
|
18
|
+
:commits,
|
|
19
|
+
:maintainer_changes,
|
|
20
|
+
:releases_url,
|
|
21
|
+
:releases_text,
|
|
22
|
+
:source_url,
|
|
23
|
+
:upgrade_guide_url,
|
|
24
|
+
:upgrade_guide_text
|
|
25
|
+
|
|
26
|
+
def initialize(dependency:, source:, metadata_finder:,
|
|
27
|
+
vulnerabilities_fixed:, github_redirection_service:)
|
|
28
|
+
@dependency = dependency
|
|
29
|
+
@source = source
|
|
30
|
+
@metadata_finder = metadata_finder
|
|
31
|
+
@vulnerabilities_fixed = vulnerabilities_fixed
|
|
32
|
+
@github_redirection_service = github_redirection_service
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def to_s
|
|
36
|
+
msg = ""
|
|
37
|
+
msg += vulnerabilities_cascade
|
|
38
|
+
msg += release_cascade
|
|
39
|
+
msg += changelog_cascade
|
|
40
|
+
msg += upgrade_guide_cascade
|
|
41
|
+
msg += commits_cascade
|
|
42
|
+
msg += maintainer_changes_cascade
|
|
43
|
+
msg += break_tag unless msg == ""
|
|
44
|
+
"\n" + sanitize_links_and_mentions(msg, unsafe: true)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
def vulnerabilities_cascade
|
|
50
|
+
return "" unless vulnerabilities_fixed&.any?
|
|
51
|
+
|
|
52
|
+
msg = ""
|
|
53
|
+
vulnerabilities_fixed.each do |v|
|
|
54
|
+
msg += serialized_vulnerability_details(v)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
msg = sanitize_template_tags(msg)
|
|
58
|
+
msg = sanitize_links_and_mentions(msg)
|
|
59
|
+
|
|
60
|
+
build_details_tag(summary: "Vulnerabilities fixed", body: msg)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def release_cascade
|
|
64
|
+
return "" unless releases_text && releases_url
|
|
65
|
+
|
|
66
|
+
msg = "*Sourced from [#{dependency.display_name}'s releases]"\
|
|
67
|
+
"(#{releases_url}).*\n\n"
|
|
68
|
+
msg += quote_and_truncate(releases_text)
|
|
69
|
+
msg = link_issues(text: msg)
|
|
70
|
+
msg = fix_relative_links(
|
|
71
|
+
text: msg,
|
|
72
|
+
base_url: source_url + "/blob/HEAD/"
|
|
73
|
+
)
|
|
74
|
+
msg = sanitize_template_tags(msg)
|
|
75
|
+
msg = sanitize_links_and_mentions(msg)
|
|
76
|
+
|
|
77
|
+
build_details_tag(summary: "Release notes", body: msg)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def changelog_cascade
|
|
81
|
+
return "" unless changelog_url && changelog_text
|
|
82
|
+
|
|
83
|
+
msg = "*Sourced from "\
|
|
84
|
+
"[#{dependency.display_name}'s changelog]"\
|
|
85
|
+
"(#{changelog_url}).*\n\n"
|
|
86
|
+
msg += quote_and_truncate(changelog_text)
|
|
87
|
+
msg = link_issues(text: msg)
|
|
88
|
+
msg = fix_relative_links(text: msg, base_url: changelog_url)
|
|
89
|
+
msg = sanitize_template_tags(msg)
|
|
90
|
+
msg = sanitize_links_and_mentions(msg)
|
|
91
|
+
|
|
92
|
+
build_details_tag(summary: "Changelog", body: msg)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def upgrade_guide_cascade
|
|
96
|
+
return "" unless upgrade_guide_url && upgrade_guide_text
|
|
97
|
+
|
|
98
|
+
msg = "*Sourced from "\
|
|
99
|
+
"[#{dependency.display_name}'s upgrade guide]"\
|
|
100
|
+
"(#{upgrade_guide_url}).*\n\n"
|
|
101
|
+
msg += quote_and_truncate(upgrade_guide_text)
|
|
102
|
+
msg = link_issues(text: msg)
|
|
103
|
+
msg = fix_relative_links(text: msg, base_url: upgrade_guide_url)
|
|
104
|
+
msg = sanitize_template_tags(msg)
|
|
105
|
+
msg = sanitize_links_and_mentions(msg)
|
|
106
|
+
|
|
107
|
+
build_details_tag(summary: "Upgrade guide", body: msg)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def commits_cascade
|
|
111
|
+
return "" unless commits_url && commits
|
|
112
|
+
|
|
113
|
+
msg = ""
|
|
114
|
+
|
|
115
|
+
commits.reverse.first(10).each do |commit|
|
|
116
|
+
title = commit[:message].strip.split("\n").first
|
|
117
|
+
title = title.slice(0..76) + "..." if title && title.length > 80
|
|
118
|
+
title = title&.gsub(/(?<=[^\w.-])([_*`~])/, '\\1')
|
|
119
|
+
sha = commit[:sha][0, 7]
|
|
120
|
+
msg += "- [`#{sha}`](#{commit[:html_url]}) #{title}\n"
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
msg = msg.gsub(/\<.*?\>/) { |tag| "\\#{tag}" }
|
|
124
|
+
|
|
125
|
+
msg +=
|
|
126
|
+
if commits.count > 10
|
|
127
|
+
"- Additional commits viewable in "\
|
|
128
|
+
"[compare view](#{commits_url})\n"
|
|
129
|
+
else
|
|
130
|
+
"- See full diff in [compare view](#{commits_url})\n"
|
|
131
|
+
end
|
|
132
|
+
msg = link_issues(text: msg)
|
|
133
|
+
msg = sanitize_links_and_mentions(msg)
|
|
134
|
+
|
|
135
|
+
build_details_tag(summary: "Commits", body: msg)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def maintainer_changes_cascade
|
|
139
|
+
return "" unless maintainer_changes
|
|
140
|
+
|
|
141
|
+
build_details_tag(
|
|
142
|
+
summary: "Maintainer changes",
|
|
143
|
+
body: sanitize_links_and_mentions(maintainer_changes) + "\n"
|
|
144
|
+
)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def build_details_tag(summary:, body:)
|
|
148
|
+
# Azure DevOps does not support <details> tag (https://developercommunity.visualstudio.com/content/problem/608769/add-support-for-in-markdown.html)
|
|
149
|
+
# CodeCommit does not support the <details> tag (no url available)
|
|
150
|
+
if source_provider_supports_html?
|
|
151
|
+
msg = "<details>\n<summary>#{summary}</summary>\n\n"
|
|
152
|
+
msg += body
|
|
153
|
+
msg + "</details>\n"
|
|
154
|
+
else
|
|
155
|
+
"\n\##{summary}\n\n#{body}"
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def serialized_vulnerability_details(details)
|
|
160
|
+
msg = vulnerability_source_line(details)
|
|
161
|
+
|
|
162
|
+
if details["title"]
|
|
163
|
+
msg += "> **#{details['title'].lines.map(&:strip).join(' ')}**\n"
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
if (description = details["description"])
|
|
167
|
+
description.strip.lines.first(20).each { |line| msg += "> #{line}" }
|
|
168
|
+
msg += truncated_line if description.strip.lines.count > 20
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
msg += "\n" unless msg.end_with?("\n")
|
|
172
|
+
msg += "> \n"
|
|
173
|
+
msg += vulnerability_version_range_lines(details)
|
|
174
|
+
msg + "\n"
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def vulnerability_source_line(details)
|
|
178
|
+
if details["source_url"] && details["source_name"]
|
|
179
|
+
"*Sourced from [#{details['source_name']}]"\
|
|
180
|
+
"(#{details['source_url']}).*\n\n"
|
|
181
|
+
elsif details["source_name"]
|
|
182
|
+
"*Sourced from #{details['source_name']}.*\n\n"
|
|
183
|
+
else
|
|
184
|
+
""
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def vulnerability_version_range_lines(details)
|
|
189
|
+
msg = ""
|
|
190
|
+
%w(
|
|
191
|
+
patched_versions
|
|
192
|
+
unaffected_versions
|
|
193
|
+
affected_versions
|
|
194
|
+
).each do |tp|
|
|
195
|
+
type = tp.split("_").first.capitalize
|
|
196
|
+
next unless details[tp]
|
|
197
|
+
|
|
198
|
+
versions_string = details[tp].any? ? details[tp].join("; ") : "none"
|
|
199
|
+
versions_string = versions_string.gsub(/(?<!\\)~/, '\~')
|
|
200
|
+
msg += "> #{type} versions: #{versions_string}\n"
|
|
201
|
+
end
|
|
202
|
+
msg
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def link_issues(text:)
|
|
206
|
+
IssueLinker.
|
|
207
|
+
new(source_url: source_url).
|
|
208
|
+
link_issues(text: text)
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def fix_relative_links(text:, base_url:)
|
|
212
|
+
text.gsub(/\[.*?\]\([^)]+\)/) do |link|
|
|
213
|
+
next link if link.include?("://")
|
|
214
|
+
|
|
215
|
+
relative_path = link.match(/\((.*?)\)/).captures.last
|
|
216
|
+
base = base_url.split("://").last.gsub(%r{[^/]*$}, "")
|
|
217
|
+
path = File.join(base, relative_path)
|
|
218
|
+
absolute_path =
|
|
219
|
+
base_url.sub(
|
|
220
|
+
%r{(?<=://).*$},
|
|
221
|
+
Pathname.new(path).cleanpath.to_s
|
|
222
|
+
)
|
|
223
|
+
link.gsub(relative_path, absolute_path)
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def quote_and_truncate(text, limit: 50)
|
|
228
|
+
lines = text.split("\n")
|
|
229
|
+
lines.first(limit).tap do |limited_lines|
|
|
230
|
+
limited_lines.map! { |line| "> #{line}\n" }
|
|
231
|
+
limited_lines << truncated_line if lines.count > limit
|
|
232
|
+
end.join
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
def truncated_line
|
|
236
|
+
# Tables can spill out of truncated details, so we close them
|
|
237
|
+
"></tr></table> \n ... (truncated)\n"
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def break_tag
|
|
241
|
+
source_provider_supports_html? ? "\n<br />" : "\n\n"
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def source_provider_supports_html?
|
|
245
|
+
!%w(azure codecommit).include?(source.provider)
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def sanitize_links_and_mentions(text, unsafe: false)
|
|
249
|
+
return text unless source.provider == "github"
|
|
250
|
+
|
|
251
|
+
LinkAndMentionSanitizer.
|
|
252
|
+
new(github_redirection_service: github_redirection_service).
|
|
253
|
+
sanitize_links_and_mentions(text: text, unsafe: unsafe)
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
def sanitize_template_tags(text)
|
|
257
|
+
text.gsub(/\<.*?\>/) do |tag|
|
|
258
|
+
tag_contents = tag.match(/\<(.*?)\>/).captures.first.strip
|
|
259
|
+
|
|
260
|
+
# Unclosed calls to template overflow out of the blockquote block,
|
|
261
|
+
# wrecking the rest of our PRs. Other tags don't share this problem.
|
|
262
|
+
next "\\#{tag}" if tag_contents.start_with?("template")
|
|
263
|
+
|
|
264
|
+
tag
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
end
|
|
@@ -172,6 +172,7 @@ module Dependabot
|
|
|
172
172
|
last_dependabot_commit_message&.split(/[:(]/)&.first
|
|
173
173
|
end
|
|
174
174
|
|
|
175
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
|
175
176
|
def using_angular_commit_messages?
|
|
176
177
|
return false if recent_commit_messages.none?
|
|
177
178
|
|
|
@@ -202,6 +203,7 @@ module Dependabot
|
|
|
202
203
|
|
|
203
204
|
true
|
|
204
205
|
end
|
|
206
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
|
205
207
|
|
|
206
208
|
def using_eslint_commit_messages?
|
|
207
209
|
return false if recent_commit_messages.none?
|
|
@@ -178,6 +178,7 @@ module Dependabot
|
|
|
178
178
|
)
|
|
179
179
|
end
|
|
180
180
|
|
|
181
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
|
181
182
|
def self.configure_git_credentials(credentials)
|
|
182
183
|
# Then add a file-based credential store that loads a file in this repo.
|
|
183
184
|
# Under the hood this uses git credential-store, but it's invoked through
|
|
@@ -221,6 +222,7 @@ module Dependabot
|
|
|
221
222
|
# Save the file
|
|
222
223
|
File.write("git.store", git_store_content)
|
|
223
224
|
end
|
|
225
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
|
224
226
|
|
|
225
227
|
def self.reset_git_repo(path)
|
|
226
228
|
Dir.chdir(path) do
|
data/lib/dependabot/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dependabot-common
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.120.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dependabot
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-09-
|
|
11
|
+
date: 2020-09-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: aws-sdk-codecommit
|
|
@@ -292,14 +292,14 @@ dependencies:
|
|
|
292
292
|
requirements:
|
|
293
293
|
- - "~>"
|
|
294
294
|
- !ruby/object:Gem::Version
|
|
295
|
-
version: 0.
|
|
295
|
+
version: 0.91.0
|
|
296
296
|
type: :development
|
|
297
297
|
prerelease: false
|
|
298
298
|
version_requirements: !ruby/object:Gem::Requirement
|
|
299
299
|
requirements:
|
|
300
300
|
- - "~>"
|
|
301
301
|
- !ruby/object:Gem::Version
|
|
302
|
-
version: 0.
|
|
302
|
+
version: 0.91.0
|
|
303
303
|
- !ruby/object:Gem::Dependency
|
|
304
304
|
name: vcr
|
|
305
305
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -376,6 +376,7 @@ files:
|
|
|
376
376
|
- lib/dependabot/pull_request_creator/message_builder.rb
|
|
377
377
|
- lib/dependabot/pull_request_creator/message_builder/issue_linker.rb
|
|
378
378
|
- lib/dependabot/pull_request_creator/message_builder/link_and_mention_sanitizer.rb
|
|
379
|
+
- lib/dependabot/pull_request_creator/message_builder/metadata_presenter.rb
|
|
379
380
|
- lib/dependabot/pull_request_creator/pr_name_prefixer.rb
|
|
380
381
|
- lib/dependabot/pull_request_updater.rb
|
|
381
382
|
- lib/dependabot/pull_request_updater/github.rb
|