dependabot-common 0.391.0 → 0.392.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/command_helpers.rb +10 -2
- data/lib/dependabot/dependency_requirement.rb +28 -15
- data/lib/dependabot/errors.rb +7 -0
- data/lib/dependabot/pull_request_creator/branch_name_template.rb +1 -1
- data/lib/dependabot/pull_request_creator/message_builder/issue_linker.rb +21 -2
- data/lib/dependabot/pull_request_creator/message_builder/link_and_mention_sanitizer.rb +53 -13
- data/lib/dependabot/pull_request_creator/message_builder/metadata_presenter.rb +20 -13
- data/lib/dependabot/shared_helpers.rb +30 -7
- data/lib/dependabot/workspace/git.rb +2 -2
- data/lib/dependabot.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6a574e02b5e7a33f7f245c56ae3df5942505a73cee3c1f32b8a07c1b36ba13a2
|
|
4
|
+
data.tar.gz: 4ee0767b57e78681464704b7e41557692d57cf240f40f2577d0313a87f78d371
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b63a271847067f6adf096dcbbd9e97e0e986defc09125f55afa8be96cb820660c76551982b46d7c613e29ff93093d87bb1c1849d99c6e7bd75fab3f9abcc3a28
|
|
7
|
+
data.tar.gz: 28753fa5c276536d7cb8e16cc7bf183796bdd968e31c0efcb92ded66fd8b07a6e05304d0da3eba70a64fc1bd990f9167a073a072791655bdeb47cfb2f8c01d14
|
|
@@ -26,6 +26,7 @@ module Dependabot
|
|
|
26
26
|
EnvCmdItem = T.type_alias do
|
|
27
27
|
T.any(
|
|
28
28
|
String,
|
|
29
|
+
T::Array[String],
|
|
29
30
|
T::Hash[T.any(String, Symbol), T.anything]
|
|
30
31
|
)
|
|
31
32
|
end
|
|
@@ -109,7 +110,7 @@ module Dependabot
|
|
|
109
110
|
else
|
|
110
111
|
env_cmd
|
|
111
112
|
end
|
|
112
|
-
command_for_log = sanitized_env_cmd.join(" ")
|
|
113
|
+
command_for_log = sanitized_env_cmd.map { |item| item.is_a?(Array) ? item.first : item }.join(" ")
|
|
113
114
|
Dependabot.logger.public_send(log_level, "Started process PID: #{pid} with command: #{command_for_log}")
|
|
114
115
|
|
|
115
116
|
# Write to stdin if input data is provided
|
|
@@ -263,7 +264,14 @@ module Dependabot
|
|
|
263
264
|
|
|
264
265
|
sig { params(env_cmd: T::Array[EnvCmdItem]).returns(T.nilable(String)) }
|
|
265
266
|
def self.command_string_for_logging(env_cmd)
|
|
266
|
-
|
|
267
|
+
command_parts = env_cmd.filter_map do |item|
|
|
268
|
+
case item
|
|
269
|
+
when Array then item.first
|
|
270
|
+
when String then item
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
command_parts.join(" ") unless command_parts.empty?
|
|
267
275
|
end
|
|
268
276
|
private_class_method :command_string_for_logging
|
|
269
277
|
|
|
@@ -16,7 +16,7 @@ module Dependabot
|
|
|
16
16
|
#
|
|
17
17
|
# Subclasses Hash so it is a drop-in replacement at call sites (and in
|
|
18
18
|
# type annotations) that treat requirement entries as
|
|
19
|
-
# T::Hash[Symbol,
|
|
19
|
+
# T::Hash[Symbol, Object], while exposing typed readers for the
|
|
20
20
|
# well-known keys. New code should prefer the typed readers; hash-style
|
|
21
21
|
# access remains supported while call sites are migrated gradually.
|
|
22
22
|
#
|
|
@@ -37,15 +37,11 @@ module Dependabot
|
|
|
37
37
|
ObjectHash = T.type_alias { T::Hash[T.any(Symbol, String), Object] }
|
|
38
38
|
Requirement = T.type_alias { T.any(String, Symbol) }
|
|
39
39
|
Source = T.type_alias { T.any(String, ObjectHash) }
|
|
40
|
-
Input = T.type_alias { T.any(
|
|
40
|
+
Input = T.type_alias { T::Hash[T.any(Symbol, String), T.anything] }
|
|
41
41
|
|
|
42
42
|
K = type_member { { fixed: Symbol } }
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
# rubocop:disable Sorbet/ForbidTUntyped
|
|
46
|
-
V = type_member { { fixed: T.untyped } }
|
|
47
|
-
Elem = type_member { { fixed: [Symbol, T.untyped] } }
|
|
48
|
-
# rubocop:enable Sorbet/ForbidTUntyped
|
|
43
|
+
V = type_member { { fixed: Object } }
|
|
44
|
+
Elem = type_member { { fixed: [Symbol, Object] } }
|
|
49
45
|
|
|
50
46
|
# Builds a DependencyRequirement from a requirement hash, symbolising
|
|
51
47
|
# top-level keys. Accepts both plain hashes and existing
|
|
@@ -53,7 +49,12 @@ module Dependabot
|
|
|
53
49
|
sig { params(hash: Input).returns(DependencyRequirement) }
|
|
54
50
|
def self.create(hash)
|
|
55
51
|
requirement = new
|
|
56
|
-
|
|
52
|
+
hash.each do |key, value|
|
|
53
|
+
case value
|
|
54
|
+
when Object then requirement[key.to_sym] = value
|
|
55
|
+
else raise TypeError, "requirement values must inherit Object"
|
|
56
|
+
end
|
|
57
|
+
end
|
|
57
58
|
requirement
|
|
58
59
|
end
|
|
59
60
|
|
|
@@ -62,7 +63,7 @@ module Dependabot
|
|
|
62
63
|
# or :unfixable when no valid updated requirement can be generated.
|
|
63
64
|
sig { returns(T.nilable(Requirement)) }
|
|
64
65
|
def requirement
|
|
65
|
-
value =
|
|
66
|
+
value = self[:requirement]
|
|
66
67
|
return if value.nil?
|
|
67
68
|
return value if value.is_a?(String) || value == :unfixable
|
|
68
69
|
|
|
@@ -82,7 +83,7 @@ module Dependabot
|
|
|
82
83
|
# the underlying hash access under sorbet-runtime.
|
|
83
84
|
sig { returns(T.nilable(T::Array[Group])) }
|
|
84
85
|
def groups
|
|
85
|
-
value =
|
|
86
|
+
value = self[:groups]
|
|
86
87
|
return if value.nil?
|
|
87
88
|
raise TypeError, "groups must be an array of strings or symbols, or nil" unless value.is_a?(Array)
|
|
88
89
|
|
|
@@ -101,7 +102,7 @@ module Dependabot
|
|
|
101
102
|
# parser or deserialised from a job definition.
|
|
102
103
|
sig { returns(T.nilable(Source)) }
|
|
103
104
|
def source
|
|
104
|
-
value =
|
|
105
|
+
value = self[:source]
|
|
105
106
|
return if value.nil?
|
|
106
107
|
return value if value.is_a?(String)
|
|
107
108
|
|
|
@@ -175,6 +176,16 @@ module Dependabot
|
|
|
175
176
|
raise TypeError, "metadata #{key} must be a symbol or nil"
|
|
176
177
|
end
|
|
177
178
|
|
|
179
|
+
# Reads a boolean metadata field such as "include_debug_script".
|
|
180
|
+
sig { params(key: String).returns(T.nilable(T::Boolean)) }
|
|
181
|
+
def metadata_boolean(key)
|
|
182
|
+
value = metadata_value(key)
|
|
183
|
+
return if value.nil?
|
|
184
|
+
return value if value == true || value == false
|
|
185
|
+
|
|
186
|
+
raise TypeError, "metadata #{key} must be a boolean or nil"
|
|
187
|
+
end
|
|
188
|
+
|
|
178
189
|
# Reads a nested metadata hash whose values are all strings, such as
|
|
179
190
|
# "dependency_set" (`{ group: "my.group", version: "1.4.0" }`). Keys are
|
|
180
191
|
# symbolised so callers can read them with symbols regardless of how the
|
|
@@ -205,12 +216,14 @@ module Dependabot
|
|
|
205
216
|
details = metadata
|
|
206
217
|
return if details.nil?
|
|
207
218
|
|
|
208
|
-
details[key.to_sym]
|
|
219
|
+
return details[key.to_sym] if details.key?(key.to_sym)
|
|
220
|
+
|
|
221
|
+
details[key]
|
|
209
222
|
end
|
|
210
223
|
|
|
211
224
|
sig { params(key: Symbol).returns(T.nilable(String)) }
|
|
212
225
|
def optional_string(key)
|
|
213
|
-
value =
|
|
226
|
+
value = self[key]
|
|
214
227
|
return if value.nil?
|
|
215
228
|
return value if value.is_a?(String)
|
|
216
229
|
|
|
@@ -219,7 +232,7 @@ module Dependabot
|
|
|
219
232
|
|
|
220
233
|
sig { params(key: Symbol).returns(T.nilable(ObjectHash)) }
|
|
221
234
|
def optional_object_hash(key)
|
|
222
|
-
value =
|
|
235
|
+
value = self[key]
|
|
223
236
|
return if value.nil?
|
|
224
237
|
|
|
225
238
|
object_hash(value, key)
|
data/lib/dependabot/errors.rb
CHANGED
|
@@ -246,6 +246,11 @@ module Dependabot
|
|
|
246
246
|
"error-type": "dependency_file_not_resolvable",
|
|
247
247
|
"error-detail": { message: error.message }
|
|
248
248
|
}
|
|
249
|
+
when Dependabot::BranchNameFormattingError
|
|
250
|
+
{
|
|
251
|
+
"error-type": "branch_name_formatting_error",
|
|
252
|
+
"error-detail": { message: error.message }
|
|
253
|
+
}
|
|
249
254
|
when Dependabot::BlockedDependencyVersion
|
|
250
255
|
{
|
|
251
256
|
"error-type": "blocked_dependency_version",
|
|
@@ -509,6 +514,8 @@ module Dependabot
|
|
|
509
514
|
|
|
510
515
|
class RefNamespaceConflictError < DependabotError; end
|
|
511
516
|
|
|
517
|
+
class BranchNameFormattingError < DependabotError; end
|
|
518
|
+
|
|
512
519
|
#####################
|
|
513
520
|
# Repo level errors #
|
|
514
521
|
#####################
|
|
@@ -11,7 +11,7 @@ module Dependabot
|
|
|
11
11
|
class BranchNameTemplate
|
|
12
12
|
extend T::Sig
|
|
13
13
|
|
|
14
|
-
class Error < Dependabot::
|
|
14
|
+
class Error < Dependabot::BranchNameFormattingError; end
|
|
15
15
|
|
|
16
16
|
SOLO_PLACEHOLDERS = %w(prefix package_manager directory target_branch dependency version name).freeze
|
|
17
17
|
GROUP_PLACEHOLDERS = %w(prefix package_manager directory target_branch group_name name).freeze
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
require "sorbet-runtime"
|
|
5
|
+
require "uri"
|
|
5
6
|
require "dependabot/pull_request_creator/message_builder"
|
|
6
7
|
|
|
7
8
|
module Dependabot
|
|
@@ -53,19 +54,37 @@ module Dependabot
|
|
|
53
54
|
&.fetch("repo", nil)
|
|
54
55
|
|
|
55
56
|
source = if repo
|
|
56
|
-
"
|
|
57
|
+
"#{qualified_reference_base_url}/#{repo}"
|
|
57
58
|
elsif source_url
|
|
58
59
|
source_url
|
|
59
60
|
end
|
|
60
61
|
|
|
61
62
|
if source
|
|
62
|
-
"[#{repo ? (repo + tag) : tag}](#{source}
|
|
63
|
+
"[#{repo ? (repo + tag) : tag}](#{source}#{issue_path(source)}/#{number})"
|
|
63
64
|
else
|
|
64
65
|
issue_link
|
|
65
66
|
end
|
|
66
67
|
end
|
|
67
68
|
end
|
|
68
69
|
end
|
|
70
|
+
|
|
71
|
+
private
|
|
72
|
+
|
|
73
|
+
sig { params(source: String).returns(String) }
|
|
74
|
+
def issue_path(source)
|
|
75
|
+
URI.parse(source).host&.downcase == "gitlab.com" ? "/-/work_items" : "/issues"
|
|
76
|
+
rescue URI::InvalidURIError
|
|
77
|
+
"/issues"
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
sig { returns(String) }
|
|
81
|
+
def qualified_reference_base_url
|
|
82
|
+
return "https://github.com" unless source_url
|
|
83
|
+
|
|
84
|
+
URI.parse(T.must(source_url)).host&.downcase == "gitlab.com" ? "https://gitlab.com" : "https://github.com"
|
|
85
|
+
rescue URI::InvalidURIError
|
|
86
|
+
"https://github.com"
|
|
87
|
+
end
|
|
69
88
|
end
|
|
70
89
|
end
|
|
71
90
|
end
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
require "commonmarker"
|
|
5
5
|
require "sorbet-runtime"
|
|
6
6
|
require "strscan"
|
|
7
|
+
require "uri"
|
|
7
8
|
require "dependabot/pull_request_creator/message_builder"
|
|
8
9
|
|
|
9
10
|
module Dependabot
|
|
@@ -13,6 +14,9 @@ module Dependabot
|
|
|
13
14
|
extend T::Sig
|
|
14
15
|
|
|
15
16
|
GITHUB_USERNAME = /[a-z0-9]+(-[a-z0-9]+)*/i
|
|
17
|
+
GITLAB_USERNAME = /[a-z0-9](?:[a-z0-9_.-]*[a-z0-9_-])?/i
|
|
18
|
+
GITHUB_HOST = "github.com"
|
|
19
|
+
GITLAB_HOST = "gitlab.com"
|
|
16
20
|
GITHUB_REF_REGEX = %r{
|
|
17
21
|
(?:https?://)?
|
|
18
22
|
github\.com/(?<repo>#{GITHUB_USERNAME}/[^/\s]+)/
|
|
@@ -20,9 +24,6 @@ module Dependabot
|
|
|
20
24
|
}x
|
|
21
25
|
# [^/\s#]+ means one or more characters not matching (^) the class /, whitespace (\s), or #
|
|
22
26
|
GITHUB_NWO_REGEX = %r{(?<repo>#{GITHUB_USERNAME}/[^/\s#]+)#(?<number>\d+)}
|
|
23
|
-
MENTION_REGEX = %r{(?<![A-Za-z0-9`~])@#{GITHUB_USERNAME}/?}
|
|
24
|
-
# regex to match a team mention on github
|
|
25
|
-
TEAM_MENTION_REGEX = %r{(?<![A-Za-z0-9`~])@(?<org>#{GITHUB_USERNAME})/(?<team>#{GITHUB_USERNAME})/?}
|
|
26
27
|
# End of string
|
|
27
28
|
EOS_REGEX = /\z/
|
|
28
29
|
|
|
@@ -49,9 +50,18 @@ module Dependabot
|
|
|
49
50
|
sig { returns(T.nilable(String)) }
|
|
50
51
|
attr_reader :github_redirection_service
|
|
51
52
|
|
|
52
|
-
sig {
|
|
53
|
-
|
|
53
|
+
sig { returns(T.nilable(String)) }
|
|
54
|
+
attr_reader :metadata_source_url
|
|
55
|
+
|
|
56
|
+
sig do
|
|
57
|
+
params(
|
|
58
|
+
github_redirection_service: T.nilable(String),
|
|
59
|
+
metadata_source_url: T.nilable(String)
|
|
60
|
+
).void
|
|
61
|
+
end
|
|
62
|
+
def initialize(github_redirection_service:, metadata_source_url: nil)
|
|
54
63
|
@github_redirection_service = github_redirection_service
|
|
64
|
+
@metadata_source_url = metadata_source_url
|
|
55
65
|
end
|
|
56
66
|
|
|
57
67
|
sig { params(text: String, unsafe: T::Boolean, format_html: T::Boolean).returns(String) }
|
|
@@ -90,7 +100,7 @@ module Dependabot
|
|
|
90
100
|
def sanitize_mentions(doc)
|
|
91
101
|
doc.walk do |node|
|
|
92
102
|
if node.type == :text &&
|
|
93
|
-
node.string_content.match?(
|
|
103
|
+
node.string_content.match?(mention_regex)
|
|
94
104
|
nodes = if parent_node_link?(node)
|
|
95
105
|
build_mention_link_text_nodes(node.string_content)
|
|
96
106
|
else
|
|
@@ -111,10 +121,10 @@ module Dependabot
|
|
|
111
121
|
def sanitize_team_mentions(doc)
|
|
112
122
|
doc.walk do |node|
|
|
113
123
|
if node.type == :text &&
|
|
114
|
-
node.string_content.match?(
|
|
124
|
+
node.string_content.match?(team_mention_regex)
|
|
115
125
|
if parent_node_link?(node)
|
|
116
126
|
# Preserve text node formatting while preventing notifications with zero-width space
|
|
117
|
-
node.string_content = node.string_content.gsub(
|
|
127
|
+
node.string_content = node.string_content.gsub(team_mention_regex) do |match|
|
|
118
128
|
insert_zero_width_space_in_mention(match)
|
|
119
129
|
end
|
|
120
130
|
else
|
|
@@ -189,9 +199,9 @@ module Dependabot
|
|
|
189
199
|
scan = StringScanner.new(text)
|
|
190
200
|
|
|
191
201
|
until scan.eos?
|
|
192
|
-
line = scan.scan_until(
|
|
202
|
+
line = scan.scan_until(mention_regex) ||
|
|
193
203
|
scan.scan_until(EOS_REGEX)
|
|
194
|
-
line_match = T.must(line).match(
|
|
204
|
+
line_match = T.must(line).match(mention_regex)
|
|
195
205
|
mention = line_match&.to_s
|
|
196
206
|
text_node = Commonmarker::Node.new(:text)
|
|
197
207
|
|
|
@@ -199,7 +209,7 @@ module Dependabot
|
|
|
199
209
|
text_node.string_content = line_match.pre_match
|
|
200
210
|
nodes << text_node
|
|
201
211
|
nodes << create_link_node(
|
|
202
|
-
"
|
|
212
|
+
"#{mention_profile_base_url}/#{mention.delete_prefix('@')}", mention.to_s
|
|
203
213
|
)
|
|
204
214
|
else
|
|
205
215
|
text_node.string_content = line
|
|
@@ -216,9 +226,9 @@ module Dependabot
|
|
|
216
226
|
|
|
217
227
|
scan = StringScanner.new(text)
|
|
218
228
|
until scan.eos?
|
|
219
|
-
line = scan.scan_until(
|
|
229
|
+
line = scan.scan_until(team_mention_regex) ||
|
|
220
230
|
scan.scan_until(EOS_REGEX)
|
|
221
|
-
line_match = T.must(line).match(
|
|
231
|
+
line_match = T.must(line).match(team_mention_regex)
|
|
222
232
|
mention = line_match&.to_s
|
|
223
233
|
text_node = Commonmarker::Node.new(:text)
|
|
224
234
|
|
|
@@ -235,6 +245,36 @@ module Dependabot
|
|
|
235
245
|
nodes
|
|
236
246
|
end
|
|
237
247
|
|
|
248
|
+
sig { returns(Regexp) }
|
|
249
|
+
def mention_regex
|
|
250
|
+
%r{(?<![A-Za-z0-9`~])@#{mention_username_regex}/?}
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
sig { returns(Regexp) }
|
|
254
|
+
def team_mention_regex
|
|
255
|
+
username_regex = mention_username_regex
|
|
256
|
+
%r{(?<![A-Za-z0-9`~])@(?<org>#{username_regex})/(?<team>#{username_regex})/?}
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
sig { returns(Regexp) }
|
|
260
|
+
def mention_username_regex
|
|
261
|
+
metadata_source_host == GITLAB_HOST ? GITLAB_USERNAME : GITHUB_USERNAME
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
sig { returns(String) }
|
|
265
|
+
def mention_profile_base_url
|
|
266
|
+
"https://#{metadata_source_host == GITLAB_HOST ? GITLAB_HOST : GITHUB_HOST}"
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
sig { returns(T.nilable(String)) }
|
|
270
|
+
def metadata_source_host
|
|
271
|
+
return unless metadata_source_url
|
|
272
|
+
|
|
273
|
+
URI.parse(T.must(metadata_source_url)).host&.downcase
|
|
274
|
+
rescue URI::InvalidURIError
|
|
275
|
+
nil
|
|
276
|
+
end
|
|
277
|
+
|
|
238
278
|
sig { params(text: String).returns(T::Array[Commonmarker::Node]) }
|
|
239
279
|
def build_mention_link_text_nodes(text)
|
|
240
280
|
code_node = Commonmarker::Node.new(:code)
|
|
@@ -85,13 +85,11 @@ module Dependabot
|
|
|
85
85
|
def vulnerabilities_cascade
|
|
86
86
|
return "" unless vulnerabilities_fixed&.any?
|
|
87
87
|
|
|
88
|
-
msg =
|
|
89
|
-
|
|
90
|
-
|
|
88
|
+
msg = T.must(vulnerabilities_fixed).map do |vulnerability|
|
|
89
|
+
details = sanitize_template_tags(serialized_vulnerability_details(vulnerability))
|
|
90
|
+
sanitize_links_and_mentions(details, metadata_source_url: vulnerability["source_url"])
|
|
91
91
|
end
|
|
92
|
-
|
|
93
|
-
msg = sanitize_template_tags(msg)
|
|
94
|
-
msg = sanitize_links_and_mentions(msg)
|
|
92
|
+
msg = msg.join
|
|
95
93
|
|
|
96
94
|
build_details_tag(summary: "Vulnerabilities fixed", body: msg)
|
|
97
95
|
end
|
|
@@ -109,7 +107,7 @@ module Dependabot
|
|
|
109
107
|
base_url: source_url + "/blob/HEAD/"
|
|
110
108
|
)
|
|
111
109
|
msg = sanitize_template_tags(msg)
|
|
112
|
-
msg = sanitize_links_and_mentions(msg)
|
|
110
|
+
msg = sanitize_links_and_mentions(msg, metadata_source_url: releases_url)
|
|
113
111
|
|
|
114
112
|
build_details_tag(summary: "Release notes", body: msg)
|
|
115
113
|
end
|
|
@@ -125,7 +123,7 @@ module Dependabot
|
|
|
125
123
|
msg = link_issues(text: msg)
|
|
126
124
|
msg = fix_relative_links(text: msg, base_url: changelog_url)
|
|
127
125
|
msg = sanitize_template_tags(msg)
|
|
128
|
-
msg = sanitize_links_and_mentions(msg)
|
|
126
|
+
msg = sanitize_links_and_mentions(msg, metadata_source_url: changelog_url)
|
|
129
127
|
|
|
130
128
|
build_details_tag(summary: "Changelog", body: msg)
|
|
131
129
|
end
|
|
@@ -141,7 +139,7 @@ module Dependabot
|
|
|
141
139
|
msg = link_issues(text: msg)
|
|
142
140
|
msg = fix_relative_links(text: msg, base_url: upgrade_guide_url)
|
|
143
141
|
msg = sanitize_template_tags(msg)
|
|
144
|
-
msg = sanitize_links_and_mentions(msg)
|
|
142
|
+
msg = sanitize_links_and_mentions(msg, metadata_source_url: upgrade_guide_url)
|
|
145
143
|
|
|
146
144
|
build_details_tag(summary: "Upgrade guide", body: msg)
|
|
147
145
|
end
|
|
@@ -170,7 +168,7 @@ module Dependabot
|
|
|
170
168
|
"- See full diff in [compare view](#{commits_url})\n"
|
|
171
169
|
end
|
|
172
170
|
msg = link_issues(text: msg)
|
|
173
|
-
msg = sanitize_links_and_mentions(msg)
|
|
171
|
+
msg = sanitize_links_and_mentions(msg, metadata_source_url: commits_url)
|
|
174
172
|
|
|
175
173
|
build_details_tag(summary: "Commits", body: msg)
|
|
176
174
|
end
|
|
@@ -317,10 +315,19 @@ module Dependabot
|
|
|
317
315
|
!%w(bitbucket codecommit).include?(source.provider)
|
|
318
316
|
end
|
|
319
317
|
|
|
320
|
-
sig
|
|
321
|
-
|
|
318
|
+
sig do
|
|
319
|
+
params(
|
|
320
|
+
text: String,
|
|
321
|
+
unsafe: T::Boolean,
|
|
322
|
+
metadata_source_url: T.nilable(String)
|
|
323
|
+
).returns(String)
|
|
324
|
+
end
|
|
325
|
+
def sanitize_links_and_mentions(text, unsafe: false, metadata_source_url: source_url)
|
|
322
326
|
LinkAndMentionSanitizer
|
|
323
|
-
.new(
|
|
327
|
+
.new(
|
|
328
|
+
github_redirection_service: github_redirection_service,
|
|
329
|
+
metadata_source_url: metadata_source_url
|
|
330
|
+
)
|
|
324
331
|
.sanitize_links_and_mentions(text: text, unsafe: unsafe, format_html: source_provider_supports_html?)
|
|
325
332
|
end
|
|
326
333
|
|
|
@@ -23,6 +23,8 @@ module Dependabot
|
|
|
23
23
|
module SharedHelpers # rubocop:disable Metrics/ModuleLength
|
|
24
24
|
extend T::Sig
|
|
25
25
|
|
|
26
|
+
Command = T.type_alias { T.any(String, T::Array[String]) }
|
|
27
|
+
CommandArguments = T.type_alias { T::Array[T.any(String, T::Array[String])] }
|
|
26
28
|
USER_AGENT = T.let(
|
|
27
29
|
"dependabot-core/#{Dependabot::VERSION} " \
|
|
28
30
|
"#{Excon::USER_AGENT} ruby/#{RUBY_VERSION} " \
|
|
@@ -125,6 +127,26 @@ module Dependabot
|
|
|
125
127
|
CommandHelpers.escape_command(command)
|
|
126
128
|
end
|
|
127
129
|
|
|
130
|
+
sig do
|
|
131
|
+
params(command: Command, allow_unsafe_shell_command: T::Boolean)
|
|
132
|
+
.returns([CommandArguments, String])
|
|
133
|
+
end
|
|
134
|
+
def self.prepare_command(command, allow_unsafe_shell_command:)
|
|
135
|
+
unless command.is_a?(Array)
|
|
136
|
+
prepared_command = allow_unsafe_shell_command ? command : escape_command(command)
|
|
137
|
+
return [[prepared_command], prepared_command]
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
raise ArgumentError, "command must not be empty" if command.empty?
|
|
141
|
+
if allow_unsafe_shell_command
|
|
142
|
+
raise ArgumentError, "allow_unsafe_shell_command cannot be used with an argument vector"
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
executable = T.must(command.first)
|
|
146
|
+
[[[executable, executable], *command.drop(1)], Shellwords.join(command)]
|
|
147
|
+
end
|
|
148
|
+
private_class_method :prepare_command
|
|
149
|
+
|
|
128
150
|
# rubocop:disable Metrics/MethodLength
|
|
129
151
|
# rubocop:disable Metrics/AbcSize
|
|
130
152
|
sig do
|
|
@@ -461,10 +483,9 @@ module Dependabot
|
|
|
461
483
|
safe_directories
|
|
462
484
|
end
|
|
463
485
|
|
|
464
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
|
465
486
|
sig do
|
|
466
487
|
params(
|
|
467
|
-
command:
|
|
488
|
+
command: Command,
|
|
468
489
|
allow_unsafe_shell_command: T::Boolean,
|
|
469
490
|
cwd: T.nilable(String),
|
|
470
491
|
env: T.nilable(T::Hash[String, String]),
|
|
@@ -485,14 +506,17 @@ module Dependabot
|
|
|
485
506
|
output_observer: nil
|
|
486
507
|
)
|
|
487
508
|
start = Time.now
|
|
488
|
-
|
|
509
|
+
command_args, command_for_output = prepare_command(
|
|
510
|
+
command,
|
|
511
|
+
allow_unsafe_shell_command: allow_unsafe_shell_command
|
|
512
|
+
)
|
|
489
513
|
|
|
490
|
-
puts
|
|
514
|
+
puts command_for_output if ENV["DEBUG_HELPERS"] == "true"
|
|
491
515
|
|
|
492
516
|
opts = {}
|
|
493
517
|
opts[:chdir] = cwd if cwd
|
|
494
518
|
|
|
495
|
-
env_cmd = [env || {},
|
|
519
|
+
env_cmd = [env || {}, *command_args, opts].compact
|
|
496
520
|
kwargs = {
|
|
497
521
|
stderr_to_stdout: stderr_to_stdout,
|
|
498
522
|
timeout: timeout
|
|
@@ -511,7 +535,7 @@ module Dependabot
|
|
|
511
535
|
return stdout || "" if process&.success?
|
|
512
536
|
|
|
513
537
|
error_context = {
|
|
514
|
-
command:
|
|
538
|
+
command: command_for_output,
|
|
515
539
|
fingerprint: fingerprint,
|
|
516
540
|
time_taken: time_taken,
|
|
517
541
|
process_exit_value: process.to_s
|
|
@@ -524,7 +548,6 @@ module Dependabot
|
|
|
524
548
|
error_context: error_context
|
|
525
549
|
)
|
|
526
550
|
end
|
|
527
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
|
528
551
|
|
|
529
552
|
sig { params(stderr: T.nilable(String), error_context: T::Hash[Symbol, String]).void }
|
|
530
553
|
def self.check_out_of_disk_memory_error(stderr, error_context)
|
|
@@ -127,7 +127,7 @@ module Dependabot
|
|
|
127
127
|
|
|
128
128
|
sig { params(memo: T.nilable(String)).returns(String) }
|
|
129
129
|
def commit(memo = nil)
|
|
130
|
-
run_shell_command("git add
|
|
130
|
+
run_shell_command(["git", "add", "--", path.to_s])
|
|
131
131
|
|
|
132
132
|
msg = memo || "workspace change"
|
|
133
133
|
run_shell_command(
|
|
@@ -152,7 +152,7 @@ module Dependabot
|
|
|
152
152
|
run_shell_command("git clean -fx .")
|
|
153
153
|
end
|
|
154
154
|
|
|
155
|
-
sig { params(args:
|
|
155
|
+
sig { params(args: SharedHelpers::Command, kwargs: T.any(T::Boolean, String)).returns(String) }
|
|
156
156
|
def run_shell_command(*args, **kwargs)
|
|
157
157
|
Dir.chdir(path) { T.unsafe(SharedHelpers).run_shell_command(*args, **kwargs) }
|
|
158
158
|
end
|
data/lib/dependabot.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dependabot-common
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.392.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dependabot
|
|
@@ -625,7 +625,7 @@ licenses:
|
|
|
625
625
|
- MIT
|
|
626
626
|
metadata:
|
|
627
627
|
bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
|
|
628
|
-
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.
|
|
628
|
+
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.392.0
|
|
629
629
|
rdoc_options: []
|
|
630
630
|
require_paths:
|
|
631
631
|
- lib
|