dependabot-common 0.392.0 → 0.394.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 +79 -11
- data/lib/dependabot/credential.rb +12 -3
- data/lib/dependabot/errors.rb +4 -1
- data/lib/dependabot/file_fetchers/base.rb +199 -151
- data/lib/dependabot/file_filtering.rb +0 -2
- 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/package/npm_package_manager_config.rb +72 -0
- data/lib/dependabot/package/npm_registry_package.rb +186 -0
- data/lib/dependabot/pull_request_creator/azure.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/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 +77 -32
- 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 +35 -4
- data/lib/dependabot.rb +1 -1
- metadata +10 -4
|
@@ -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
|
|
@@ -506,18 +503,16 @@ module Dependabot
|
|
|
506
503
|
params(path: String, fetch_submodules: T::Boolean, raise_errors: T::Boolean)
|
|
507
504
|
.returns(T::Array[RepositoryContent])
|
|
508
505
|
end
|
|
509
|
-
def _fetch_repo_contents(path, fetch_submodules: false, raise_errors: true)
|
|
506
|
+
def _fetch_repo_contents(path, fetch_submodules: false, raise_errors: true)
|
|
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
|
-
|
|
517
|
-
filter_excluded(entries)
|
|
518
|
-
else
|
|
519
|
-
entries
|
|
520
|
-
end
|
|
515
|
+
filter_excluded(entries)
|
|
521
516
|
rescue *CLIENT_NOT_FOUND_ERRORS
|
|
522
517
|
raise Dependabot::DirectoryNotFound, directory if path == directory.gsub(%r{^/*}, "")
|
|
523
518
|
|
|
@@ -529,7 +524,7 @@ module Dependabot
|
|
|
529
524
|
# a retry to get its contents.
|
|
530
525
|
updated_path =
|
|
531
526
|
_full_specification_for(path, fetch_submodules: fetch_submodules)
|
|
532
|
-
.
|
|
527
|
+
.path
|
|
533
528
|
retry if updated_path != tmp_path
|
|
534
529
|
|
|
535
530
|
return result.call unless fetch_submodules && !retrying
|
|
@@ -566,8 +561,8 @@ module Dependabot
|
|
|
566
561
|
path = path.gsub(" ", "%20")
|
|
567
562
|
github_response = github_client.contents(repo, path: path, ref: commit)
|
|
568
563
|
|
|
569
|
-
if github_response.
|
|
570
|
-
update_linked_paths(repo, path, commit,
|
|
564
|
+
if github_response.is_a?(Sawyer::Resource)
|
|
565
|
+
update_linked_paths(repo, path, commit, github_response)
|
|
571
566
|
raise Octokit::NotFound
|
|
572
567
|
end
|
|
573
568
|
|
|
@@ -598,15 +593,11 @@ module Dependabot
|
|
|
598
593
|
size: 0 # NOTE: added for parity with github contents API
|
|
599
594
|
)
|
|
600
595
|
end
|
|
601
|
-
|
|
602
|
-
filter_excluded(entries)
|
|
603
|
-
else
|
|
604
|
-
entries
|
|
605
|
-
end
|
|
596
|
+
filter_excluded(entries)
|
|
606
597
|
end
|
|
607
598
|
|
|
608
599
|
# Filters out any entries whose paths match one of the exclude_paths globs.
|
|
609
|
-
sig { params(entries: T::Array[
|
|
600
|
+
sig { params(entries: T::Array[RepositoryContent]).returns(T::Array[RepositoryContent]) }
|
|
610
601
|
def filter_excluded(entries)
|
|
611
602
|
Dependabot.logger.info("DEBUG filter_excluded: entries=#{entries.length}, exclude_paths=#{@exclude_paths.inspect}") # rubocop:disable Layout/LineLength
|
|
612
603
|
|
|
@@ -628,33 +619,76 @@ module Dependabot
|
|
|
628
619
|
|
|
629
620
|
sig { params(file: Sawyer::Resource).returns(RepositoryContent) }
|
|
630
621
|
def _build_github_file_struct(file)
|
|
622
|
+
name = sawyer_string(file, :name)
|
|
631
623
|
RepositoryContent.new(
|
|
632
|
-
name:
|
|
633
|
-
path: file
|
|
634
|
-
type: file
|
|
635
|
-
sha: file
|
|
636
|
-
size: file
|
|
624
|
+
name: name,
|
|
625
|
+
path: sawyer_optional_string(file, :path) || name,
|
|
626
|
+
type: sawyer_optional_string(file, :type) || "",
|
|
627
|
+
sha: sawyer_optional_string(file, :sha),
|
|
628
|
+
size: sawyer_optional_integer(file, :size) || 0
|
|
629
|
+
)
|
|
630
|
+
end
|
|
631
|
+
|
|
632
|
+
sig { params(resource: Sawyer::Resource, key: Symbol).returns(String) }
|
|
633
|
+
def sawyer_string(resource, key)
|
|
634
|
+
value = T.cast(resource[key], Object)
|
|
635
|
+
return value if value.is_a?(String)
|
|
636
|
+
|
|
637
|
+
raise_bad_repository_response("GitHub", "#{key} must be a string")
|
|
638
|
+
end
|
|
639
|
+
|
|
640
|
+
sig { params(resource: Sawyer::Resource, key: Symbol).returns(T.nilable(String)) }
|
|
641
|
+
def sawyer_optional_string(resource, key)
|
|
642
|
+
value = T.cast(resource[key], Object)
|
|
643
|
+
return if value.nil?
|
|
644
|
+
return value if value.is_a?(String)
|
|
645
|
+
|
|
646
|
+
raise_bad_repository_response("GitHub", "#{key} must be a string or nil")
|
|
647
|
+
end
|
|
648
|
+
|
|
649
|
+
sig { params(resource: Sawyer::Resource, key: Symbol).returns(T.nilable(Integer)) }
|
|
650
|
+
def sawyer_optional_integer(resource, key)
|
|
651
|
+
value = T.cast(resource[key], Object)
|
|
652
|
+
return if value.nil?
|
|
653
|
+
return value if value.is_a?(Integer)
|
|
654
|
+
|
|
655
|
+
raise_bad_repository_response("GitHub", "#{key} must be an integer or nil")
|
|
656
|
+
end
|
|
657
|
+
|
|
658
|
+
sig { params(resource: Gitlab::ObjectifiedHash, key: String).returns(String) }
|
|
659
|
+
def gitlab_string(resource, key)
|
|
660
|
+
value = T.cast(resource[key], Object)
|
|
661
|
+
return value if value.is_a?(String)
|
|
662
|
+
|
|
663
|
+
raise_bad_repository_response("GitLab", "#{key} must be a string")
|
|
664
|
+
end
|
|
665
|
+
|
|
666
|
+
sig { params(provider: String, message: String).returns(T.noreturn) }
|
|
667
|
+
def raise_bad_repository_response(provider, message)
|
|
668
|
+
raise Dependabot::PrivateSourceBadResponse.new(
|
|
669
|
+
source.url,
|
|
670
|
+
"Malformed #{provider} repository response: #{message}"
|
|
637
671
|
)
|
|
638
672
|
end
|
|
639
673
|
|
|
640
674
|
sig { params(repo: String, path: String, commit: String).returns(T::Array[RepositoryContent]) }
|
|
641
675
|
def _gitlab_repo_contents(repo, path, commit)
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
676
|
+
gitlab_client
|
|
677
|
+
.repo_tree(repo, path: path, ref: commit, per_page: 100)
|
|
678
|
+
.map do |raw_file|
|
|
679
|
+
file = raw_file
|
|
680
|
+
object_type = gitlab_string(file, "type")
|
|
647
681
|
# GitLab API essentially returns the output from `git ls-tree`
|
|
648
|
-
type = case
|
|
682
|
+
type = case object_type
|
|
649
683
|
when "blob" then "file"
|
|
650
684
|
when "tree" then "dir"
|
|
651
685
|
when "commit" then "submodule"
|
|
652
|
-
else
|
|
686
|
+
else object_type
|
|
653
687
|
end
|
|
654
688
|
|
|
655
689
|
RepositoryContent.new(
|
|
656
|
-
name: file
|
|
657
|
-
path: file
|
|
690
|
+
name: gitlab_string(file, "name"),
|
|
691
|
+
path: gitlab_string(file, "path"),
|
|
658
692
|
type: type,
|
|
659
693
|
size: 0 # GitLab doesn't return file size
|
|
660
694
|
)
|
|
@@ -666,17 +700,19 @@ module Dependabot
|
|
|
666
700
|
response = azure_client.fetch_repo_contents(commit, path)
|
|
667
701
|
|
|
668
702
|
response.map do |entry|
|
|
669
|
-
|
|
703
|
+
object_type = T.cast(entry.fetch("gitObjectType"), String)
|
|
704
|
+
relative_path = T.cast(entry.fetch("relativePath"), String)
|
|
705
|
+
type = case object_type
|
|
670
706
|
when "blob" then "file"
|
|
671
707
|
when "tree" then "dir"
|
|
672
|
-
else
|
|
708
|
+
else object_type
|
|
673
709
|
end
|
|
674
710
|
|
|
675
711
|
RepositoryContent.new(
|
|
676
|
-
name: File.basename(
|
|
677
|
-
path:
|
|
712
|
+
name: File.basename(relative_path),
|
|
713
|
+
path: relative_path,
|
|
678
714
|
type: type,
|
|
679
|
-
size: entry.fetch("size")
|
|
715
|
+
size: T.cast(entry.fetch("size"), Integer)
|
|
680
716
|
)
|
|
681
717
|
end
|
|
682
718
|
end
|
|
@@ -691,17 +727,19 @@ module Dependabot
|
|
|
691
727
|
)
|
|
692
728
|
|
|
693
729
|
response.map do |file|
|
|
694
|
-
|
|
730
|
+
object_type = T.cast(file.fetch("type"), String)
|
|
731
|
+
path = T.cast(file.fetch("path"), String)
|
|
732
|
+
type = case object_type
|
|
695
733
|
when "commit_file" then "file"
|
|
696
734
|
when "commit_directory" then "dir"
|
|
697
|
-
else
|
|
735
|
+
else object_type
|
|
698
736
|
end
|
|
699
737
|
|
|
700
738
|
RepositoryContent.new(
|
|
701
|
-
name: File.basename(
|
|
702
|
-
path:
|
|
739
|
+
name: File.basename(path),
|
|
740
|
+
path: path,
|
|
703
741
|
type: type,
|
|
704
|
-
size: file.fetch("size", 0)
|
|
742
|
+
size: T.cast(file.fetch("size", 0), Integer)
|
|
705
743
|
)
|
|
706
744
|
end
|
|
707
745
|
end
|
|
@@ -714,7 +752,8 @@ module Dependabot
|
|
|
714
752
|
path
|
|
715
753
|
)
|
|
716
754
|
|
|
717
|
-
response.
|
|
755
|
+
output = T.cast(response.data, Aws::CodeCommit::Types::GetFolderOutput)
|
|
756
|
+
output.files.map do |file|
|
|
718
757
|
RepositoryContent.new(
|
|
719
758
|
name: File.basename(file.relative_path),
|
|
720
759
|
path: file.relative_path,
|
|
@@ -724,29 +763,32 @@ module Dependabot
|
|
|
724
763
|
end
|
|
725
764
|
end
|
|
726
765
|
|
|
727
|
-
sig { params(path: String, fetch_submodules: T::Boolean).returns(
|
|
766
|
+
sig { params(path: String, fetch_submodules: T::Boolean).returns(RepositorySpecification) }
|
|
728
767
|
def _full_specification_for(path, fetch_submodules:)
|
|
729
768
|
if fetch_submodules && _linked_dir_for(path)
|
|
730
|
-
linked_dir_details = @linked_paths[_linked_dir_for(path)]
|
|
769
|
+
linked_dir_details = T.must(@linked_paths[T.must(_linked_dir_for(path))])
|
|
731
770
|
sub_path =
|
|
732
771
|
path.gsub(%r{^#{Regexp.quote(T.must(_linked_dir_for(path)))}(/|$)}, "")
|
|
733
772
|
new_path =
|
|
734
|
-
Pathname.new(File.join(linked_dir_details.
|
|
773
|
+
Pathname.new(File.join(linked_dir_details.path, sub_path))
|
|
735
774
|
.cleanpath.to_path
|
|
736
775
|
.gsub(%r{^/}, "")
|
|
737
|
-
|
|
738
|
-
repo: linked_dir_details.
|
|
739
|
-
commit: linked_dir_details.
|
|
740
|
-
provider: linked_dir_details.
|
|
776
|
+
RepositorySpecification.new(
|
|
777
|
+
repo: linked_dir_details.repo,
|
|
778
|
+
commit: linked_dir_details.commit,
|
|
779
|
+
provider: linked_dir_details.provider,
|
|
741
780
|
path: new_path
|
|
742
|
-
|
|
781
|
+
)
|
|
743
782
|
else
|
|
744
|
-
|
|
783
|
+
resolved_commit = commit
|
|
784
|
+
raise Octokit::NotFound unless resolved_commit
|
|
785
|
+
|
|
786
|
+
RepositorySpecification.new(
|
|
745
787
|
repo: source.repo,
|
|
746
788
|
path: path,
|
|
747
|
-
commit:
|
|
789
|
+
commit: resolved_commit,
|
|
748
790
|
provider: source.provider
|
|
749
|
-
|
|
791
|
+
)
|
|
750
792
|
end
|
|
751
793
|
end
|
|
752
794
|
|
|
@@ -754,9 +796,11 @@ module Dependabot
|
|
|
754
796
|
def _fetch_file_content(path, fetch_submodules: false)
|
|
755
797
|
path = path.gsub(%r{^/*}, "")
|
|
756
798
|
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
799
|
+
specification = _full_specification_for(path, fetch_submodules: fetch_submodules)
|
|
800
|
+
provider = specification.provider
|
|
801
|
+
repo = specification.repo
|
|
802
|
+
path = specification.path
|
|
803
|
+
commit = specification.commit
|
|
760
804
|
|
|
761
805
|
_fetch_file_content_fully_specified(provider, repo, path, commit)
|
|
762
806
|
rescue *CLIENT_NOT_FOUND_ERRORS
|
|
@@ -777,7 +821,7 @@ module Dependabot
|
|
|
777
821
|
when "github"
|
|
778
822
|
_fetch_file_content_from_github(path, repo, commit)
|
|
779
823
|
when "gitlab"
|
|
780
|
-
tmp =
|
|
824
|
+
tmp = gitlab_string(gitlab_client.get_file(repo, path, commit), "content")
|
|
781
825
|
decode_binary_string(tmp)
|
|
782
826
|
when "azure"
|
|
783
827
|
azure_client.fetch_file_contents(commit, path)
|
|
@@ -789,33 +833,17 @@ module Dependabot
|
|
|
789
833
|
end
|
|
790
834
|
end
|
|
791
835
|
|
|
792
|
-
# rubocop:disable Metrics/AbcSize
|
|
793
836
|
sig { params(path: String, repo: String, commit: String).returns(String) }
|
|
794
837
|
def _fetch_file_content_from_github(path, repo, commit)
|
|
795
|
-
tmp =
|
|
796
|
-
|
|
797
|
-
raise Octokit::NotFound if tmp.is_a?(Array)
|
|
798
|
-
|
|
799
|
-
if T.unsafe(tmp).type == "symlink"
|
|
800
|
-
@linked_paths[path] = {
|
|
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
|
|
838
|
+
tmp = github_file_resource(path, repo, commit)
|
|
812
839
|
|
|
813
|
-
|
|
840
|
+
content = sawyer_string(tmp, :content)
|
|
841
|
+
if content == ""
|
|
814
842
|
# The file may have exceeded the 1MB limit
|
|
815
843
|
# see https://github.blog/changelog/2022-05-03-increased-file-size-limit-when-retrieving-file-contents-via-rest-api/
|
|
816
|
-
|
|
844
|
+
github_client.raw_contents(repo, path: path, ref: commit)
|
|
817
845
|
else
|
|
818
|
-
decode_binary_string(
|
|
846
|
+
decode_binary_string(content)
|
|
819
847
|
end
|
|
820
848
|
rescue Octokit::Forbidden => e
|
|
821
849
|
raise unless e.message.include?("too_large")
|
|
@@ -827,17 +855,37 @@ module Dependabot
|
|
|
827
855
|
file_details = repo_contents(dir: dir).find { |f| f.name == basename }
|
|
828
856
|
raise unless file_details
|
|
829
857
|
|
|
830
|
-
tmp = github_client.blob(repo, file_details.sha)
|
|
831
|
-
|
|
858
|
+
tmp = github_client.blob(repo, T.must(file_details.sha))
|
|
859
|
+
content = sawyer_string(tmp, :content)
|
|
860
|
+
return content if sawyer_string(tmp, :encoding) == "utf-8"
|
|
832
861
|
|
|
833
|
-
decode_binary_string(
|
|
862
|
+
decode_binary_string(content)
|
|
863
|
+
end
|
|
864
|
+
sig { params(path: String, repo: String, commit: String).returns(Sawyer::Resource) }
|
|
865
|
+
def github_file_resource(path, repo, commit)
|
|
866
|
+
resource = github_client.contents(repo, path: path, ref: commit)
|
|
867
|
+
raise Octokit::NotFound if resource.is_a?(Array)
|
|
868
|
+
return resource unless sawyer_optional_string(resource, :type) == "symlink"
|
|
869
|
+
|
|
870
|
+
target = sawyer_string(resource, :target)
|
|
871
|
+
clean_target = Pathname.new(target).cleanpath.to_path
|
|
872
|
+
@linked_paths[path] = LinkedPath.new(
|
|
873
|
+
repo: repo,
|
|
874
|
+
provider: "github",
|
|
875
|
+
commit: commit,
|
|
876
|
+
path: clean_target
|
|
877
|
+
)
|
|
878
|
+
|
|
879
|
+
target_resource = github_client.contents(repo, path: clean_target, ref: commit)
|
|
880
|
+
return target_resource if target_resource.is_a?(Sawyer::Resource)
|
|
881
|
+
|
|
882
|
+
raise_bad_repository_response("GitHub", "symlink target must be a file")
|
|
834
883
|
end
|
|
835
|
-
# rubocop:enable Metrics/AbcSize
|
|
836
884
|
|
|
837
885
|
# Update the @linked_paths hash by exploiting a side-effect of
|
|
838
886
|
# recursively calling `repo_contents` for each directory up the tree
|
|
839
887
|
# until a submodule or symlink is found
|
|
840
|
-
sig { params(path: String).returns(T.nilable(T::Array[
|
|
888
|
+
sig { params(path: String).returns(T.nilable(T::Array[RepositoryContent])) }
|
|
841
889
|
def _find_linked_dirs(path)
|
|
842
890
|
path = Pathname.new(path).cleanpath.to_path.gsub(%r{^/*}, "")
|
|
843
891
|
dir = File.dirname(path)
|
|
@@ -90,8 +90,6 @@ module Dependabot
|
|
|
90
90
|
).returns(T::Boolean)
|
|
91
91
|
end
|
|
92
92
|
def self.should_exclude_path?(path, context, exclude_paths)
|
|
93
|
-
return false unless Dependabot::Experiments.enabled?(:enable_exclude_paths_subdirectory_manifest_files)
|
|
94
|
-
|
|
95
93
|
return false if exclude_paths.nil? || exclude_paths.empty?
|
|
96
94
|
|
|
97
95
|
should_exclude = exclude_path?(path, exclude_paths)
|
|
@@ -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
|