dependabot-common 0.391.0 → 0.393.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 +42 -22
- data/lib/dependabot/clients/bitbucket.rb +52 -26
- data/lib/dependabot/clients/bitbucket_with_retries.rb +11 -12
- data/lib/dependabot/clients/codecommit.rb +73 -53
- data/lib/dependabot/clients/github_resource_parser.rb +70 -0
- data/lib/dependabot/clients/github_with_retries.rb +63 -23
- data/lib/dependabot/clients/gitlab_with_retries.rb +19 -17
- data/lib/dependabot/clients/json_response_parser.rb +103 -0
- data/lib/dependabot/command_helpers.rb +89 -13
- data/lib/dependabot/credential.rb +12 -3
- data/lib/dependabot/dependency_requirement.rb +28 -15
- data/lib/dependabot/errors.rb +7 -0
- data/lib/dependabot/file_fetchers/base.rb +196 -140
- data/lib/dependabot/file_updaters/vendor_updater.rb +8 -2
- data/lib/dependabot/git_tag_details.rb +8 -14
- data/lib/dependabot/metadata_finders/base/changelog_finder.rb +211 -110
- data/lib/dependabot/metadata_finders/base/commit_response_parser.rb +68 -0
- data/lib/dependabot/metadata_finders/base/commits_finder.rb +44 -38
- data/lib/dependabot/pull_request_creator/azure.rb +1 -1
- data/lib/dependabot/pull_request_creator/branch_name_template.rb +1 -1
- data/lib/dependabot/pull_request_creator/codecommit.rb +10 -12
- data/lib/dependabot/pull_request_creator/github.rb +55 -35
- data/lib/dependabot/pull_request_creator/gitlab.rb +37 -11
- data/lib/dependabot/pull_request_creator/labeler.rb +65 -15
- 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/pull_request_creator/pr_name_prefixer.rb +179 -78
- data/lib/dependabot/pull_request_updater/azure.rb +63 -11
- data/lib/dependabot/pull_request_updater/github.rb +44 -34
- data/lib/dependabot/pull_request_updater/gitlab.rb +23 -12
- data/lib/dependabot/pull_request_updater.rb +3 -3
- data/lib/dependabot/shared_helpers.rb +107 -39
- data/lib/dependabot/update_checkers/base.rb +9 -5
- data/lib/dependabot/update_checkers/version_filters.rb +5 -0
- data/lib/dependabot/update_checkers/vulnerability_audit.rb +282 -0
- data/lib/dependabot/workspace/git.rb +36 -5
- data/lib/dependabot.rb +1 -1
- metadata +6 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# typed:
|
|
1
|
+
# typed: strong
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
require "sorbet-runtime"
|
|
@@ -19,40 +19,26 @@ require "dependabot/shared_helpers"
|
|
|
19
19
|
# rubocop:disable Metrics/ClassLength
|
|
20
20
|
module Dependabot
|
|
21
21
|
module FileFetchers
|
|
22
|
-
class RepositoryContent
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
attr_reader :path
|
|
30
|
-
|
|
31
|
-
sig { returns(T.nilable(String)) }
|
|
32
|
-
attr_reader :type
|
|
33
|
-
|
|
34
|
-
sig { returns(T.nilable(Integer)) }
|
|
35
|
-
attr_reader :size
|
|
22
|
+
class RepositoryContent < T::ImmutableStruct
|
|
23
|
+
const :name, String
|
|
24
|
+
const :path, String
|
|
25
|
+
const :type, String
|
|
26
|
+
const :size, Integer
|
|
27
|
+
const :sha, T.nilable(String), default: nil
|
|
28
|
+
end
|
|
36
29
|
|
|
37
|
-
|
|
38
|
-
|
|
30
|
+
class LinkedPath < T::ImmutableStruct
|
|
31
|
+
const :repo, String
|
|
32
|
+
const :provider, String
|
|
33
|
+
const :commit, String
|
|
34
|
+
const :path, String
|
|
35
|
+
end
|
|
39
36
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
size: T.nilable(Integer),
|
|
46
|
-
sha: T.nilable(String)
|
|
47
|
-
).void
|
|
48
|
-
end
|
|
49
|
-
def initialize(name: nil, path: nil, type: nil, size: nil, sha: nil)
|
|
50
|
-
@name = name
|
|
51
|
-
@path = path
|
|
52
|
-
@type = type
|
|
53
|
-
@size = size
|
|
54
|
-
@sha = sha
|
|
55
|
-
end
|
|
37
|
+
class RepositorySpecification < T::ImmutableStruct
|
|
38
|
+
const :provider, String
|
|
39
|
+
const :repo, String
|
|
40
|
+
const :path, String
|
|
41
|
+
const :commit, String
|
|
56
42
|
end
|
|
57
43
|
|
|
58
44
|
class Base
|
|
@@ -146,8 +132,9 @@ module Dependabot
|
|
|
146
132
|
@repo_contents_path = repo_contents_path
|
|
147
133
|
@update_config = T.let(update_config, T.nilable(Dependabot::Config::UpdateConfig))
|
|
148
134
|
@exclude_paths = T.let(update_config&.exclude_paths || [], T::Array[String])
|
|
149
|
-
@linked_paths = T.let({}, T::Hash[
|
|
150
|
-
@submodules = T.let([], T::Array[
|
|
135
|
+
@linked_paths = T.let({}, T::Hash[String, LinkedPath])
|
|
136
|
+
@submodules = T.let([], T::Array[String])
|
|
137
|
+
@repo_contents = T.let(nil, T.nilable(T::Hash[String, T::Array[RepositoryContent]]))
|
|
151
138
|
@options = options
|
|
152
139
|
|
|
153
140
|
@files = T.let([], T::Array[DependencyFile])
|
|
@@ -202,7 +189,7 @@ module Dependabot
|
|
|
202
189
|
|
|
203
190
|
branch = target_branch || default_branch_for_repo
|
|
204
191
|
|
|
205
|
-
@commit ||= T.let(
|
|
192
|
+
@commit ||= T.let(fetch_commit_for_provider(repo, branch), T.nilable(String))
|
|
206
193
|
rescue *CLIENT_NOT_FOUND_ERRORS
|
|
207
194
|
raise Dependabot::BranchNotFound, branch
|
|
208
195
|
rescue Octokit::Conflict => e
|
|
@@ -226,7 +213,7 @@ module Dependabot
|
|
|
226
213
|
raise Dependabot::RepoNotFound.new(source, e.message)
|
|
227
214
|
end
|
|
228
215
|
|
|
229
|
-
sig { overridable.returns(T.nilable(T::Hash[Symbol, T.
|
|
216
|
+
sig { overridable.returns(T.nilable(T::Hash[Symbol, T.anything])) }
|
|
230
217
|
def ecosystem_versions; end
|
|
231
218
|
|
|
232
219
|
sig { abstract.returns(T::Array[DependencyFile]) }
|
|
@@ -236,7 +223,9 @@ module Dependabot
|
|
|
236
223
|
|
|
237
224
|
sig { params(name: String).returns(T.nilable(Dependabot::DependencyFile)) }
|
|
238
225
|
def fetch_support_file(name)
|
|
239
|
-
fetch_file_if_present(name)
|
|
226
|
+
file = fetch_file_if_present(name)
|
|
227
|
+
file.support_file = true if file
|
|
228
|
+
file
|
|
240
229
|
end
|
|
241
230
|
|
|
242
231
|
sig { params(filename: String, fetch_submodules: T::Boolean).returns(T.nilable(DependencyFile)) }
|
|
@@ -304,7 +293,10 @@ module Dependabot
|
|
|
304
293
|
|
|
305
294
|
linked_path = symlinked_subpath(clean_path)
|
|
306
295
|
type = "symlink" if linked_path
|
|
307
|
-
|
|
296
|
+
if type == "symlink"
|
|
297
|
+
linked_path_details = T.must(@linked_paths[T.must(linked_path)])
|
|
298
|
+
symlink_target = clean_path.sub(T.must(linked_path), linked_path_details.path)
|
|
299
|
+
end
|
|
308
300
|
|
|
309
301
|
DependencyFile.new(
|
|
310
302
|
name: Pathname.new(filename).cleanpath.to_path,
|
|
@@ -342,7 +334,7 @@ module Dependabot
|
|
|
342
334
|
raise_errors: T::Boolean,
|
|
343
335
|
fetch_submodules: T::Boolean
|
|
344
336
|
)
|
|
345
|
-
.returns(T::Array[
|
|
337
|
+
.returns(T::Array[RepositoryContent])
|
|
346
338
|
end
|
|
347
339
|
def repo_contents(
|
|
348
340
|
dir: ".",
|
|
@@ -353,7 +345,7 @@ module Dependabot
|
|
|
353
345
|
dir = File.join(directory, dir) unless ignore_base_directory
|
|
354
346
|
path = Pathname.new(dir).cleanpath.to_path.gsub(%r{^/*}, "")
|
|
355
347
|
|
|
356
|
-
@repo_contents ||=
|
|
348
|
+
@repo_contents ||= {}
|
|
357
349
|
@repo_contents[dir.to_s] ||= if repo_contents_path
|
|
358
350
|
_cloned_repo_contents(path)
|
|
359
351
|
else
|
|
@@ -378,7 +370,7 @@ module Dependabot
|
|
|
378
370
|
|
|
379
371
|
sig { returns(String) }
|
|
380
372
|
def default_branch_for_repo
|
|
381
|
-
@default_branch_for_repo ||= T.let(
|
|
373
|
+
@default_branch_for_repo ||= T.let(fetch_default_branch_for_provider(repo), T.nilable(String))
|
|
382
374
|
rescue *CLIENT_NOT_FOUND_ERRORS
|
|
383
375
|
raise Dependabot::RepoNotFound, source
|
|
384
376
|
end
|
|
@@ -390,49 +382,54 @@ module Dependabot
|
|
|
390
382
|
commit: String,
|
|
391
383
|
github_response: Sawyer::Resource
|
|
392
384
|
)
|
|
393
|
-
.returns(T.nilable(
|
|
385
|
+
.returns(T.nilable(LinkedPath))
|
|
394
386
|
end
|
|
395
387
|
def update_linked_paths(repo, path, commit, github_response)
|
|
396
|
-
case github_response
|
|
388
|
+
case sawyer_string(github_response, :type)
|
|
397
389
|
when "submodule"
|
|
398
|
-
|
|
390
|
+
submodule_url = sawyer_optional_string(github_response, :submodule_git_url)
|
|
391
|
+
return unless submodule_url
|
|
392
|
+
|
|
393
|
+
sub_source = Source.from_url(submodule_url)
|
|
399
394
|
return unless sub_source
|
|
400
395
|
|
|
401
|
-
@linked_paths[path] =
|
|
396
|
+
@linked_paths[path] = LinkedPath.new(
|
|
402
397
|
repo: sub_source.repo,
|
|
403
398
|
provider: sub_source.provider,
|
|
404
|
-
commit: github_response
|
|
399
|
+
commit: sawyer_string(github_response, :sha),
|
|
405
400
|
path: "/"
|
|
406
|
-
|
|
401
|
+
)
|
|
407
402
|
when "symlink"
|
|
408
|
-
updated_path = File.join(File.dirname(path), github_response
|
|
409
|
-
@linked_paths[path] =
|
|
403
|
+
updated_path = File.join(File.dirname(path), sawyer_string(github_response, :target))
|
|
404
|
+
@linked_paths[path] = LinkedPath.new(
|
|
410
405
|
repo: repo,
|
|
411
406
|
provider: "github",
|
|
412
407
|
commit: commit,
|
|
413
408
|
path: Pathname.new(updated_path).cleanpath.to_path
|
|
414
|
-
|
|
409
|
+
)
|
|
415
410
|
end
|
|
416
411
|
end
|
|
417
412
|
|
|
418
|
-
sig
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
413
|
+
sig { params(repo: String, branch: String).returns(String) }
|
|
414
|
+
def fetch_commit_for_provider(repo, branch)
|
|
415
|
+
case source.provider
|
|
416
|
+
when "github" then github_client.fetch_commit(repo, branch)
|
|
417
|
+
when "gitlab" then gitlab_client.fetch_commit(repo, branch)
|
|
418
|
+
when "azure" then azure_client.fetch_commit(repo, branch)
|
|
419
|
+
when "bitbucket" then bitbucket_client.fetch_commit(repo, branch)
|
|
420
|
+
when "codecommit" then codecommit_client.fetch_commit(repo, branch)
|
|
421
|
+
else raise "Unsupported provider '#{source.provider}'."
|
|
422
|
+
end
|
|
428
423
|
end
|
|
429
|
-
|
|
424
|
+
|
|
425
|
+
sig { params(repo: String).returns(String) }
|
|
426
|
+
def fetch_default_branch_for_provider(repo)
|
|
430
427
|
case source.provider
|
|
431
|
-
when "github" then github_client
|
|
432
|
-
when "gitlab" then gitlab_client
|
|
433
|
-
when "azure" then azure_client
|
|
434
|
-
when "bitbucket" then bitbucket_client
|
|
435
|
-
when "codecommit" then codecommit_client
|
|
428
|
+
when "github" then github_client.fetch_default_branch(repo)
|
|
429
|
+
when "gitlab" then gitlab_client.fetch_default_branch(repo)
|
|
430
|
+
when "azure" then azure_client.fetch_default_branch(repo)
|
|
431
|
+
when "bitbucket" then bitbucket_client.fetch_default_branch(repo)
|
|
432
|
+
when "codecommit" then codecommit_client.fetch_default_branch(repo)
|
|
436
433
|
else raise "Unsupported provider '#{source.provider}'."
|
|
437
434
|
end
|
|
438
435
|
end
|
|
@@ -508,9 +505,11 @@ module Dependabot
|
|
|
508
505
|
end
|
|
509
506
|
def _fetch_repo_contents(path, fetch_submodules: false, raise_errors: true) # rubocop:disable Metrics/PerceivedComplexity
|
|
510
507
|
path = path.gsub(" ", "%20")
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
508
|
+
specification = _full_specification_for(path, fetch_submodules: fetch_submodules)
|
|
509
|
+
provider = specification.provider
|
|
510
|
+
repo = specification.repo
|
|
511
|
+
tmp_path = specification.path
|
|
512
|
+
commit = specification.commit
|
|
514
513
|
|
|
515
514
|
entries = _fetch_repo_contents_fully_specified(provider, repo, tmp_path, commit)
|
|
516
515
|
if Dependabot::Experiments.enabled?(:enable_exclude_paths_subdirectory_manifest_files)
|
|
@@ -529,7 +528,7 @@ module Dependabot
|
|
|
529
528
|
# a retry to get its contents.
|
|
530
529
|
updated_path =
|
|
531
530
|
_full_specification_for(path, fetch_submodules: fetch_submodules)
|
|
532
|
-
.
|
|
531
|
+
.path
|
|
533
532
|
retry if updated_path != tmp_path
|
|
534
533
|
|
|
535
534
|
return result.call unless fetch_submodules && !retrying
|
|
@@ -566,8 +565,8 @@ module Dependabot
|
|
|
566
565
|
path = path.gsub(" ", "%20")
|
|
567
566
|
github_response = github_client.contents(repo, path: path, ref: commit)
|
|
568
567
|
|
|
569
|
-
if github_response.
|
|
570
|
-
update_linked_paths(repo, path, commit,
|
|
568
|
+
if github_response.is_a?(Sawyer::Resource)
|
|
569
|
+
update_linked_paths(repo, path, commit, github_response)
|
|
571
570
|
raise Octokit::NotFound
|
|
572
571
|
end
|
|
573
572
|
|
|
@@ -606,7 +605,7 @@ module Dependabot
|
|
|
606
605
|
end
|
|
607
606
|
|
|
608
607
|
# Filters out any entries whose paths match one of the exclude_paths globs.
|
|
609
|
-
sig { params(entries: T::Array[
|
|
608
|
+
sig { params(entries: T::Array[RepositoryContent]).returns(T::Array[RepositoryContent]) }
|
|
610
609
|
def filter_excluded(entries)
|
|
611
610
|
Dependabot.logger.info("DEBUG filter_excluded: entries=#{entries.length}, exclude_paths=#{@exclude_paths.inspect}") # rubocop:disable Layout/LineLength
|
|
612
611
|
|
|
@@ -628,33 +627,76 @@ module Dependabot
|
|
|
628
627
|
|
|
629
628
|
sig { params(file: Sawyer::Resource).returns(RepositoryContent) }
|
|
630
629
|
def _build_github_file_struct(file)
|
|
630
|
+
name = sawyer_string(file, :name)
|
|
631
631
|
RepositoryContent.new(
|
|
632
|
-
name:
|
|
633
|
-
path: file
|
|
634
|
-
type: file
|
|
635
|
-
sha: file
|
|
636
|
-
size: file
|
|
632
|
+
name: name,
|
|
633
|
+
path: sawyer_optional_string(file, :path) || name,
|
|
634
|
+
type: sawyer_optional_string(file, :type) || "",
|
|
635
|
+
sha: sawyer_optional_string(file, :sha),
|
|
636
|
+
size: sawyer_optional_integer(file, :size) || 0
|
|
637
|
+
)
|
|
638
|
+
end
|
|
639
|
+
|
|
640
|
+
sig { params(resource: Sawyer::Resource, key: Symbol).returns(String) }
|
|
641
|
+
def sawyer_string(resource, key)
|
|
642
|
+
value = T.cast(resource[key], Object)
|
|
643
|
+
return value if value.is_a?(String)
|
|
644
|
+
|
|
645
|
+
raise_bad_repository_response("GitHub", "#{key} must be a string")
|
|
646
|
+
end
|
|
647
|
+
|
|
648
|
+
sig { params(resource: Sawyer::Resource, key: Symbol).returns(T.nilable(String)) }
|
|
649
|
+
def sawyer_optional_string(resource, key)
|
|
650
|
+
value = T.cast(resource[key], Object)
|
|
651
|
+
return if value.nil?
|
|
652
|
+
return value if value.is_a?(String)
|
|
653
|
+
|
|
654
|
+
raise_bad_repository_response("GitHub", "#{key} must be a string or nil")
|
|
655
|
+
end
|
|
656
|
+
|
|
657
|
+
sig { params(resource: Sawyer::Resource, key: Symbol).returns(T.nilable(Integer)) }
|
|
658
|
+
def sawyer_optional_integer(resource, key)
|
|
659
|
+
value = T.cast(resource[key], Object)
|
|
660
|
+
return if value.nil?
|
|
661
|
+
return value if value.is_a?(Integer)
|
|
662
|
+
|
|
663
|
+
raise_bad_repository_response("GitHub", "#{key} must be an integer or nil")
|
|
664
|
+
end
|
|
665
|
+
|
|
666
|
+
sig { params(resource: Gitlab::ObjectifiedHash, key: String).returns(String) }
|
|
667
|
+
def gitlab_string(resource, key)
|
|
668
|
+
value = T.cast(resource[key], Object)
|
|
669
|
+
return value if value.is_a?(String)
|
|
670
|
+
|
|
671
|
+
raise_bad_repository_response("GitLab", "#{key} must be a string")
|
|
672
|
+
end
|
|
673
|
+
|
|
674
|
+
sig { params(provider: String, message: String).returns(T.noreturn) }
|
|
675
|
+
def raise_bad_repository_response(provider, message)
|
|
676
|
+
raise Dependabot::PrivateSourceBadResponse.new(
|
|
677
|
+
source.url,
|
|
678
|
+
"Malformed #{provider} repository response: #{message}"
|
|
637
679
|
)
|
|
638
680
|
end
|
|
639
681
|
|
|
640
682
|
sig { params(repo: String, path: String, commit: String).returns(T::Array[RepositoryContent]) }
|
|
641
683
|
def _gitlab_repo_contents(repo, path, commit)
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
684
|
+
gitlab_client
|
|
685
|
+
.repo_tree(repo, path: path, ref: commit, per_page: 100)
|
|
686
|
+
.map do |raw_file|
|
|
687
|
+
file = raw_file
|
|
688
|
+
object_type = gitlab_string(file, "type")
|
|
647
689
|
# GitLab API essentially returns the output from `git ls-tree`
|
|
648
|
-
type = case
|
|
690
|
+
type = case object_type
|
|
649
691
|
when "blob" then "file"
|
|
650
692
|
when "tree" then "dir"
|
|
651
693
|
when "commit" then "submodule"
|
|
652
|
-
else
|
|
694
|
+
else object_type
|
|
653
695
|
end
|
|
654
696
|
|
|
655
697
|
RepositoryContent.new(
|
|
656
|
-
name: file
|
|
657
|
-
path: file
|
|
698
|
+
name: gitlab_string(file, "name"),
|
|
699
|
+
path: gitlab_string(file, "path"),
|
|
658
700
|
type: type,
|
|
659
701
|
size: 0 # GitLab doesn't return file size
|
|
660
702
|
)
|
|
@@ -666,17 +708,19 @@ module Dependabot
|
|
|
666
708
|
response = azure_client.fetch_repo_contents(commit, path)
|
|
667
709
|
|
|
668
710
|
response.map do |entry|
|
|
669
|
-
|
|
711
|
+
object_type = T.cast(entry.fetch("gitObjectType"), String)
|
|
712
|
+
relative_path = T.cast(entry.fetch("relativePath"), String)
|
|
713
|
+
type = case object_type
|
|
670
714
|
when "blob" then "file"
|
|
671
715
|
when "tree" then "dir"
|
|
672
|
-
else
|
|
716
|
+
else object_type
|
|
673
717
|
end
|
|
674
718
|
|
|
675
719
|
RepositoryContent.new(
|
|
676
|
-
name: File.basename(
|
|
677
|
-
path:
|
|
720
|
+
name: File.basename(relative_path),
|
|
721
|
+
path: relative_path,
|
|
678
722
|
type: type,
|
|
679
|
-
size: entry.fetch("size")
|
|
723
|
+
size: T.cast(entry.fetch("size"), Integer)
|
|
680
724
|
)
|
|
681
725
|
end
|
|
682
726
|
end
|
|
@@ -691,17 +735,19 @@ module Dependabot
|
|
|
691
735
|
)
|
|
692
736
|
|
|
693
737
|
response.map do |file|
|
|
694
|
-
|
|
738
|
+
object_type = T.cast(file.fetch("type"), String)
|
|
739
|
+
path = T.cast(file.fetch("path"), String)
|
|
740
|
+
type = case object_type
|
|
695
741
|
when "commit_file" then "file"
|
|
696
742
|
when "commit_directory" then "dir"
|
|
697
|
-
else
|
|
743
|
+
else object_type
|
|
698
744
|
end
|
|
699
745
|
|
|
700
746
|
RepositoryContent.new(
|
|
701
|
-
name: File.basename(
|
|
702
|
-
path:
|
|
747
|
+
name: File.basename(path),
|
|
748
|
+
path: path,
|
|
703
749
|
type: type,
|
|
704
|
-
size: file.fetch("size", 0)
|
|
750
|
+
size: T.cast(file.fetch("size", 0), Integer)
|
|
705
751
|
)
|
|
706
752
|
end
|
|
707
753
|
end
|
|
@@ -714,7 +760,8 @@ module Dependabot
|
|
|
714
760
|
path
|
|
715
761
|
)
|
|
716
762
|
|
|
717
|
-
response.
|
|
763
|
+
output = T.cast(response.data, Aws::CodeCommit::Types::GetFolderOutput)
|
|
764
|
+
output.files.map do |file|
|
|
718
765
|
RepositoryContent.new(
|
|
719
766
|
name: File.basename(file.relative_path),
|
|
720
767
|
path: file.relative_path,
|
|
@@ -724,29 +771,32 @@ module Dependabot
|
|
|
724
771
|
end
|
|
725
772
|
end
|
|
726
773
|
|
|
727
|
-
sig { params(path: String, fetch_submodules: T::Boolean).returns(
|
|
774
|
+
sig { params(path: String, fetch_submodules: T::Boolean).returns(RepositorySpecification) }
|
|
728
775
|
def _full_specification_for(path, fetch_submodules:)
|
|
729
776
|
if fetch_submodules && _linked_dir_for(path)
|
|
730
|
-
linked_dir_details = @linked_paths[_linked_dir_for(path)]
|
|
777
|
+
linked_dir_details = T.must(@linked_paths[T.must(_linked_dir_for(path))])
|
|
731
778
|
sub_path =
|
|
732
779
|
path.gsub(%r{^#{Regexp.quote(T.must(_linked_dir_for(path)))}(/|$)}, "")
|
|
733
780
|
new_path =
|
|
734
|
-
Pathname.new(File.join(linked_dir_details.
|
|
781
|
+
Pathname.new(File.join(linked_dir_details.path, sub_path))
|
|
735
782
|
.cleanpath.to_path
|
|
736
783
|
.gsub(%r{^/}, "")
|
|
737
|
-
|
|
738
|
-
repo: linked_dir_details.
|
|
739
|
-
commit: linked_dir_details.
|
|
740
|
-
provider: linked_dir_details.
|
|
784
|
+
RepositorySpecification.new(
|
|
785
|
+
repo: linked_dir_details.repo,
|
|
786
|
+
commit: linked_dir_details.commit,
|
|
787
|
+
provider: linked_dir_details.provider,
|
|
741
788
|
path: new_path
|
|
742
|
-
|
|
789
|
+
)
|
|
743
790
|
else
|
|
744
|
-
|
|
791
|
+
resolved_commit = commit
|
|
792
|
+
raise Octokit::NotFound unless resolved_commit
|
|
793
|
+
|
|
794
|
+
RepositorySpecification.new(
|
|
745
795
|
repo: source.repo,
|
|
746
796
|
path: path,
|
|
747
|
-
commit:
|
|
797
|
+
commit: resolved_commit,
|
|
748
798
|
provider: source.provider
|
|
749
|
-
|
|
799
|
+
)
|
|
750
800
|
end
|
|
751
801
|
end
|
|
752
802
|
|
|
@@ -754,9 +804,11 @@ module Dependabot
|
|
|
754
804
|
def _fetch_file_content(path, fetch_submodules: false)
|
|
755
805
|
path = path.gsub(%r{^/*}, "")
|
|
756
806
|
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
807
|
+
specification = _full_specification_for(path, fetch_submodules: fetch_submodules)
|
|
808
|
+
provider = specification.provider
|
|
809
|
+
repo = specification.repo
|
|
810
|
+
path = specification.path
|
|
811
|
+
commit = specification.commit
|
|
760
812
|
|
|
761
813
|
_fetch_file_content_fully_specified(provider, repo, path, commit)
|
|
762
814
|
rescue *CLIENT_NOT_FOUND_ERRORS
|
|
@@ -777,7 +829,7 @@ module Dependabot
|
|
|
777
829
|
when "github"
|
|
778
830
|
_fetch_file_content_from_github(path, repo, commit)
|
|
779
831
|
when "gitlab"
|
|
780
|
-
tmp =
|
|
832
|
+
tmp = gitlab_string(gitlab_client.get_file(repo, path, commit), "content")
|
|
781
833
|
decode_binary_string(tmp)
|
|
782
834
|
when "azure"
|
|
783
835
|
azure_client.fetch_file_contents(commit, path)
|
|
@@ -789,33 +841,17 @@ module Dependabot
|
|
|
789
841
|
end
|
|
790
842
|
end
|
|
791
843
|
|
|
792
|
-
# rubocop:disable Metrics/AbcSize
|
|
793
844
|
sig { params(path: String, repo: String, commit: String).returns(String) }
|
|
794
845
|
def _fetch_file_content_from_github(path, repo, commit)
|
|
795
|
-
tmp =
|
|
796
|
-
|
|
797
|
-
raise Octokit::NotFound if tmp.is_a?(Array)
|
|
846
|
+
tmp = github_file_resource(path, repo, commit)
|
|
798
847
|
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
repo: repo,
|
|
802
|
-
provider: "github",
|
|
803
|
-
commit: commit,
|
|
804
|
-
path: Pathname.new(T.unsafe(tmp).target).cleanpath.to_path
|
|
805
|
-
}
|
|
806
|
-
tmp = github_client.contents(
|
|
807
|
-
repo,
|
|
808
|
-
path: Pathname.new(T.unsafe(tmp).target).cleanpath.to_path,
|
|
809
|
-
ref: commit
|
|
810
|
-
)
|
|
811
|
-
end
|
|
812
|
-
|
|
813
|
-
if T.unsafe(tmp).content == ""
|
|
848
|
+
content = sawyer_string(tmp, :content)
|
|
849
|
+
if content == ""
|
|
814
850
|
# The file may have exceeded the 1MB limit
|
|
815
851
|
# see https://github.blog/changelog/2022-05-03-increased-file-size-limit-when-retrieving-file-contents-via-rest-api/
|
|
816
|
-
|
|
852
|
+
github_client.raw_contents(repo, path: path, ref: commit)
|
|
817
853
|
else
|
|
818
|
-
decode_binary_string(
|
|
854
|
+
decode_binary_string(content)
|
|
819
855
|
end
|
|
820
856
|
rescue Octokit::Forbidden => e
|
|
821
857
|
raise unless e.message.include?("too_large")
|
|
@@ -827,17 +863,37 @@ module Dependabot
|
|
|
827
863
|
file_details = repo_contents(dir: dir).find { |f| f.name == basename }
|
|
828
864
|
raise unless file_details
|
|
829
865
|
|
|
830
|
-
tmp = github_client.blob(repo, file_details.sha)
|
|
831
|
-
|
|
866
|
+
tmp = github_client.blob(repo, T.must(file_details.sha))
|
|
867
|
+
content = sawyer_string(tmp, :content)
|
|
868
|
+
return content if sawyer_string(tmp, :encoding) == "utf-8"
|
|
832
869
|
|
|
833
|
-
decode_binary_string(
|
|
870
|
+
decode_binary_string(content)
|
|
871
|
+
end
|
|
872
|
+
sig { params(path: String, repo: String, commit: String).returns(Sawyer::Resource) }
|
|
873
|
+
def github_file_resource(path, repo, commit)
|
|
874
|
+
resource = github_client.contents(repo, path: path, ref: commit)
|
|
875
|
+
raise Octokit::NotFound if resource.is_a?(Array)
|
|
876
|
+
return resource unless sawyer_optional_string(resource, :type) == "symlink"
|
|
877
|
+
|
|
878
|
+
target = sawyer_string(resource, :target)
|
|
879
|
+
clean_target = Pathname.new(target).cleanpath.to_path
|
|
880
|
+
@linked_paths[path] = LinkedPath.new(
|
|
881
|
+
repo: repo,
|
|
882
|
+
provider: "github",
|
|
883
|
+
commit: commit,
|
|
884
|
+
path: clean_target
|
|
885
|
+
)
|
|
886
|
+
|
|
887
|
+
target_resource = github_client.contents(repo, path: clean_target, ref: commit)
|
|
888
|
+
return target_resource if target_resource.is_a?(Sawyer::Resource)
|
|
889
|
+
|
|
890
|
+
raise_bad_repository_response("GitHub", "symlink target must be a file")
|
|
834
891
|
end
|
|
835
|
-
# rubocop:enable Metrics/AbcSize
|
|
836
892
|
|
|
837
893
|
# Update the @linked_paths hash by exploiting a side-effect of
|
|
838
894
|
# recursively calling `repo_contents` for each directory up the tree
|
|
839
895
|
# until a submodule or symlink is found
|
|
840
|
-
sig { params(path: String).returns(T.nilable(T::Array[
|
|
896
|
+
sig { params(path: String).returns(T.nilable(T::Array[RepositoryContent])) }
|
|
841
897
|
def _find_linked_dirs(path)
|
|
842
898
|
path = Pathname.new(path).cleanpath.to_path.gsub(%r{^/*}, "")
|
|
843
899
|
dir = File.dirname(path)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# typed:
|
|
1
|
+
# typed: strong
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
require "sorbet-runtime"
|
|
@@ -27,7 +27,13 @@ module Dependabot
|
|
|
27
27
|
super(repo_contents_path: @repo_contents_path, target_directory: @vendor_dir)
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
sig do
|
|
31
|
+
params(base_directory: String, only_paths: T.nilable(T::Array[String]))
|
|
32
|
+
.returns(T::Array[Dependabot::DependencyFile])
|
|
33
|
+
end
|
|
34
|
+
def updated_vendor_cache_files(base_directory:, only_paths: nil)
|
|
35
|
+
updated_files(base_directory: base_directory, only_paths: only_paths)
|
|
36
|
+
end
|
|
31
37
|
|
|
32
38
|
private
|
|
33
39
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# typed:
|
|
1
|
+
# typed: strong
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
require "sorbet-runtime"
|
|
@@ -18,22 +18,16 @@ module Dependabot
|
|
|
18
18
|
# release date for cooldown handling.
|
|
19
19
|
#
|
|
20
20
|
# Subclasses Hash so it is a drop-in replacement at the many call sites that
|
|
21
|
-
# read entries with [:key] / fetch
|
|
22
|
-
# T::Hash[Symbol, T.untyped], while exposing typed readers for the well-known
|
|
21
|
+
# read entries with [:key] / fetch, while exposing typed readers for the well-known
|
|
23
22
|
# keys. Instances compare equal (Hash#==) to plain hashes with the same
|
|
24
23
|
# content, so existing comparisons and API payloads are unaffected.
|
|
25
24
|
class GitTagDetails < Hash
|
|
26
25
|
extend T::Sig
|
|
27
26
|
extend T::Generic
|
|
28
27
|
|
|
29
|
-
# The values are heterogeneous (strings and a version object), so this
|
|
30
|
-
# bridge class is necessarily untyped at the Hash level; the typed readers
|
|
31
|
-
# below are the migration path.
|
|
32
|
-
# rubocop:disable Sorbet/ForbidTUntyped
|
|
33
28
|
K = type_member { { fixed: Symbol } }
|
|
34
|
-
V = type_member { { fixed:
|
|
35
|
-
Elem = type_member { { fixed: [Symbol,
|
|
36
|
-
# rubocop:enable Sorbet/ForbidTUntyped
|
|
29
|
+
V = type_member { { fixed: Object } }
|
|
30
|
+
Elem = type_member { { fixed: [Symbol, Object] } }
|
|
37
31
|
|
|
38
32
|
sig do
|
|
39
33
|
params(
|
|
@@ -54,25 +48,25 @@ module Dependabot
|
|
|
54
48
|
# The tag or ref name, e.g. "v1.2.0".
|
|
55
49
|
sig { returns(String) }
|
|
56
50
|
def tag
|
|
57
|
-
self[:tag]
|
|
51
|
+
T.cast(self[:tag], String)
|
|
58
52
|
end
|
|
59
53
|
|
|
60
54
|
# The version parsed from the tag name.
|
|
61
55
|
sig { returns(T.nilable(Gem::Version)) }
|
|
62
56
|
def version
|
|
63
|
-
self[:version]
|
|
57
|
+
T.cast(self[:version], T.nilable(Gem::Version))
|
|
64
58
|
end
|
|
65
59
|
|
|
66
60
|
# The SHA of the commit the tag points at.
|
|
67
61
|
sig { returns(T.nilable(String)) }
|
|
68
62
|
def commit_sha
|
|
69
|
-
self[:commit_sha]
|
|
63
|
+
T.cast(self[:commit_sha], T.nilable(String))
|
|
70
64
|
end
|
|
71
65
|
|
|
72
66
|
# The SHA of the tag object itself (nil for lightweight tags).
|
|
73
67
|
sig { returns(T.nilable(String)) }
|
|
74
68
|
def tag_sha
|
|
75
|
-
self[:tag_sha]
|
|
69
|
+
T.cast(self[:tag_sha], T.nilable(String))
|
|
76
70
|
end
|
|
77
71
|
end
|
|
78
72
|
end
|