dependabot-common 0.334.0 → 0.335.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 +108 -60
- data/lib/dependabot/clients/bitbucket.rb +17 -4
- data/lib/dependabot/clients/codecommit.rb +17 -7
- data/lib/dependabot/config/file.rb +31 -28
- data/lib/dependabot/dependency.rb +18 -7
- data/lib/dependabot/dependency_file.rb +17 -6
- data/lib/dependabot/dependency_graphers/README.md +54 -0
- data/lib/dependabot/dependency_graphers/base.rb +118 -0
- data/lib/dependabot/dependency_graphers/generic.rb +76 -0
- data/lib/dependabot/dependency_graphers.rb +33 -0
- data/lib/dependabot/file_fetchers/base.rb +11 -4
- data/lib/dependabot/file_filtering.rb +9 -5
- data/lib/dependabot/file_parsers/base.rb +8 -2
- data/lib/dependabot/file_updaters/artifact_updater.rb +1 -0
- data/lib/dependabot/git_commit_checker.rb +17 -10
- data/lib/dependabot/git_metadata_fetcher.rb +4 -2
- data/lib/dependabot/metadata_finders/base/changelog_finder.rb +6 -2
- data/lib/dependabot/metadata_finders/base/changelog_pruner.rb +4 -2
- data/lib/dependabot/notices.rb +7 -3
- data/lib/dependabot/package/release_cooldown_options.rb +6 -2
- data/lib/dependabot/pull_request_creator/azure.rb +15 -3
- data/lib/dependabot/pull_request_creator/bitbucket.rb +13 -3
- data/lib/dependabot/pull_request_creator/branch_namer/base.rb +8 -2
- data/lib/dependabot/pull_request_creator/branch_namer/dependency_group_strategy.rb +15 -5
- data/lib/dependabot/pull_request_creator/branch_namer/multi_ecosystem_strategy.rb +15 -5
- data/lib/dependabot/pull_request_creator/branch_namer/solo_strategy.rb +11 -7
- data/lib/dependabot/pull_request_creator/branch_namer.rb +11 -2
- data/lib/dependabot/pull_request_creator/codecommit.rb +20 -7
- data/lib/dependabot/pull_request_creator/commit_signer.rb +10 -4
- data/lib/dependabot/pull_request_creator/github.rb +18 -5
- data/lib/dependabot/pull_request_creator/gitlab.rb +16 -4
- data/lib/dependabot/pull_request_creator/labeler.rb +35 -19
- data/lib/dependabot/pull_request_creator/message_builder/issue_linker.rb +15 -10
- data/lib/dependabot/pull_request_creator/message_builder/metadata_presenter.rb +7 -2
- data/lib/dependabot/pull_request_creator/message_builder.rb +16 -6
- data/lib/dependabot/pull_request_creator/pr_name_prefixer.rb +7 -2
- data/lib/dependabot/pull_request_creator.rb +31 -12
- data/lib/dependabot/pull_request_updater/azure.rb +9 -2
- data/lib/dependabot/pull_request_updater/github.rb +10 -3
- data/lib/dependabot/pull_request_updater/gitlab.rb +9 -2
- data/lib/dependabot/pull_request_updater.rb +11 -4
- data/lib/dependabot/security_advisory.rb +12 -6
- data/lib/dependabot/shared_helpers.rb +36 -19
- data/lib/dependabot/source.rb +14 -4
- data/lib/dependabot/update_checkers/base.rb +13 -5
- data/lib/dependabot.rb +1 -1
- metadata +16 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ca29ec928a5e569aa377708755f29f998ca87ddb68ed2722a5171386427e3f87
|
4
|
+
data.tar.gz: 206f507ef450d40f3a002187a7890dc5b5abc88c7d8df5e53a87a27a14aa9f71
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3a3baf81472a1b7528fb6f95f9c5ed76f79186fd4aa442e073b2f0bc60e676186f592ab16a18f1f6bb747e652e522d0f1af2a7ac077a3dbce0d89001c001fc93
|
7
|
+
data.tar.gz: 26a4aaa04570ec094267b7e2739a394fe4d279807ad03453ac6cec8c766d18cb3b13e73665923cf8e58ca64ab6fad7b8b8a20656a0feaa93b80bcdaed6119503
|
@@ -65,10 +65,12 @@ module Dependabot
|
|
65
65
|
|
66
66
|
sig { params(_repo: T.nilable(String), branch: String).returns(String) }
|
67
67
|
def fetch_commit(_repo, branch)
|
68
|
-
response = get(
|
69
|
-
|
70
|
-
|
71
|
-
|
68
|
+
response = get(
|
69
|
+
T.must(source.api_endpoint) +
|
70
|
+
source.organization + "/" + source.project +
|
71
|
+
"/_apis/git/repositories/" + source.unscoped_repo +
|
72
|
+
"/stats/branches?name=" + branch
|
73
|
+
)
|
72
74
|
|
73
75
|
raise NotFound if response.status == 400
|
74
76
|
|
@@ -77,9 +79,11 @@ module Dependabot
|
|
77
79
|
|
78
80
|
sig { params(_repo: String).returns(String) }
|
79
81
|
def fetch_default_branch(_repo)
|
80
|
-
response = get(
|
81
|
-
|
82
|
-
|
82
|
+
response = get(
|
83
|
+
T.must(source.api_endpoint) +
|
84
|
+
source.organization + "/" + source.project +
|
85
|
+
"/_apis/git/repositories/" + source.unscoped_repo
|
86
|
+
)
|
83
87
|
|
84
88
|
JSON.parse(response.body).fetch("defaultBranch").gsub("refs/heads/", "")
|
85
89
|
end
|
@@ -94,10 +98,12 @@ module Dependabot
|
|
94
98
|
def fetch_repo_contents(commit = nil, path = nil)
|
95
99
|
tree = fetch_repo_contents_treeroot(commit, path)
|
96
100
|
|
97
|
-
response = get(
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
+
response = get(
|
102
|
+
T.must(source.api_endpoint) +
|
103
|
+
source.organization + "/" + source.project +
|
104
|
+
"/_apis/git/repositories/" + source.unscoped_repo +
|
105
|
+
"/trees/" + tree + "?recursive=false"
|
106
|
+
)
|
101
107
|
|
102
108
|
JSON.parse(response.body).fetch("treeEntries")
|
103
109
|
end
|
@@ -124,12 +130,14 @@ module Dependabot
|
|
124
130
|
|
125
131
|
sig { params(commit: String, path: String).returns(String) }
|
126
132
|
def fetch_file_contents(commit, path)
|
127
|
-
response = get(
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
+
response = get(
|
134
|
+
T.must(source.api_endpoint) +
|
135
|
+
source.organization + "/" + source.project +
|
136
|
+
"/_apis/git/repositories/" + source.unscoped_repo +
|
137
|
+
"/items?path=" + path +
|
138
|
+
"&versionDescriptor.versionType=commit" \
|
139
|
+
"&versionDescriptor.version=" + commit
|
140
|
+
)
|
133
141
|
|
134
142
|
response.body
|
135
143
|
end
|
@@ -150,22 +158,26 @@ module Dependabot
|
|
150
158
|
|
151
159
|
sig { params(branch_name: String).returns(T.nilable(T::Hash[String, T.untyped])) }
|
152
160
|
def branch(branch_name)
|
153
|
-
response = get(
|
154
|
-
|
155
|
-
|
156
|
-
|
161
|
+
response = get(
|
162
|
+
T.must(source.api_endpoint) +
|
163
|
+
source.organization + "/" + source.project +
|
164
|
+
"/_apis/git/repositories/" + source.unscoped_repo +
|
165
|
+
"/refs?filter=heads/" + branch_name
|
166
|
+
)
|
157
167
|
|
158
168
|
JSON.parse(response.body).fetch("value").first
|
159
169
|
end
|
160
170
|
|
161
171
|
sig { params(source_branch: String, target_branch: String).returns(T::Array[T::Hash[String, T.untyped]]) }
|
162
172
|
def pull_requests(source_branch, target_branch)
|
163
|
-
response = get(
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
173
|
+
response = get(
|
174
|
+
T.must(source.api_endpoint) +
|
175
|
+
source.organization + "/" + source.project +
|
176
|
+
"/_apis/git/repositories/" + source.unscoped_repo +
|
177
|
+
"/pullrequests?searchCriteria.status=all" \
|
178
|
+
"&searchCriteria.sourceRefName=refs/heads/" + source_branch +
|
179
|
+
"&searchCriteria.targetRefName=refs/heads/" + target_branch
|
180
|
+
)
|
169
181
|
|
170
182
|
JSON.parse(response.body).fetch("value")
|
171
183
|
end
|
@@ -180,8 +192,13 @@ module Dependabot
|
|
180
192
|
)
|
181
193
|
.returns(T.untyped)
|
182
194
|
end
|
183
|
-
def create_commit(
|
184
|
-
|
195
|
+
def create_commit(
|
196
|
+
branch_name,
|
197
|
+
base_commit,
|
198
|
+
commit_message,
|
199
|
+
files,
|
200
|
+
author_details
|
201
|
+
)
|
185
202
|
content = {
|
186
203
|
refUpdates: [
|
187
204
|
{ name: "refs/heads/" + branch_name, oldObjectId: base_commit }
|
@@ -204,9 +221,12 @@ module Dependabot
|
|
204
221
|
]
|
205
222
|
}
|
206
223
|
|
207
|
-
post(
|
208
|
-
"/
|
209
|
-
|
224
|
+
post(
|
225
|
+
T.must(source.api_endpoint) + source.organization + "/" + source.project +
|
226
|
+
"/_apis/git/repositories/" + source.unscoped_repo +
|
227
|
+
"/pushes?api-version=5.0",
|
228
|
+
content.to_json
|
229
|
+
)
|
210
230
|
end
|
211
231
|
|
212
232
|
# rubocop:disable Metrics/ParameterLists
|
@@ -223,9 +243,16 @@ module Dependabot
|
|
223
243
|
)
|
224
244
|
.returns(T.untyped)
|
225
245
|
end
|
226
|
-
def create_pull_request(
|
227
|
-
|
228
|
-
|
246
|
+
def create_pull_request(
|
247
|
+
pr_name,
|
248
|
+
source_branch,
|
249
|
+
target_branch,
|
250
|
+
pr_description,
|
251
|
+
labels,
|
252
|
+
reviewers = nil,
|
253
|
+
assignees = nil,
|
254
|
+
work_item = nil
|
255
|
+
)
|
229
256
|
content = {
|
230
257
|
sourceRefName: "refs/heads/" + source_branch,
|
231
258
|
targetRefName: "refs/heads/" + target_branch,
|
@@ -236,10 +263,13 @@ module Dependabot
|
|
236
263
|
workItemRefs: [{ id: work_item }]
|
237
264
|
}
|
238
265
|
|
239
|
-
post(
|
240
|
-
|
241
|
-
|
242
|
-
|
266
|
+
post(
|
267
|
+
T.must(source.api_endpoint) +
|
268
|
+
source.organization + "/" + source.project +
|
269
|
+
"/_apis/git/repositories/" + source.unscoped_repo +
|
270
|
+
"/pullrequests?api-version=5.0",
|
271
|
+
content.to_json
|
272
|
+
)
|
243
273
|
end
|
244
274
|
|
245
275
|
sig do
|
@@ -255,9 +285,16 @@ module Dependabot
|
|
255
285
|
)
|
256
286
|
.returns(T.untyped)
|
257
287
|
end
|
258
|
-
def autocomplete_pull_request(
|
259
|
-
|
260
|
-
|
288
|
+
def autocomplete_pull_request(
|
289
|
+
pull_request_id,
|
290
|
+
auto_complete_set_by,
|
291
|
+
merge_commit_message,
|
292
|
+
delete_source_branch = true,
|
293
|
+
squash_merge = true,
|
294
|
+
merge_strategy = "squash",
|
295
|
+
trans_work_items = true,
|
296
|
+
ignore_config_ids = []
|
297
|
+
)
|
261
298
|
content = {
|
262
299
|
autoCompleteSetBy: {
|
263
300
|
id: auto_complete_set_by
|
@@ -272,19 +309,24 @@ module Dependabot
|
|
272
309
|
}
|
273
310
|
}
|
274
311
|
|
275
|
-
response = patch(
|
276
|
-
|
277
|
-
|
278
|
-
|
312
|
+
response = patch(
|
313
|
+
T.must(source.api_endpoint) +
|
314
|
+
source.organization + "/" + source.project +
|
315
|
+
"/_apis/git/repositories/" + source.unscoped_repo +
|
316
|
+
"/pullrequests/" + pull_request_id.to_s + "?api-version=5.1",
|
317
|
+
content.to_json
|
318
|
+
)
|
279
319
|
|
280
320
|
JSON.parse(response.body)
|
281
321
|
end
|
282
322
|
|
283
323
|
sig { params(pull_request_id: String).returns(T::Hash[String, T.untyped]) }
|
284
324
|
def pull_request(pull_request_id)
|
285
|
-
response = get(
|
286
|
-
|
287
|
-
|
325
|
+
response = get(
|
326
|
+
T.must(source.api_endpoint) +
|
327
|
+
source.organization + "/" + source.project +
|
328
|
+
"/_apis/git/pullrequests/" + pull_request_id
|
329
|
+
)
|
288
330
|
|
289
331
|
JSON.parse(response.body)
|
290
332
|
end
|
@@ -299,9 +341,12 @@ module Dependabot
|
|
299
341
|
}
|
300
342
|
]
|
301
343
|
|
302
|
-
response = post(
|
303
|
-
|
304
|
-
|
344
|
+
response = post(
|
345
|
+
T.must(source.api_endpoint) + source.organization + "/" + source.project +
|
346
|
+
"/_apis/git/repositories/" + source.unscoped_repo +
|
347
|
+
"/refs?api-version=5.0",
|
348
|
+
content.to_json
|
349
|
+
)
|
305
350
|
|
306
351
|
JSON.parse(response.body).fetch("value").first
|
307
352
|
end
|
@@ -309,19 +354,22 @@ module Dependabot
|
|
309
354
|
|
310
355
|
sig do
|
311
356
|
params(
|
312
|
-
previous_tag: T.nilable(String),
|
357
|
+
previous_tag: T.nilable(String),
|
358
|
+
new_tag: T.nilable(String),
|
313
359
|
type: String
|
314
360
|
)
|
315
361
|
.returns(T::Array[T::Hash[String, T.untyped]])
|
316
362
|
end
|
317
363
|
def compare(previous_tag, new_tag, type)
|
318
|
-
response = get(
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
364
|
+
response = get(
|
365
|
+
T.must(source.api_endpoint) +
|
366
|
+
source.organization + "/" + source.project +
|
367
|
+
"/_apis/git/repositories/" + source.unscoped_repo +
|
368
|
+
"/commits?searchCriteria.itemVersion.versionType=#{type}" \
|
369
|
+
"&searchCriteria.itemVersion.version=#{previous_tag}" \
|
370
|
+
"&searchCriteria.compareVersion.versionType=#{type}" \
|
371
|
+
"&searchCriteria.compareVersion.version=#{new_tag}"
|
372
|
+
)
|
325
373
|
|
326
374
|
JSON.parse(response.body).fetch("value")
|
327
375
|
end
|
@@ -168,8 +168,14 @@ module Dependabot
|
|
168
168
|
)
|
169
169
|
.void
|
170
170
|
end
|
171
|
-
def create_commit(
|
172
|
-
|
171
|
+
def create_commit(
|
172
|
+
repo,
|
173
|
+
branch_name,
|
174
|
+
base_commit,
|
175
|
+
commit_message,
|
176
|
+
files,
|
177
|
+
author_details
|
178
|
+
)
|
173
179
|
parameters = {
|
174
180
|
message: commit_message, # TODO: Format markup in commit message
|
175
181
|
author: "#{author_details.fetch(:name)} <#{author_details.fetch(:email)}>",
|
@@ -201,8 +207,15 @@ module Dependabot
|
|
201
207
|
)
|
202
208
|
.void
|
203
209
|
end
|
204
|
-
def create_pull_request(
|
205
|
-
|
210
|
+
def create_pull_request(
|
211
|
+
repo,
|
212
|
+
pr_name,
|
213
|
+
source_branch,
|
214
|
+
target_branch,
|
215
|
+
pr_description,
|
216
|
+
_labels,
|
217
|
+
_work_item = nil
|
218
|
+
)
|
206
219
|
reviewers = default_reviewers(repo)
|
207
220
|
|
208
221
|
content = {
|
@@ -79,7 +79,8 @@ module Dependabot
|
|
79
79
|
|
80
80
|
sig do
|
81
81
|
params(
|
82
|
-
repo: String,
|
82
|
+
repo: String,
|
83
|
+
commit: T.nilable(String),
|
83
84
|
path: T.nilable(String)
|
84
85
|
)
|
85
86
|
# See PR 9344: should .returns(Seahorse::Client::Response)
|
@@ -112,8 +113,8 @@ module Dependabot
|
|
112
113
|
commit_specifier: commit,
|
113
114
|
file_path: path
|
114
115
|
).file_content
|
115
|
-
|
116
|
-
|
116
|
+
rescue Aws::CodeCommit::Errors::FileDoesNotExistException
|
117
|
+
raise NotFound
|
117
118
|
end
|
118
119
|
|
119
120
|
sig do
|
@@ -253,8 +254,13 @@ module Dependabot
|
|
253
254
|
)
|
254
255
|
.returns(Aws::CodeCommit::Types::CreateCommitOutput)
|
255
256
|
end
|
256
|
-
def create_commit(
|
257
|
-
|
257
|
+
def create_commit(
|
258
|
+
branch_name,
|
259
|
+
author_name,
|
260
|
+
base_commit,
|
261
|
+
commit_message,
|
262
|
+
files
|
263
|
+
)
|
258
264
|
cc_client.create_commit(
|
259
265
|
repository_name: source.unscoped_repo,
|
260
266
|
branch_name: branch_name,
|
@@ -280,8 +286,12 @@ module Dependabot
|
|
280
286
|
)
|
281
287
|
.returns(T.nilable(Aws::CodeCommit::Types::CreatePullRequestOutput))
|
282
288
|
end
|
283
|
-
def create_pull_request(
|
284
|
-
|
289
|
+
def create_pull_request(
|
290
|
+
pr_name,
|
291
|
+
target_branch,
|
292
|
+
source_branch,
|
293
|
+
pr_description
|
294
|
+
)
|
285
295
|
cc_client.create_pull_request(
|
286
296
|
title: pr_name,
|
287
297
|
description: pr_description,
|
@@ -58,34 +58,37 @@ module Dependabot
|
|
58
58
|
|
59
59
|
private
|
60
60
|
|
61
|
-
PACKAGE_MANAGER_LOOKUP = T.let(
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
61
|
+
PACKAGE_MANAGER_LOOKUP = T.let(
|
62
|
+
{
|
63
|
+
"bun" => "bun",
|
64
|
+
"bundler" => "bundler",
|
65
|
+
"cargo" => "cargo",
|
66
|
+
"composer" => "composer",
|
67
|
+
"conda" => "conda",
|
68
|
+
"devcontainer" => "devcontainers",
|
69
|
+
"docker-compose" => "docker_compose",
|
70
|
+
"docker" => "docker",
|
71
|
+
"dotnet-sdk" => "dotnet_sdk",
|
72
|
+
"elm" => "elm",
|
73
|
+
"github-actions" => "github_actions",
|
74
|
+
"gitsubmodule" => "submodules",
|
75
|
+
"gomod" => "go_modules",
|
76
|
+
"gradle" => "gradle",
|
77
|
+
"helm" => "helm",
|
78
|
+
"maven" => "maven",
|
79
|
+
"mix" => "hex",
|
80
|
+
"npm" => "npm_and_yarn",
|
81
|
+
"nuget" => "nuget",
|
82
|
+
"pip" => "pip",
|
83
|
+
"pub" => "pub",
|
84
|
+
"rust-toolchain" => "rust_toolchain",
|
85
|
+
"swift" => "swift",
|
86
|
+
"terraform" => "terraform",
|
87
|
+
"uv" => "uv",
|
88
|
+
"vcpkg" => "vcpkg"
|
89
|
+
}.freeze,
|
90
|
+
T::Hash[String, String]
|
91
|
+
)
|
89
92
|
|
90
93
|
REVERSE_PACKAGE_MANAGER_LOOKUP = T.let(
|
91
94
|
PACKAGE_MANAGER_LOOKUP.invert.freeze,
|
@@ -118,9 +118,18 @@ module Dependabot
|
|
118
118
|
metadata: T.nilable(T::Hash[T.any(Symbol, String), String])
|
119
119
|
).void
|
120
120
|
end
|
121
|
-
def initialize(
|
122
|
-
|
123
|
-
|
121
|
+
def initialize(
|
122
|
+
name:,
|
123
|
+
requirements:,
|
124
|
+
package_manager:,
|
125
|
+
version: nil,
|
126
|
+
previous_version: nil,
|
127
|
+
previous_requirements: nil,
|
128
|
+
directory: nil,
|
129
|
+
subdependency_metadata: [],
|
130
|
+
removed: false,
|
131
|
+
metadata: {}
|
132
|
+
)
|
124
133
|
@name = name
|
125
134
|
@version = T.let(
|
126
135
|
case version
|
@@ -239,6 +248,7 @@ module Dependabot
|
|
239
248
|
sig { returns(T.nilable(String)) }
|
240
249
|
def humanized_version
|
241
250
|
return "removed" if removed?
|
251
|
+
return nil if version.nil?
|
242
252
|
|
243
253
|
if T.must(version).match?(/^[0-9a-f]{40}/)
|
244
254
|
return new_ref if ref_changed? && new_ref
|
@@ -399,10 +409,11 @@ module Dependabot
|
|
399
409
|
optional_keys = %i(metadata)
|
400
410
|
unless requirement_fields.flatten
|
401
411
|
.all? { |r| required_keys.sort == (r.keys - optional_keys).sort }
|
402
|
-
raise ArgumentError,
|
403
|
-
|
404
|
-
|
405
|
-
|
412
|
+
raise ArgumentError,
|
413
|
+
"each requirement must have the following " \
|
414
|
+
"required keys: #{required_keys.join(', ')}." \
|
415
|
+
"Optionally, it may have the following keys: " \
|
416
|
+
"#{optional_keys.join(', ')}."
|
406
417
|
end
|
407
418
|
|
408
419
|
return if requirement_fields.flatten.none? { |r| r[:requirement] == "" }
|
@@ -60,8 +60,10 @@ module Dependabot
|
|
60
60
|
end
|
61
61
|
|
62
62
|
# See https://github.com/git/git/blob/a36e024e989f4d35f35987a60e3af8022cac3420/object.h#L144-L153
|
63
|
-
VALID_MODES = T.let(
|
64
|
-
|
63
|
+
VALID_MODES = T.let(
|
64
|
+
[Mode::FILE, Mode::EXECUTABLE, Mode::TREE, Mode::SUBMODULE, Mode::SYMLINK].freeze,
|
65
|
+
T::Array[String]
|
66
|
+
)
|
65
67
|
|
66
68
|
sig do
|
67
69
|
params(
|
@@ -79,10 +81,19 @@ module Dependabot
|
|
79
81
|
)
|
80
82
|
.void
|
81
83
|
end
|
82
|
-
def initialize(
|
83
|
-
|
84
|
-
|
85
|
-
|
84
|
+
def initialize(
|
85
|
+
name:,
|
86
|
+
content:,
|
87
|
+
directory: "/",
|
88
|
+
type: "file",
|
89
|
+
support_file: false,
|
90
|
+
vendored_file: false,
|
91
|
+
symlink_target: nil,
|
92
|
+
content_encoding: ContentEncoding::UTF_8,
|
93
|
+
deleted: false,
|
94
|
+
operation: Operation::UPDATE,
|
95
|
+
mode: nil
|
96
|
+
)
|
86
97
|
@name = name
|
87
98
|
@content = content
|
88
99
|
@directory = T.let(clean_directory(directory), String)
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# Dependency Graphers
|
2
|
+
|
3
|
+
Dependency graphers are used to convert a set of parsed dependencies into a data structure we can use to output the dependency graph of a project in a generic data structure based on GitHub's [Dependency submission API](https://docs.github.com/en/rest/dependency-graph/dependency-submission).
|
4
|
+
|
5
|
+
We will expect each language Dependabot supports to implement a `Dependabot::DependencyGraphers` class in future, but for now any modules that do not implement a specific class fail over to a 'best effort' generic implementation that works in most cases.
|
6
|
+
|
7
|
+
## Public API
|
8
|
+
|
9
|
+
Each `Dependabot::DependencyGraphers` class implements the following methods:
|
10
|
+
|
11
|
+
| Method | Description |
|
12
|
+
|-----------------------------|-----------------------------------------------------------------------------------------------|
|
13
|
+
| `.relevant_dependency_file` | Checks the list of `Dependabot::DependencyFile` objects assigned and determines which one the dependency list should be reported against. In most languages this will be the lockfile, if present, and the manifest otherwise. |
|
14
|
+
| `.resolved_dependencies` | Processes the assigned `Dependabot::Dependency` objects into an informational hash |
|
15
|
+
|
16
|
+
An example of a `.resolved_dependencies` hash for a Bundler project:
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
"addressable": {
|
20
|
+
"package_url": "pkg:gem/addressable@2.8.6",
|
21
|
+
"relationship": "indirect",
|
22
|
+
"scope": "runtime",
|
23
|
+
"dependencies": [],
|
24
|
+
"metadata": {}
|
25
|
+
},
|
26
|
+
"ast": {
|
27
|
+
"package_url": "pkg:gem/ast@2.4.2",
|
28
|
+
"relationship": "indirect",
|
29
|
+
"scope": "runtime",
|
30
|
+
"dependencies": [],
|
31
|
+
"metadata": {}
|
32
|
+
},
|
33
|
+
"aws-eventstream": {
|
34
|
+
"package_url": "pkg:gem/aws-eventstream@1.3.0",
|
35
|
+
"relationship": "indirect",
|
36
|
+
"scope": "runtime",
|
37
|
+
"dependencies": [],
|
38
|
+
"metadata": {}
|
39
|
+
}
|
40
|
+
```
|
41
|
+
|
42
|
+
## Writing a file fetcher for a new language
|
43
|
+
|
44
|
+
All new file fetchers should inherit from `Dependabot::DependencyGraphers::Base` and
|
45
|
+
implement the following methods:
|
46
|
+
|
47
|
+
| Method | Description |
|
48
|
+
|----------------------------------|-----------------------------------------------------------------------------------------------|
|
49
|
+
| `.relevant_dependency_file` | See Public API section. |
|
50
|
+
| `.fetch_subdependencies` | Private method to fetch a list of package names, or PURLs, that are subdependencies of a given `Dependabot::Dependency`. It is expected that some languages will need to perform additional native commands to obtain this data. |
|
51
|
+
| `.purl_pkg_for` | Private method to map the given `Dependabot::Dependency` to the correct [Package-URL type](https://github.com/package-url/purl-spec/blob/main/PURL-TYPES.rst) for the package manager involved. |
|
52
|
+
|
53
|
+
> [!WARNING]
|
54
|
+
> While PURLs are preferred in all languages for `.fetch_subdependencies`, for languages where multiple versions of a single dependency are permitted they _must_ be provided to be precise.
|