dependabot-common 0.213.0 → 0.214.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 +10 -1
- data/lib/dependabot/clients/bitbucket.rb +41 -13
- data/lib/dependabot/clients/github_with_retries.rb +15 -19
- data/lib/dependabot/dependency.rb +8 -0
- data/lib/dependabot/dependency_file.rb +11 -3
- data/lib/dependabot/file_fetchers/base.rb +28 -7
- data/lib/dependabot/git_commit_checker.rb +119 -84
- data/lib/dependabot/git_metadata_fetcher.rb +21 -17
- data/lib/dependabot/pull_request_creator/azure.rb +6 -2
- data/lib/dependabot/pull_request_creator/github.rb +1 -1
- data/lib/dependabot/pull_request_creator.rb +2 -0
- data/lib/dependabot/update_checkers/base.rb +12 -5
- data/lib/dependabot/version.rb +1 -1
- metadata +27 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1fab7bc375e03e37b65e94e3e05e7c9ad945d982295b6c9a030083ed038dbaf3
|
|
4
|
+
data.tar.gz: 9924a1980357d1833988bd19a8119a05162a28cc20cbdf157626744ef93be0ba
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 88069b0acbe42180a064046ab55cba565da0f9a3e00d40582a3fb406aee9e3b357cf8e3bdf34dc84da959c931c1519a87e02022e994baf947193f7d6fb949be8
|
|
7
|
+
data.tar.gz: 785cddd10adbed3413e7fdfcbfcc9b5fa00fde7a55f6e171db0c62f4e4a9f17000dc06d7e4c75d312fda6c7801e9fa6428642ea2b3473dc1b4d7f14e0a660bff
|
|
@@ -172,7 +172,8 @@ module Dependabot
|
|
|
172
172
|
|
|
173
173
|
# rubocop:disable Metrics/ParameterLists
|
|
174
174
|
def create_pull_request(pr_name, source_branch, target_branch,
|
|
175
|
-
pr_description, labels,
|
|
175
|
+
pr_description, labels,
|
|
176
|
+
reviewers = nil, assignees = nil, work_item = nil)
|
|
176
177
|
pr_description = truncate_pr_description(pr_description)
|
|
177
178
|
|
|
178
179
|
content = {
|
|
@@ -181,6 +182,7 @@ module Dependabot
|
|
|
181
182
|
title: pr_name,
|
|
182
183
|
description: pr_description,
|
|
183
184
|
labels: labels.map { |label| { name: label } },
|
|
185
|
+
reviewers: pr_reviewers(reviewers, assignees),
|
|
184
186
|
workItemRefs: [{ id: work_item }]
|
|
185
187
|
}
|
|
186
188
|
|
|
@@ -324,6 +326,13 @@ module Dependabot
|
|
|
324
326
|
message&.include?("TF401289")
|
|
325
327
|
end
|
|
326
328
|
|
|
329
|
+
def pr_reviewers(reviewers, assignees)
|
|
330
|
+
return [] unless reviewers || assignees
|
|
331
|
+
|
|
332
|
+
pr_reviewers = reviewers&.map { |r_id| { id: r_id, isRequired: true } } || []
|
|
333
|
+
pr_reviewers + (assignees&.map { |r_id| { id: r_id, isRequired: false } } || [])
|
|
334
|
+
end
|
|
335
|
+
|
|
327
336
|
attr_reader :auth_header
|
|
328
337
|
attr_reader :credentials
|
|
329
338
|
attr_reader :source
|
|
@@ -12,6 +12,8 @@ module Dependabot
|
|
|
12
12
|
|
|
13
13
|
class Forbidden < StandardError; end
|
|
14
14
|
|
|
15
|
+
class TimedOut < StandardError; end
|
|
16
|
+
|
|
15
17
|
#######################
|
|
16
18
|
# Constructor methods #
|
|
17
19
|
#######################
|
|
@@ -79,19 +81,24 @@ module Dependabot
|
|
|
79
81
|
JSON.parse(response.body)
|
|
80
82
|
end
|
|
81
83
|
|
|
82
|
-
def pull_requests(repo, source_branch, target_branch)
|
|
83
|
-
pr_path = "#{repo}/pullrequests"
|
|
84
|
-
# Get pull requests with
|
|
85
|
-
pr_path += "
|
|
84
|
+
def pull_requests(repo, source_branch, target_branch, status = %w(OPEN MERGED DECLINED SUPERSEDED))
|
|
85
|
+
pr_path = "#{repo}/pullrequests?"
|
|
86
|
+
# Get pull requests with given status
|
|
87
|
+
status.each { |n| pr_path += "status=#{n}&" }
|
|
86
88
|
next_page_url = base_url + pr_path
|
|
87
89
|
pull_requests = paginate({ "next" => next_page_url })
|
|
88
90
|
|
|
89
91
|
pull_requests unless source_branch && target_branch
|
|
90
92
|
|
|
91
93
|
pull_requests.select do |pr|
|
|
92
|
-
|
|
94
|
+
if source_branch.nil?
|
|
95
|
+
source_branch_matches = true
|
|
96
|
+
else
|
|
97
|
+
pr_source_branch = pr.fetch("source").fetch("branch").fetch("name")
|
|
98
|
+
source_branch_matches = pr_source_branch == source_branch
|
|
99
|
+
end
|
|
93
100
|
pr_target_branch = pr.fetch("destination").fetch("branch").fetch("name")
|
|
94
|
-
|
|
101
|
+
source_branch_matches && pr_target_branch == target_branch
|
|
95
102
|
end
|
|
96
103
|
end
|
|
97
104
|
|
|
@@ -106,8 +113,7 @@ module Dependabot
|
|
|
106
113
|
}
|
|
107
114
|
|
|
108
115
|
files.each do |file|
|
|
109
|
-
|
|
110
|
-
parameters[absolute_path] = file.content
|
|
116
|
+
parameters[file.path] = file.content
|
|
111
117
|
end
|
|
112
118
|
|
|
113
119
|
body = encode_form_parameters(parameters)
|
|
@@ -144,6 +150,23 @@ module Dependabot
|
|
|
144
150
|
end
|
|
145
151
|
# rubocop:enable Metrics/ParameterLists
|
|
146
152
|
|
|
153
|
+
def decline_pull_request(repo, pr_id, comment = nil)
|
|
154
|
+
# https://developer.atlassian.com/cloud/bitbucket/rest/api-group-pullrequests/
|
|
155
|
+
decline_path = "#{repo}/pullrequests/#{pr_id}/decline"
|
|
156
|
+
post(base_url + decline_path, "")
|
|
157
|
+
|
|
158
|
+
comment = "Dependabot declined the pull request." if comment.nil?
|
|
159
|
+
|
|
160
|
+
content = {
|
|
161
|
+
content: {
|
|
162
|
+
raw: comment
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
comment_path = "#{repo}/pullrequests/#{pr_id}/comments"
|
|
167
|
+
post(base_url + comment_path, content.to_json)
|
|
168
|
+
end
|
|
169
|
+
|
|
147
170
|
def current_user
|
|
148
171
|
base_url = "https://api.bitbucket.org/2.0/user?fields=uuid"
|
|
149
172
|
response = get(base_url)
|
|
@@ -205,6 +228,14 @@ module Dependabot
|
|
|
205
228
|
end
|
|
206
229
|
|
|
207
230
|
def post(url, body, content_type = "application/json")
|
|
231
|
+
headers = auth_header
|
|
232
|
+
|
|
233
|
+
headers = if body.empty?
|
|
234
|
+
headers.merge({ "Accept" => "application/json" })
|
|
235
|
+
else
|
|
236
|
+
headers.merge({ "Content-Type" => content_type })
|
|
237
|
+
end
|
|
238
|
+
|
|
208
239
|
response = Excon.post(
|
|
209
240
|
url,
|
|
210
241
|
body: body,
|
|
@@ -212,16 +243,13 @@ module Dependabot
|
|
|
212
243
|
password: credentials&.fetch("password", nil),
|
|
213
244
|
idempotent: false,
|
|
214
245
|
**SharedHelpers.excon_defaults(
|
|
215
|
-
headers:
|
|
216
|
-
{
|
|
217
|
-
"Content-Type" => content_type
|
|
218
|
-
}
|
|
219
|
-
)
|
|
246
|
+
headers: headers
|
|
220
247
|
)
|
|
221
248
|
)
|
|
222
249
|
raise Unauthorized if response.status == 401
|
|
223
250
|
raise Forbidden if response.status == 403
|
|
224
251
|
raise NotFound if response.status == 404
|
|
252
|
+
raise TimedOut if response.status == 555
|
|
225
253
|
|
|
226
254
|
response
|
|
227
255
|
end
|
|
@@ -84,7 +84,16 @@ module Dependabot
|
|
|
84
84
|
access_tokens << nil if access_tokens.empty?
|
|
85
85
|
access_tokens.uniq!
|
|
86
86
|
|
|
87
|
-
|
|
87
|
+
Octokit.middleware = Faraday::RackBuilder.new do |builder|
|
|
88
|
+
builder.use Faraday::Retry::Middleware, exceptions: RETRYABLE_ERRORS, max: max_retries || 3
|
|
89
|
+
|
|
90
|
+
Octokit::Default::MIDDLEWARE.handlers.each do |handler|
|
|
91
|
+
next if handler.klass == Faraday::Retry::Middleware
|
|
92
|
+
|
|
93
|
+
builder.use handler.klass
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
88
97
|
@clients = access_tokens.map do |token|
|
|
89
98
|
Octokit::Client.new(args.merge(access_token: token))
|
|
90
99
|
end
|
|
@@ -95,13 +104,11 @@ module Dependabot
|
|
|
95
104
|
client = untried_clients.pop
|
|
96
105
|
|
|
97
106
|
begin
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
super
|
|
104
|
-
end
|
|
107
|
+
if client.respond_to?(method_name)
|
|
108
|
+
mutatable_args = args.map(&:dup)
|
|
109
|
+
client.public_send(method_name, *mutatable_args, &block)
|
|
110
|
+
else
|
|
111
|
+
super
|
|
105
112
|
end
|
|
106
113
|
rescue Octokit::NotFound, Octokit::Unauthorized, Octokit::Forbidden
|
|
107
114
|
raise unless (client = untried_clients.pop)
|
|
@@ -113,17 +120,6 @@ module Dependabot
|
|
|
113
120
|
def respond_to_missing?(method_name, include_private = false)
|
|
114
121
|
@clients.first.respond_to?(method_name) || super
|
|
115
122
|
end
|
|
116
|
-
|
|
117
|
-
def retry_connection_failures
|
|
118
|
-
retry_attempt = 0
|
|
119
|
-
|
|
120
|
-
begin
|
|
121
|
-
yield
|
|
122
|
-
rescue *RETRYABLE_ERRORS
|
|
123
|
-
retry_attempt += 1
|
|
124
|
-
retry_attempt <= @max_retries ? retry : raise
|
|
125
|
-
end
|
|
126
|
-
end
|
|
127
123
|
end
|
|
128
124
|
end
|
|
129
125
|
end
|
|
@@ -67,6 +67,10 @@ module Dependabot
|
|
|
67
67
|
@removed
|
|
68
68
|
end
|
|
69
69
|
|
|
70
|
+
def numeric_version
|
|
71
|
+
@numeric_version ||= version_class.new(version) if version && version_class.correct?(version)
|
|
72
|
+
end
|
|
73
|
+
|
|
70
74
|
def to_h
|
|
71
75
|
{
|
|
72
76
|
"name" => name,
|
|
@@ -136,6 +140,10 @@ module Dependabot
|
|
|
136
140
|
|
|
137
141
|
private
|
|
138
142
|
|
|
143
|
+
def version_class
|
|
144
|
+
Utils.version_class_for_package_manager(package_manager)
|
|
145
|
+
end
|
|
146
|
+
|
|
139
147
|
def check_values
|
|
140
148
|
raise ArgumentError, "blank strings must not be provided as versions" if [version, previous_version].any?("")
|
|
141
149
|
|
|
@@ -5,7 +5,7 @@ require "pathname"
|
|
|
5
5
|
module Dependabot
|
|
6
6
|
class DependencyFile
|
|
7
7
|
attr_accessor :name, :content, :directory, :type, :support_file,
|
|
8
|
-
:symlink_target, :content_encoding, :operation
|
|
8
|
+
:symlink_target, :content_encoding, :operation, :mode
|
|
9
9
|
|
|
10
10
|
class ContentEncoding
|
|
11
11
|
UTF_8 = "utf-8"
|
|
@@ -20,7 +20,8 @@ module Dependabot
|
|
|
20
20
|
|
|
21
21
|
def initialize(name:, content:, directory: "/", type: "file",
|
|
22
22
|
support_file: false, symlink_target: nil,
|
|
23
|
-
content_encoding: ContentEncoding::UTF_8, deleted: false,
|
|
23
|
+
content_encoding: ContentEncoding::UTF_8, deleted: false,
|
|
24
|
+
operation: Operation::UPDATE, mode: nil)
|
|
24
25
|
@name = name
|
|
25
26
|
@content = content
|
|
26
27
|
@directory = clean_directory(directory)
|
|
@@ -40,6 +41,12 @@ module Dependabot
|
|
|
40
41
|
# support_file flag instead)
|
|
41
42
|
@type = type
|
|
42
43
|
|
|
44
|
+
begin
|
|
45
|
+
@mode = File.stat((symlink_target || path).sub(%r{^/}, "")).mode.to_s(8)
|
|
46
|
+
rescue StandardError
|
|
47
|
+
@mode = mode
|
|
48
|
+
end
|
|
49
|
+
|
|
43
50
|
return unless (type == "symlink") ^ symlink_target
|
|
44
51
|
|
|
45
52
|
raise "Symlinks must specify a target!" unless symlink_target
|
|
@@ -55,7 +62,8 @@ module Dependabot
|
|
|
55
62
|
"support_file" => support_file,
|
|
56
63
|
"content_encoding" => content_encoding,
|
|
57
64
|
"deleted" => deleted,
|
|
58
|
-
"operation" => operation
|
|
65
|
+
"operation" => operation,
|
|
66
|
+
"mode" => mode
|
|
59
67
|
}
|
|
60
68
|
|
|
61
69
|
details["symlink_target"] = symlink_target if symlink_target
|
|
@@ -26,6 +26,12 @@ module Dependabot
|
|
|
26
26
|
Dependabot::Clients::CodeCommit::NotFound
|
|
27
27
|
].freeze
|
|
28
28
|
|
|
29
|
+
GIT_SUBMODULE_INACCESSIBLE_ERROR =
|
|
30
|
+
/^fatal: unable to access '(?<url>.*)': The requested URL returned error: (?<code>\d+)$/
|
|
31
|
+
GIT_SUBMODULE_CLONE_ERROR =
|
|
32
|
+
/^fatal: clone of '(?<url>.*)' into submodule path '.*' failed$/
|
|
33
|
+
GIT_SUBMODULE_ERROR_REGEX = /(#{GIT_SUBMODULE_INACCESSIBLE_ERROR})|(#{GIT_SUBMODULE_CLONE_ERROR})/
|
|
34
|
+
|
|
29
35
|
def self.required_files_in?(_filename_array)
|
|
30
36
|
raise NotImplementedError
|
|
31
37
|
end
|
|
@@ -592,11 +598,26 @@ module Dependabot
|
|
|
592
598
|
" --no-recurse-submodules"
|
|
593
599
|
end
|
|
594
600
|
clone_options << " --branch #{source.branch} --single-branch" if source.branch
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
601
|
+
|
|
602
|
+
submodule_cloning_failed = false
|
|
603
|
+
begin
|
|
604
|
+
SharedHelpers.run_shell_command(
|
|
605
|
+
<<~CMD
|
|
606
|
+
git clone #{clone_options.string} #{source.url} #{path}
|
|
607
|
+
CMD
|
|
608
|
+
)
|
|
609
|
+
rescue SharedHelpers::HelperSubprocessFailed => e
|
|
610
|
+
raise unless GIT_SUBMODULE_ERROR_REGEX && e.message.downcase.include?("submodule")
|
|
611
|
+
|
|
612
|
+
submodule_cloning_failed = true
|
|
613
|
+
match = e.message.match(GIT_SUBMODULE_ERROR_REGEX)
|
|
614
|
+
url = match.named_captures["url"]
|
|
615
|
+
code = match.named_captures["code"]
|
|
616
|
+
|
|
617
|
+
# Submodules might be in the repo but unrelated to dependencies,
|
|
618
|
+
# so ignoring this error to try the update anyway since the base repo exists.
|
|
619
|
+
Dependabot.logger.error("Cloning of submodule failed: #{url} error: #{code || 'unknown'}")
|
|
620
|
+
end
|
|
600
621
|
|
|
601
622
|
if source.commit
|
|
602
623
|
# This code will only be called for testing. Production will never pass a commit
|
|
@@ -604,7 +625,7 @@ module Dependabot
|
|
|
604
625
|
Dir.chdir(path) do
|
|
605
626
|
fetch_options = StringIO.new
|
|
606
627
|
fetch_options << "--depth 1"
|
|
607
|
-
fetch_options << if recurse_submodules_when_cloning?
|
|
628
|
+
fetch_options << if recurse_submodules_when_cloning? && !submodule_cloning_failed
|
|
608
629
|
" --recurse-submodules=on-demand"
|
|
609
630
|
else
|
|
610
631
|
" --no-recurse-submodules"
|
|
@@ -614,7 +635,7 @@ module Dependabot
|
|
|
614
635
|
|
|
615
636
|
reset_options = StringIO.new
|
|
616
637
|
reset_options << "--hard"
|
|
617
|
-
reset_options << if recurse_submodules_when_cloning?
|
|
638
|
+
reset_options << if recurse_submodules_when_cloning? && !submodule_cloning_failed
|
|
618
639
|
" --recurse-submodules"
|
|
619
640
|
else
|
|
620
641
|
" --no-recurse-submodules"
|
|
@@ -23,13 +23,12 @@ module Dependabot
|
|
|
23
23
|
|
|
24
24
|
def initialize(dependency:, credentials:,
|
|
25
25
|
ignored_versions: [], raise_on_ignored: false,
|
|
26
|
-
|
|
26
|
+
consider_version_branches_pinned: false)
|
|
27
27
|
@dependency = dependency
|
|
28
28
|
@credentials = credentials
|
|
29
29
|
@ignored_versions = ignored_versions
|
|
30
30
|
@raise_on_ignored = raise_on_ignored
|
|
31
|
-
@
|
|
32
|
-
@version_class = version_class
|
|
31
|
+
@consider_version_branches_pinned = consider_version_branches_pinned
|
|
33
32
|
end
|
|
34
33
|
|
|
35
34
|
def git_dependency?
|
|
@@ -52,17 +51,17 @@ module Dependabot
|
|
|
52
51
|
# If the specified `ref` is actually a tag, we're pinned
|
|
53
52
|
return true if local_upload_pack.match?(%r{ refs/tags/#{ref}$})
|
|
54
53
|
|
|
55
|
-
#
|
|
56
|
-
return
|
|
54
|
+
# Assume we're pinned unless the specified `ref` is actually a branch
|
|
55
|
+
return true unless local_upload_pack.match?(%r{ refs/heads/#{ref}$})
|
|
57
56
|
|
|
58
|
-
#
|
|
59
|
-
|
|
57
|
+
# TODO: Research whether considering branches that look like versions pinned makes sense for all ecosystems
|
|
58
|
+
@consider_version_branches_pinned && version_tag?(ref)
|
|
60
59
|
end
|
|
61
60
|
|
|
62
61
|
def pinned_ref_looks_like_version?
|
|
63
62
|
return false unless pinned?
|
|
64
63
|
|
|
65
|
-
dependency_source_details.fetch(:ref)
|
|
64
|
+
version_tag?(dependency_source_details.fetch(:ref))
|
|
66
65
|
end
|
|
67
66
|
|
|
68
67
|
def pinned_ref_looks_like_commit_sha?
|
|
@@ -70,6 +69,11 @@ module Dependabot
|
|
|
70
69
|
ref_looks_like_commit_sha?(ref)
|
|
71
70
|
end
|
|
72
71
|
|
|
72
|
+
def head_commit_for_pinned_ref
|
|
73
|
+
ref = dependency_source_details.fetch(:ref)
|
|
74
|
+
local_repo_git_metadata_fetcher.head_commit_for_ref_sha(ref)
|
|
75
|
+
end
|
|
76
|
+
|
|
73
77
|
def ref_looks_like_commit_sha?(ref)
|
|
74
78
|
return false unless ref&.match?(/^[0-9a-f]{6,40}$/)
|
|
75
79
|
|
|
@@ -85,13 +89,8 @@ module Dependabot
|
|
|
85
89
|
def head_commit_for_current_branch
|
|
86
90
|
ref = ref_or_branch || "HEAD"
|
|
87
91
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
local_repo_git_metadata_fetcher.head_commit_for_ref(ref)
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
sha = local_repo_git_metadata_fetcher.head_commit_for_ref(ref)
|
|
94
|
-
return sha if sha
|
|
92
|
+
sha = head_commit_for_local_branch(ref)
|
|
93
|
+
return sha if pinned? || sha
|
|
95
94
|
|
|
96
95
|
raise Dependabot::GitDependencyReferenceNotFound, dependency.name
|
|
97
96
|
end
|
|
@@ -100,75 +99,45 @@ module Dependabot
|
|
|
100
99
|
local_repo_git_metadata_fetcher.head_commit_for_ref(name)
|
|
101
100
|
end
|
|
102
101
|
|
|
103
|
-
def
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
return [] unless max_tag
|
|
102
|
+
def local_tag_for_latest_version_matching_existing_precision
|
|
103
|
+
max_local_tag_for_current_precision(allowed_version_tags)
|
|
104
|
+
end
|
|
108
105
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
map do |t|
|
|
112
|
-
version = t.name.match(VERSION_REGEX).named_captures.fetch("version")
|
|
113
|
-
{
|
|
114
|
-
tag: t.name,
|
|
115
|
-
version: version_class.new(version),
|
|
116
|
-
commit_sha: t.commit_sha,
|
|
117
|
-
tag_sha: t.tag_sha
|
|
118
|
-
}
|
|
119
|
-
end
|
|
106
|
+
def local_ref_for_latest_version_matching_existing_precision
|
|
107
|
+
max_local_tag_for_current_precision(allowed_version_refs)
|
|
120
108
|
end
|
|
121
109
|
|
|
122
110
|
def local_tag_for_latest_version
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
return unless tag
|
|
111
|
+
max_local_tag(allowed_version_tags)
|
|
112
|
+
end
|
|
126
113
|
|
|
127
|
-
|
|
128
|
-
{
|
|
129
|
-
tag: tag.name,
|
|
130
|
-
version: version_class.new(version),
|
|
131
|
-
commit_sha: tag.commit_sha,
|
|
132
|
-
tag_sha: tag.tag_sha
|
|
133
|
-
}
|
|
114
|
+
def local_tags_for_allowed_versions_matching_existing_precision
|
|
115
|
+
select_matching_existing_precision(allowed_version_tags).map { |t| to_local_tag(t) }
|
|
134
116
|
end
|
|
135
117
|
|
|
136
|
-
def
|
|
137
|
-
|
|
138
|
-
max_by do |t|
|
|
139
|
-
version = t.name.match(VERSION_REGEX).named_captures.
|
|
140
|
-
fetch("version")
|
|
141
|
-
version_class.new(version)
|
|
142
|
-
end
|
|
118
|
+
def local_tags_for_allowed_versions
|
|
119
|
+
allowed_version_tags.map { |t| to_local_tag(t) }
|
|
143
120
|
end
|
|
144
121
|
|
|
145
122
|
def allowed_version_tags
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
select { |t| version_tag?(t.name) && matches_existing_prefix?(t.name) }
|
|
149
|
-
filtered = tags.
|
|
150
|
-
reject { |t| tag_included_in_ignore_requirements?(t) }
|
|
151
|
-
if @raise_on_ignored && filter_lower_versions(filtered).empty? && filter_lower_versions(tags).any?
|
|
152
|
-
raise Dependabot::AllVersionsIgnored
|
|
153
|
-
end
|
|
123
|
+
allowed_versions(local_tags)
|
|
124
|
+
end
|
|
154
125
|
|
|
155
|
-
|
|
156
|
-
|
|
126
|
+
def allowed_version_refs
|
|
127
|
+
allowed_versions(local_refs)
|
|
157
128
|
end
|
|
158
129
|
|
|
159
130
|
def current_version
|
|
160
131
|
return unless dependency.version && version_tag?(dependency.version)
|
|
161
132
|
|
|
162
|
-
|
|
163
|
-
version_class.new(version)
|
|
133
|
+
version_from_ref(dependency.version)
|
|
164
134
|
end
|
|
165
135
|
|
|
166
136
|
def filter_lower_versions(tags)
|
|
167
137
|
return tags unless current_version
|
|
168
138
|
|
|
169
139
|
versions = tags.map do |t|
|
|
170
|
-
|
|
171
|
-
version_class.new(version)
|
|
140
|
+
version_from_tag(t)
|
|
172
141
|
end
|
|
173
142
|
|
|
174
143
|
versions.select do |version|
|
|
@@ -176,15 +145,14 @@ module Dependabot
|
|
|
176
145
|
end
|
|
177
146
|
end
|
|
178
147
|
|
|
179
|
-
def
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
tags = local_tags.select { |t| t.commit_sha == ref && version_class.correct?(t.name) }.
|
|
184
|
-
sort_by { |t| version_class.new(t.name) }
|
|
185
|
-
return if tags.empty?
|
|
148
|
+
def most_specific_tag_equivalent_to_pinned_ref
|
|
149
|
+
commit_sha = head_commit_for_local_branch(dependency_source_details.fetch(:ref))
|
|
150
|
+
most_specific_version_tag_for_sha(commit_sha)
|
|
151
|
+
end
|
|
186
152
|
|
|
187
|
-
|
|
153
|
+
def local_tag_for_pinned_sha
|
|
154
|
+
commit_sha = dependency_source_details.fetch(:ref)
|
|
155
|
+
most_specific_version_tag_for_sha(commit_sha)
|
|
188
156
|
end
|
|
189
157
|
|
|
190
158
|
def git_repo_reachable?
|
|
@@ -198,6 +166,49 @@ module Dependabot
|
|
|
198
166
|
|
|
199
167
|
attr_reader :dependency, :credentials, :ignored_versions
|
|
200
168
|
|
|
169
|
+
def max_local_tag_for_current_precision(tags)
|
|
170
|
+
max_local_tag(select_matching_existing_precision(tags))
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def max_local_tag(tags)
|
|
174
|
+
max_version_tag = tags.max_by { |t| version_from_tag(t) }
|
|
175
|
+
|
|
176
|
+
to_local_tag(max_version_tag)
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# Find the latest version with the same precision as the pinned version.
|
|
180
|
+
def select_matching_existing_precision(tags)
|
|
181
|
+
current_precision = precision(dependency.version)
|
|
182
|
+
|
|
183
|
+
tags.select { |tag| precision(scan_version(tag.name)) == current_precision }
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def precision(version)
|
|
187
|
+
version.split(".").length
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def most_specific_version_tag_for_sha(commit_sha)
|
|
191
|
+
tags = local_tags.select { |t| t.commit_sha == commit_sha && version_class.correct?(t.name) }.
|
|
192
|
+
sort_by { |t| version_class.new(t.name) }
|
|
193
|
+
return if tags.empty?
|
|
194
|
+
|
|
195
|
+
tags[-1].name
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def allowed_versions(local_tags)
|
|
199
|
+
tags =
|
|
200
|
+
local_tags.
|
|
201
|
+
select { |t| version_tag?(t.name) && matches_existing_prefix?(t.name) }
|
|
202
|
+
filtered = tags.
|
|
203
|
+
reject { |t| tag_included_in_ignore_requirements?(t) }
|
|
204
|
+
if @raise_on_ignored && filter_lower_versions(filtered).empty? && filter_lower_versions(tags).any?
|
|
205
|
+
raise Dependabot::AllVersionsIgnored
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
filtered.
|
|
209
|
+
reject { |t| tag_is_prerelease?(t) && !wants_prerelease? }
|
|
210
|
+
end
|
|
211
|
+
|
|
201
212
|
def pinned_ref_in_release?(version)
|
|
202
213
|
raise "Not a git dependency!" unless git_dependency?
|
|
203
214
|
|
|
@@ -236,9 +247,15 @@ module Dependabot
|
|
|
236
247
|
local_repo_git_metadata_fetcher.upload_pack
|
|
237
248
|
end
|
|
238
249
|
|
|
250
|
+
def local_refs
|
|
251
|
+
handle_tag_prefix(local_repo_git_metadata_fetcher.refs_for_upload_pack)
|
|
252
|
+
end
|
|
253
|
+
|
|
239
254
|
def local_tags
|
|
240
|
-
|
|
255
|
+
handle_tag_prefix(local_repo_git_metadata_fetcher.tags_for_upload_pack)
|
|
256
|
+
end
|
|
241
257
|
|
|
258
|
+
def handle_tag_prefix(tags)
|
|
242
259
|
if dependency_source_details&.fetch(:ref, nil)&.start_with?("tags/")
|
|
243
260
|
tags = tags.map do |tag|
|
|
244
261
|
tag.dup.tap { |t| t.name = "tags/#{tag.name}" }
|
|
@@ -341,6 +358,18 @@ module Dependabot
|
|
|
341
358
|
tag.gsub(VERSION_REGEX, "").gsub(/v$/i, "")
|
|
342
359
|
end
|
|
343
360
|
|
|
361
|
+
def to_local_tag(tag)
|
|
362
|
+
return unless tag
|
|
363
|
+
|
|
364
|
+
version = version_from_tag(tag)
|
|
365
|
+
{
|
|
366
|
+
tag: tag.name,
|
|
367
|
+
version: version,
|
|
368
|
+
commit_sha: tag.commit_sha,
|
|
369
|
+
tag_sha: tag.ref_sha
|
|
370
|
+
}
|
|
371
|
+
end
|
|
372
|
+
|
|
344
373
|
def listing_source_url
|
|
345
374
|
@listing_source_url ||=
|
|
346
375
|
begin
|
|
@@ -404,31 +433,37 @@ module Dependabot
|
|
|
404
433
|
return false unless dependency_source_details&.fetch(:ref, nil)
|
|
405
434
|
return false unless pinned_ref_looks_like_version?
|
|
406
435
|
|
|
407
|
-
version = dependency_source_details.fetch(:ref)
|
|
408
|
-
|
|
409
|
-
version_class.new(version).prerelease?
|
|
436
|
+
version = version_from_ref(dependency_source_details.fetch(:ref))
|
|
437
|
+
version.prerelease?
|
|
410
438
|
end
|
|
411
439
|
|
|
412
440
|
def tag_included_in_ignore_requirements?(tag)
|
|
413
|
-
version = tag
|
|
414
|
-
ignore_requirements.any? { |r| r.satisfied_by?(
|
|
441
|
+
version = version_from_tag(tag)
|
|
442
|
+
ignore_requirements.any? { |r| r.satisfied_by?(version) }
|
|
415
443
|
end
|
|
416
444
|
|
|
417
445
|
def tag_is_prerelease?(tag)
|
|
418
|
-
|
|
419
|
-
version_class.new(version).prerelease?
|
|
446
|
+
version_from_tag(tag).prerelease?
|
|
420
447
|
end
|
|
421
448
|
|
|
422
|
-
def
|
|
423
|
-
|
|
449
|
+
def version_from_tag(tag)
|
|
450
|
+
version_from_ref(tag.name)
|
|
451
|
+
end
|
|
424
452
|
|
|
425
|
-
|
|
453
|
+
def version_from_ref(name)
|
|
454
|
+
version_class.new(scan_version(name))
|
|
426
455
|
end
|
|
427
456
|
|
|
428
|
-
def
|
|
429
|
-
|
|
457
|
+
def scan_version(name)
|
|
458
|
+
name.match(VERSION_REGEX).named_captures.fetch("version")
|
|
459
|
+
end
|
|
430
460
|
|
|
431
|
-
|
|
461
|
+
def version_class
|
|
462
|
+
@version_class ||= Utils.version_class_for_package_manager(dependency.package_manager)
|
|
463
|
+
end
|
|
464
|
+
|
|
465
|
+
def requirement_class
|
|
466
|
+
@requirement_class ||= Utils.requirement_class_for_package_manager(dependency.package_manager)
|
|
432
467
|
end
|
|
433
468
|
|
|
434
469
|
def local_repo_git_metadata_fetcher
|
|
@@ -22,7 +22,21 @@ module Dependabot
|
|
|
22
22
|
def tags
|
|
23
23
|
return [] unless upload_pack
|
|
24
24
|
|
|
25
|
-
@tags ||= tags_for_upload_pack
|
|
25
|
+
@tags ||= tags_for_upload_pack.map do |ref|
|
|
26
|
+
OpenStruct.new(
|
|
27
|
+
name: ref.name,
|
|
28
|
+
tag_sha: ref.ref_sha,
|
|
29
|
+
commit_sha: ref.commit_sha
|
|
30
|
+
)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def tags_for_upload_pack
|
|
35
|
+
@tags_for_upload_pack ||= refs_for_upload_pack.select { |ref| ref.ref_type == :tag }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def refs_for_upload_pack
|
|
39
|
+
@refs_for_upload_pack ||= parse_refs_for_upload_pack
|
|
26
40
|
end
|
|
27
41
|
|
|
28
42
|
def ref_names
|
|
@@ -44,6 +58,12 @@ module Dependabot
|
|
|
44
58
|
commit_sha
|
|
45
59
|
end
|
|
46
60
|
|
|
61
|
+
def head_commit_for_ref_sha(ref)
|
|
62
|
+
refs_for_upload_pack.
|
|
63
|
+
find { |r| r.ref_sha == ref }&.
|
|
64
|
+
commit_sha
|
|
65
|
+
end
|
|
66
|
+
|
|
47
67
|
private
|
|
48
68
|
|
|
49
69
|
attr_reader :url, :credentials
|
|
@@ -102,22 +122,6 @@ module Dependabot
|
|
|
102
122
|
end
|
|
103
123
|
end
|
|
104
124
|
|
|
105
|
-
def tags_for_upload_pack
|
|
106
|
-
refs_for_upload_pack.
|
|
107
|
-
select { |ref| ref.ref_type == :tag }.
|
|
108
|
-
map do |ref|
|
|
109
|
-
OpenStruct.new(
|
|
110
|
-
name: ref.name,
|
|
111
|
-
tag_sha: ref.ref_sha,
|
|
112
|
-
commit_sha: ref.commit_sha
|
|
113
|
-
)
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
def refs_for_upload_pack
|
|
118
|
-
@refs_for_upload_pack ||= parse_refs_for_upload_pack
|
|
119
|
-
end
|
|
120
|
-
|
|
121
125
|
def parse_refs_for_upload_pack
|
|
122
126
|
peeled_lines = []
|
|
123
127
|
|
|
@@ -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, :work_item
|
|
11
|
+
:author_details, :labeler, :reviewers, :assignees, :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:, work_item: nil)
|
|
15
|
+
author_details:, labeler:, reviewers: nil, assignees: nil, work_item: nil)
|
|
16
16
|
@source = source
|
|
17
17
|
@branch_name = branch_name
|
|
18
18
|
@base_commit = base_commit
|
|
@@ -23,6 +23,8 @@ module Dependabot
|
|
|
23
23
|
@pr_name = pr_name
|
|
24
24
|
@author_details = author_details
|
|
25
25
|
@labeler = labeler
|
|
26
|
+
@reviewers = reviewers
|
|
27
|
+
@assignees = assignees
|
|
26
28
|
@work_item = work_item
|
|
27
29
|
end
|
|
28
30
|
|
|
@@ -79,6 +81,8 @@ module Dependabot
|
|
|
79
81
|
source.branch || default_branch,
|
|
80
82
|
pr_description,
|
|
81
83
|
labeler.labels_for_pr,
|
|
84
|
+
reviewers,
|
|
85
|
+
assignees,
|
|
82
86
|
work_item
|
|
83
87
|
)
|
|
84
88
|
end
|
|
@@ -137,8 +137,7 @@ module Dependabot
|
|
|
137
137
|
# Can't (currently) detect whether git dependencies are vulnerable
|
|
138
138
|
return false if existing_version_is_sha?
|
|
139
139
|
|
|
140
|
-
|
|
141
|
-
security_advisories.any? { |a| a.vulnerable?(version) }
|
|
140
|
+
active_advisories.any?
|
|
142
141
|
end
|
|
143
142
|
|
|
144
143
|
def ignore_requirements
|
|
@@ -147,6 +146,10 @@ module Dependabot
|
|
|
147
146
|
|
|
148
147
|
private
|
|
149
148
|
|
|
149
|
+
def active_advisories
|
|
150
|
+
security_advisories.select { |a| a.vulnerable?(current_version) }
|
|
151
|
+
end
|
|
152
|
+
|
|
150
153
|
def latest_version_resolvable_with_full_unlock?
|
|
151
154
|
raise NotImplementedError
|
|
152
155
|
end
|
|
@@ -235,7 +238,7 @@ module Dependabot
|
|
|
235
238
|
# this case we treat the version as up-to-date so that it's ignored.
|
|
236
239
|
return true if latest_version.to_s.match?(/^[0-9a-f]{40}$/)
|
|
237
240
|
|
|
238
|
-
latest_version <=
|
|
241
|
+
latest_version <= current_version
|
|
239
242
|
end
|
|
240
243
|
|
|
241
244
|
def numeric_version_can_update?(requirements_to_unlock:)
|
|
@@ -244,7 +247,7 @@ module Dependabot
|
|
|
244
247
|
case requirements_to_unlock&.to_sym
|
|
245
248
|
when :none
|
|
246
249
|
new_version = latest_resolvable_version_with_no_unlock
|
|
247
|
-
new_version && new_version >
|
|
250
|
+
new_version && new_version > current_version
|
|
248
251
|
when :own
|
|
249
252
|
preferred_version_resolvable_with_unlock?
|
|
250
253
|
when :all
|
|
@@ -259,7 +262,7 @@ module Dependabot
|
|
|
259
262
|
|
|
260
263
|
if existing_version_is_sha?
|
|
261
264
|
return false if new_version.to_s.start_with?(dependency.version)
|
|
262
|
-
elsif new_version <=
|
|
265
|
+
elsif new_version <= current_version
|
|
263
266
|
return false
|
|
264
267
|
end
|
|
265
268
|
|
|
@@ -275,6 +278,10 @@ module Dependabot
|
|
|
275
278
|
changed_requirements.none?
|
|
276
279
|
end
|
|
277
280
|
|
|
281
|
+
def current_version
|
|
282
|
+
@current_version ||= dependency.numeric_version
|
|
283
|
+
end
|
|
284
|
+
|
|
278
285
|
def can_compare_requirements?
|
|
279
286
|
version_from_requirements &&
|
|
280
287
|
latest_version &&
|
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.214.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dependabot
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-
|
|
11
|
+
date: 2022-12-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -119,6 +119,9 @@ dependencies:
|
|
|
119
119
|
- - "~>"
|
|
120
120
|
- !ruby/object:Gem::Version
|
|
121
121
|
version: '0.75'
|
|
122
|
+
- - "<"
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: '0.94'
|
|
122
125
|
type: :runtime
|
|
123
126
|
prerelease: false
|
|
124
127
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -126,6 +129,9 @@ dependencies:
|
|
|
126
129
|
- - "~>"
|
|
127
130
|
- !ruby/object:Gem::Version
|
|
128
131
|
version: '0.75'
|
|
132
|
+
- - "<"
|
|
133
|
+
- !ruby/object:Gem::Version
|
|
134
|
+
version: '0.94'
|
|
129
135
|
- !ruby/object:Gem::Dependency
|
|
130
136
|
name: faraday
|
|
131
137
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -140,6 +146,20 @@ dependencies:
|
|
|
140
146
|
- - '='
|
|
141
147
|
- !ruby/object:Gem::Version
|
|
142
148
|
version: 2.6.0
|
|
149
|
+
- !ruby/object:Gem::Dependency
|
|
150
|
+
name: faraday-retry
|
|
151
|
+
requirement: !ruby/object:Gem::Requirement
|
|
152
|
+
requirements:
|
|
153
|
+
- - '='
|
|
154
|
+
- !ruby/object:Gem::Version
|
|
155
|
+
version: 2.0.0
|
|
156
|
+
type: :runtime
|
|
157
|
+
prerelease: false
|
|
158
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
159
|
+
requirements:
|
|
160
|
+
- - '='
|
|
161
|
+
- !ruby/object:Gem::Version
|
|
162
|
+
version: 2.0.0
|
|
143
163
|
- !ruby/object:Gem::Dependency
|
|
144
164
|
name: gitlab
|
|
145
165
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -262,14 +282,14 @@ dependencies:
|
|
|
262
282
|
requirements:
|
|
263
283
|
- - "~>"
|
|
264
284
|
- !ruby/object:Gem::Version
|
|
265
|
-
version:
|
|
285
|
+
version: 4.0.0
|
|
266
286
|
type: :development
|
|
267
287
|
prerelease: false
|
|
268
288
|
version_requirements: !ruby/object:Gem::Requirement
|
|
269
289
|
requirements:
|
|
270
290
|
- - "~>"
|
|
271
291
|
- !ruby/object:Gem::Version
|
|
272
|
-
version:
|
|
292
|
+
version: 4.0.0
|
|
273
293
|
- !ruby/object:Gem::Dependency
|
|
274
294
|
name: rake
|
|
275
295
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -318,14 +338,14 @@ dependencies:
|
|
|
318
338
|
requirements:
|
|
319
339
|
- - "~>"
|
|
320
340
|
- !ruby/object:Gem::Version
|
|
321
|
-
version: 1.
|
|
341
|
+
version: 1.39.0
|
|
322
342
|
type: :development
|
|
323
343
|
prerelease: false
|
|
324
344
|
version_requirements: !ruby/object:Gem::Requirement
|
|
325
345
|
requirements:
|
|
326
346
|
- - "~>"
|
|
327
347
|
- !ruby/object:Gem::Version
|
|
328
|
-
version: 1.
|
|
348
|
+
version: 1.39.0
|
|
329
349
|
- !ruby/object:Gem::Dependency
|
|
330
350
|
name: rubocop-performance
|
|
331
351
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -503,7 +523,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
503
523
|
requirements:
|
|
504
524
|
- - ">="
|
|
505
525
|
- !ruby/object:Gem::Version
|
|
506
|
-
version: 3.3.
|
|
526
|
+
version: 3.3.7
|
|
507
527
|
requirements: []
|
|
508
528
|
rubygems_version: 3.3.7
|
|
509
529
|
signing_key:
|