dependabot-common 0.380.0 → 0.382.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.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/lib/dependabot/clients/github_with_retries.rb +2 -2
  3. data/lib/dependabot/clients/gitlab_with_retries.rb +2 -2
  4. data/lib/dependabot/command_helpers.rb +1 -1
  5. data/lib/dependabot/config/ignore_condition.rb +1 -1
  6. data/lib/dependabot/credential.rb +14 -1
  7. data/lib/dependabot/dependency.rb +12 -10
  8. data/lib/dependabot/dependency_file.rb +1 -1
  9. data/lib/dependabot/dependency_requirement.rb +94 -0
  10. data/lib/dependabot/errors.rb +12 -0
  11. data/lib/dependabot/file_fetchers/base.rb +34 -32
  12. data/lib/dependabot/file_parsers/base/dependency_set.rb +1 -1
  13. data/lib/dependabot/file_parsers/base.rb +5 -0
  14. data/lib/dependabot/file_updaters/artifact_updater.rb +40 -4
  15. data/lib/dependabot/file_updaters/vendor_updater.rb +42 -3
  16. data/lib/dependabot/git_commit_checker.rb +18 -17
  17. data/lib/dependabot/git_tag_details.rb +78 -0
  18. data/lib/dependabot/metadata_finders/base/changelog_finder.rb +11 -14
  19. data/lib/dependabot/metadata_finders/base/commits_finder.rb +13 -9
  20. data/lib/dependabot/metadata_finders/base/release_finder.rb +14 -12
  21. data/lib/dependabot/notices.rb +1 -1
  22. data/lib/dependabot/package/package_latest_version_finder.rb +8 -3
  23. data/lib/dependabot/pull_request_creator/branch_namer/solo_strategy.rb +16 -16
  24. data/lib/dependabot/pull_request_creator/github.rb +17 -17
  25. data/lib/dependabot/pull_request_creator/gitlab.rb +16 -14
  26. data/lib/dependabot/pull_request_creator/labeler.rb +19 -17
  27. data/lib/dependabot/pull_request_creator/pr_name_prefixer.rb +3 -3
  28. data/lib/dependabot/pull_request_updater/github.rb +13 -11
  29. data/lib/dependabot/pull_request_updater/gitlab.rb +2 -2
  30. data/lib/dependabot/shared_helpers.rb +2 -1
  31. data/lib/dependabot/update_checkers/base.rb +15 -1
  32. data/lib/dependabot.rb +1 -1
  33. metadata +4 -2
@@ -14,6 +14,7 @@ require "dependabot/source"
14
14
  require "dependabot/dependency"
15
15
  require "dependabot/credential"
16
16
  require "dependabot/git_metadata_fetcher"
17
+ require "dependabot/git_tag_details"
17
18
  module Dependabot
18
19
  # rubocop:disable Metrics/ClassLength
19
20
  class GitCommitChecker
@@ -159,31 +160,31 @@ module Dependabot
159
160
  local_repo_git_metadata_fetcher.head_commit_for_ref(name)
160
161
  end
161
162
 
162
- sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
163
+ sig { returns(T.nilable(Dependabot::GitTagDetails)) }
163
164
  def local_ref_for_latest_version_matching_existing_precision
164
165
  allowed_refs = local_tag_for_pinned_sha ? allowed_version_tags : allowed_version_refs
165
166
 
166
167
  max_local_tag_for_current_precision(allowed_refs)
167
168
  end
168
169
 
169
- sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
170
+ sig { returns(T.nilable(Dependabot::GitTagDetails)) }
170
171
  def local_ref_for_latest_version_lower_precision
171
172
  allowed_refs = local_tag_for_pinned_sha ? allowed_version_tags : allowed_version_refs
172
173
 
173
174
  max_local_tag_for_lower_precision(allowed_refs)
174
175
  end
175
176
 
176
- sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) }
177
+ sig { returns(T.nilable(Dependabot::GitTagDetails)) }
177
178
  def local_tag_for_latest_version
178
179
  max_local_tag(allowed_version_tags)
179
180
  end
180
181
 
181
- sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
182
+ sig { returns(T::Array[Dependabot::GitTagDetails]) }
182
183
  def local_tags_for_allowed_versions_matching_existing_precision
183
184
  select_matching_existing_precision(allowed_version_tags).filter_map { |t| to_local_tag(t) }
184
185
  end
185
186
 
186
- sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
187
+ sig { returns(T::Array[Dependabot::GitTagDetails]) }
187
188
  def local_tags_for_allowed_versions
188
189
  allowed_version_tags.filter_map { |t| to_local_tag(t) }
189
190
  end
@@ -272,7 +273,7 @@ module Dependabot
272
273
  local_tags_matching_sha(commit_sha).map(&:name)
273
274
  end
274
275
 
275
- sig { params(tags: T::Array[Dependabot::GitRef]).returns(T.nilable(T::Hash[Symbol, T.untyped])) }
276
+ sig { params(tags: T::Array[Dependabot::GitRef]).returns(T.nilable(Dependabot::GitTagDetails)) }
276
277
  def max_local_tag(tags)
277
278
  max_version_tag = tags.max_by { |t| version_from_tag(t) }
278
279
 
@@ -295,12 +296,12 @@ module Dependabot
295
296
  sig { returns(T::Array[String]) }
296
297
  attr_reader :ignored_versions
297
298
 
298
- sig { params(tags: T::Array[Dependabot::GitRef]).returns(T.nilable(T::Hash[Symbol, T.untyped])) }
299
+ sig { params(tags: T::Array[Dependabot::GitRef]).returns(T.nilable(Dependabot::GitTagDetails)) }
299
300
  def max_local_tag_for_current_precision(tags)
300
301
  max_local_tag(select_matching_existing_precision(tags))
301
302
  end
302
303
 
303
- sig { params(tags: T::Array[Dependabot::GitRef]).returns(T.nilable(T::Hash[Symbol, T.untyped])) }
304
+ sig { params(tags: T::Array[Dependabot::GitRef]).returns(T.nilable(Dependabot::GitTagDetails)) }
304
305
  def max_local_tag_for_lower_precision(tags)
305
306
  max_local_tag(select_lower_precision(tags))
306
307
  end
@@ -463,7 +464,7 @@ module Dependabot
463
464
  .for_github_dot_com(credentials: credentials)
464
465
 
465
466
  # TODO: create this method instead of relying on method_missing
466
- T.unsafe(client).compare(listing_source_repo, ref1, ref2).status
467
+ T.unsafe(client.compare(T.must(listing_source_repo), ref1, ref2)).status
467
468
  end
468
469
 
469
470
  sig { params(ref1: String, ref2: String).returns(String) }
@@ -471,10 +472,10 @@ module Dependabot
471
472
  client = Clients::GitlabWithRetries
472
473
  .for_gitlab_dot_com(credentials: credentials)
473
474
 
474
- comparison = T.unsafe(client).compare(listing_source_repo, ref1, ref2)
475
+ comparison = client.compare(T.must(listing_source_repo), ref1, ref2)
475
476
 
476
- if comparison.commits.none? then "behind"
477
- elsif comparison.compare_same_ref then "identical"
477
+ if T.unsafe(comparison).commits.none? then "behind"
478
+ elsif T.unsafe(comparison).compare_same_ref then "identical"
478
479
  else
479
480
  "ahead"
480
481
  end
@@ -489,7 +490,7 @@ module Dependabot
489
490
  client = Clients::BitbucketWithRetries
490
491
  .for_bitbucket_dot_org(credentials: credentials)
491
492
 
492
- response = T.unsafe(client).get(url)
493
+ response = client.get(url)
493
494
 
494
495
  # Conservatively assume that ref2 is ahead in the equality case, of
495
496
  # if we get an unexpected format (e.g., due to a 404)
@@ -553,17 +554,17 @@ module Dependabot
553
554
  prefix.length > 1 ? prefix.gsub(/v$/i, "") : prefix.gsub(/^v$/i, "")
554
555
  end
555
556
 
556
- sig { params(tag: T.nilable(Dependabot::GitRef)).returns(T.nilable(T::Hash[Symbol, T.untyped])) }
557
+ sig { params(tag: T.nilable(Dependabot::GitRef)).returns(T.nilable(Dependabot::GitTagDetails)) }
557
558
  def to_local_tag(tag)
558
559
  return unless tag
559
560
 
560
561
  version = version_from_tag(tag)
561
- {
562
+ GitTagDetails.new(
562
563
  tag: tag.name,
563
564
  version: version,
564
565
  commit_sha: tag.commit_sha,
565
566
  tag_sha: tag.ref_sha
566
- }
567
+ )
567
568
  end
568
569
 
569
570
  sig { returns(T.nilable(String)) }
@@ -688,7 +689,7 @@ module Dependabot
688
689
  source: T.must(source),
689
690
  credentials: credentials
690
691
  )
691
- T.unsafe(client).releases(T.must(source).repo, per_page: 100)
692
+ client.releases(T.must(source).repo, per_page: 100)
692
693
  rescue Octokit::Error
693
694
  []
694
695
  end,
@@ -0,0 +1,78 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ require "sorbet-runtime"
5
+
6
+ module Dependabot
7
+ # A git tag (or ref) resolved to a version, as produced by GitCommitChecker's
8
+ # local_tag_for_* / local_ref_for_* methods, e.g.:
9
+ #
10
+ # {
11
+ # tag: "v1.2.0",
12
+ # version: Dependabot::Version.new("1.2.0"),
13
+ # commit_sha: "a1b2c3...",
14
+ # tag_sha: "d4e5f6..." # nil for lightweight tags
15
+ # }
16
+ #
17
+ # Distinct from Dependabot::GitTagWithDetail, which carries a tag name and
18
+ # release date for cooldown handling.
19
+ #
20
+ # Subclasses Hash so it is a drop-in replacement at the many call sites that
21
+ # read entries with [:key] / fetch and treat them as
22
+ # T::Hash[Symbol, T.untyped], while exposing typed readers for the well-known
23
+ # keys. Instances compare equal (Hash#==) to plain hashes with the same
24
+ # content, so existing comparisons and API payloads are unaffected.
25
+ class GitTagDetails < Hash
26
+ extend T::Sig
27
+ extend T::Generic
28
+
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
+ K = type_member { { fixed: Symbol } }
34
+ V = type_member { { fixed: T.untyped } }
35
+ Elem = type_member { { fixed: [Symbol, T.untyped] } }
36
+ # rubocop:enable Sorbet/ForbidTUntyped
37
+
38
+ sig do
39
+ params(
40
+ tag: String,
41
+ version: T.nilable(Gem::Version),
42
+ commit_sha: T.nilable(String),
43
+ tag_sha: T.nilable(String)
44
+ ).void
45
+ end
46
+ def initialize(tag:, version: nil, commit_sha: nil, tag_sha: nil)
47
+ super()
48
+ self[:tag] = tag
49
+ self[:version] = version
50
+ self[:commit_sha] = commit_sha
51
+ self[:tag_sha] = tag_sha
52
+ end
53
+
54
+ # The tag or ref name, e.g. "v1.2.0".
55
+ sig { returns(String) }
56
+ def tag
57
+ self[:tag]
58
+ end
59
+
60
+ # The version parsed from the tag name.
61
+ sig { returns(T.nilable(Gem::Version)) }
62
+ def version
63
+ self[:version]
64
+ end
65
+
66
+ # The SHA of the commit the tag points at.
67
+ sig { returns(T.nilable(String)) }
68
+ def commit_sha
69
+ self[:commit_sha]
70
+ end
71
+
72
+ # The SHA of the tag object itself (nil for lightweight tags).
73
+ sig { returns(T.nilable(String)) }
74
+ def tag_sha
75
+ self[:tag_sha]
76
+ end
77
+ end
78
+ end
@@ -102,7 +102,7 @@ module Dependabot
102
102
  @suggested_changelog_url = @suggested_changelog_url&.split("#")&.first
103
103
 
104
104
  @new_version = T.let(nil, T.nilable(String))
105
- @changelog_from_suggested_url = T.let(nil, T.untyped)
105
+ @changelog_from_suggested_url = T.let(nil, T.nilable(Sawyer::Resource))
106
106
  end
107
107
 
108
108
  sig { returns(T.nilable(String)) }
@@ -172,7 +172,7 @@ module Dependabot
172
172
 
173
173
  opts = { path: suggested_source&.directory, ref: suggested_source&.branch }.compact
174
174
  suggested_source_client = github_client_for_source(T.must(suggested_source))
175
- tmp_files = T.unsafe(suggested_source_client).contents(suggested_source&.repo, opts)
175
+ tmp_files = suggested_source_client.contents(T.must(suggested_source).repo, opts)
176
176
 
177
177
  filename = T.must(T.must(suggested_changelog_url).split("/").last)
178
178
  @changelog_from_suggested_url =
@@ -290,7 +290,7 @@ module Dependabot
290
290
  sig { params(file_source: Dependabot::Source, file: T.untyped).returns(String) }
291
291
  def fetch_github_file(file_source, file)
292
292
  # Hitting the download URL directly causes encoding problems
293
- raw_content = T.unsafe(github_client_for_source(file_source)).get(file.url).content
293
+ raw_content = T.unsafe(github_client_for_source(file_source).get(file.url)).content
294
294
  Base64.decode64(raw_content).force_encoding("UTF-8").encode
295
295
  end
296
296
 
@@ -305,8 +305,8 @@ module Dependabot
305
305
 
306
306
  sig { params(file: T.untyped).returns(String) }
307
307
  def fetch_bitbucket_file(file)
308
- T.unsafe(bitbucket_client).get(file.download_url).body
309
- .force_encoding("UTF-8").encode
308
+ bitbucket_client.get(file.download_url).body
309
+ .force_encoding("UTF-8").encode
310
310
  end
311
311
 
312
312
  sig { params(file: T.untyped).returns(String) }
@@ -349,37 +349,34 @@ module Dependabot
349
349
  end
350
350
  end
351
351
 
352
- # rubocop:disable Metrics/AbcSize
353
352
  sig { params(ref: T.nilable(String)).returns(T::Array[T.untyped]) }
354
353
  def fetch_github_file_list(ref)
355
354
  files = []
356
355
 
357
356
  if T.must(source).directory
358
357
  opts = { path: T.must(source).directory, ref: ref }.compact
359
- tmp_files = T.unsafe(github_client).contents(T.must(source).repo, opts)
358
+ tmp_files = github_client.contents(T.must(source).repo, opts)
360
359
  files += tmp_files if tmp_files.is_a?(Array)
361
360
  end
362
361
 
363
362
  opts = { ref: ref }.compact
364
- files += T.unsafe(github_client).contents(T.must(source).repo, opts)
363
+ files += github_client.contents(T.must(source).repo, opts)
365
364
 
366
365
  files.uniq.each do |f|
367
366
  next unless f.type == "dir" && f.name.match?(/docs?/o)
368
367
 
369
368
  opts = { path: f.path, ref: ref }.compact
370
- files += T.unsafe(github_client).contents(T.must(source).repo, opts)
369
+ files += github_client.contents(T.must(source).repo, opts)
371
370
  end
372
371
 
373
372
  files
374
373
  rescue Octokit::NotFound, Octokit::UnavailableForLegalReasons
375
374
  []
376
375
  end
377
- # rubocop:enable Metrics/AbcSize
378
-
379
376
  sig { returns(T.untyped) }
380
377
  def fetch_bitbucket_file_list
381
378
  branch = default_bitbucket_branch
382
- T.unsafe(bitbucket_client).fetch_repo_contents(T.must(source).repo).map do |file|
379
+ bitbucket_client.fetch_repo_contents(T.must(source).repo).map do |file|
383
380
  type = case file.fetch("type")
384
381
  when "commit_file" then "file"
385
382
  when "commit_directory" then "dir"
@@ -402,7 +399,7 @@ module Dependabot
402
399
  sig { returns(T.untyped) }
403
400
  def fetch_gitlab_file_list
404
401
  branch = default_gitlab_branch
405
- T.unsafe(gitlab_client).repo_tree(T.must(source).repo).map do |file|
402
+ T.unsafe(gitlab_client.repo_tree(T.must(source).repo)).map do |file|
406
403
  type = case file.type
407
404
  when "blob" then "file"
408
405
  when "tree" then "dir"
@@ -544,7 +541,7 @@ module Dependabot
544
541
  def default_bitbucket_branch
545
542
  @default_bitbucket_branch ||=
546
543
  T.let(
547
- T.unsafe(bitbucket_client).fetch_default_branch(T.must(source).repo),
544
+ bitbucket_client.fetch_default_branch(T.must(source).repo),
548
545
  T.nilable(String)
549
546
  )
550
547
  end
@@ -145,7 +145,7 @@ module Dependabot
145
145
  end
146
146
 
147
147
  # TODO: Refactor me so that Composer doesn't need to be special cased
148
- sig { params(requirements: T.nilable(T::Array[T::Hash[Symbol, T.untyped]])).returns(T::Boolean) }
148
+ sig { params(requirements: T.nilable(T::Array[Dependabot::DependencyRequirement])).returns(T::Boolean) }
149
149
  def git_source?(requirements)
150
150
  # Special case Composer, which uses git as a source but handles tags
151
151
  # internally
@@ -282,13 +282,15 @@ module Dependabot
282
282
 
283
283
  args = { sha: previous_tag, path: path }.compact
284
284
  previous_commit_shas =
285
- T.unsafe(github_client).commits(repo, **args).map(&:sha)
285
+ T.unsafe(github_client.commits(repo, **args)).map(&:sha)
286
286
 
287
287
  # NOTE: We reverse this so it's consistent with the array we get
288
288
  # from `github_client.compare(...)`
289
289
  args = { sha: new_tag, path: path }.compact
290
- T.unsafe(github_client)
291
- .commits(repo, **args)
290
+ T.unsafe(
291
+ github_client
292
+ .commits(repo, **args)
293
+ )
292
294
  .reject { |c| previous_commit_shas.include?(c.sha) }.reverse
293
295
  end
294
296
  return [] unless commits
@@ -306,9 +308,9 @@ module Dependabot
306
308
 
307
309
  sig { returns(T::Array[T::Hash[Symbol, String]]) }
308
310
  def fetch_bitbucket_commits
309
- T.unsafe(bitbucket_client)
310
- .compare(T.must(source).repo, previous_tag, new_tag)
311
- .map do |commit|
311
+ bitbucket_client
312
+ .compare(T.must(source).repo, T.must(previous_tag), T.must(new_tag))
313
+ .map do |commit|
312
314
  {
313
315
  message: commit.dig("summary", "raw"),
314
316
  sha: commit["hash"],
@@ -326,8 +328,10 @@ module Dependabot
326
328
 
327
329
  sig { returns(T::Array[T::Hash[Symbol, String]]) }
328
330
  def fetch_gitlab_commits
329
- T.unsafe(gitlab_client)
330
- .compare(T.must(source).repo, previous_tag, new_tag)
331
+ T.unsafe(
332
+ gitlab_client
333
+ .compare(T.must(source).repo, T.must(previous_tag), T.must(new_tag))
334
+ )
331
335
  .commits
332
336
  .map do |commit|
333
337
  {
@@ -281,21 +281,21 @@ module Dependabot
281
281
 
282
282
  sig { returns(T::Array[T.untyped]) }
283
283
  def fetch_github_releases
284
- releases = T.unsafe(github_client).releases(T.must(source).repo, per_page: 100)
284
+ releases = github_client.releases(T.must(source).repo, per_page: 100)
285
285
 
286
286
  # Remove any releases without a tag name. These are draft releases and
287
287
  # aren't yet associated with a tag, so shouldn't be used.
288
- releases = releases.reject { |r| r.tag_name.nil? }
288
+ releases = releases.reject { |r| T.unsafe(r).tag_name.nil? }
289
289
 
290
290
  clean_release_names =
291
- releases.map { |r| r.tag_name.gsub(/^[^0-9\.]*/, "") }
291
+ releases.map { |r| T.unsafe(r).tag_name.gsub(/^[^0-9\.]*/, "") }
292
292
 
293
293
  if clean_release_names.all? { |nm| version_class.correct?(nm) }
294
294
  releases.sort_by do |r|
295
- version_class.new(r.tag_name.gsub(/^[^0-9\.]*/, ""))
295
+ version_class.new(T.unsafe(r).tag_name.gsub(/^[^0-9\.]*/, ""))
296
296
  end.reverse
297
297
  else
298
- releases.sort_by(&:id).reverse
298
+ releases.sort_by { |r| T.unsafe(r).id }.reverse
299
299
  end
300
300
  rescue Octokit::NotFound, Octokit::UnavailableForLegalReasons
301
301
  []
@@ -304,18 +304,20 @@ module Dependabot
304
304
  sig { returns(T::Array[T.untyped]) }
305
305
  def fetch_gitlab_releases
306
306
  releases =
307
- T.unsafe(gitlab_client)
308
- .tags(T.must(source).repo)
307
+ T.unsafe(
308
+ gitlab_client
309
+ .tags(T.must(source).repo)
310
+ )
309
311
  .select(&:release)
310
- .sort_by { |r| r.commit.authored_date }
312
+ .sort_by { |r| T.unsafe(r).commit.authored_date }
311
313
  .reverse
312
314
 
313
315
  releases.map do |tag|
314
316
  GitLabRelease.new(
315
- name: tag.name,
316
- tag_name: tag.release.tag_name,
317
- body: tag.release.description,
318
- html_url: "#{T.must(source).url}/tags/#{tag.name}"
317
+ name: T.unsafe(tag).name,
318
+ tag_name: T.unsafe(tag).release.tag_name,
319
+ body: T.unsafe(tag).release.description,
320
+ html_url: "#{T.must(source).url}/tags/#{T.unsafe(tag).name}"
319
321
  )
320
322
  end
321
323
  rescue Gitlab::Error::NotFound
@@ -59,7 +59,7 @@ module Dependabot
59
59
 
60
60
  # Converts the Notice object to a hash.
61
61
  # @return [Hash] The hash representation of the notice.
62
- sig { returns(T::Hash[Symbol, T.untyped]) }
62
+ sig { returns(T::Hash[Symbol, T.any(String, T::Boolean)]) }
63
63
  def to_hash
64
64
  {
65
65
  mode: @mode,
@@ -323,11 +323,16 @@ module Dependabot
323
323
 
324
324
  sig { returns(T::Boolean) }
325
325
  def wants_prerelease?
326
- return version_class.new(dependency.version).prerelease? if dependency.version
326
+ return true if dependency.numeric_version&.prerelease?
327
327
 
328
328
  dependency.requirements.any? do |req|
329
- reqs = (req.fetch(:requirement) || "").split(",").map(&:strip)
330
- reqs.any? { |r| r.match?(/[A-Za-z]/) }
329
+ req_string = req.fetch(:requirement) || ""
330
+ req_string.split(",").map(&:strip).any? do |r|
331
+ version_str = r.gsub(/^\s*[!<>=~^]+\s*/, "").strip
332
+ next false unless version_class.correct?(version_str)
333
+
334
+ version_class.new(version_str).prerelease?
335
+ end
331
336
  end
332
337
  end
333
338
 
@@ -119,21 +119,21 @@ module Dependabot
119
119
 
120
120
  sig { params(dependency: Dependabot::Dependency).returns(String) }
121
121
  def sanitized_requirement(dependency)
122
- new_library_requirement(dependency)
123
- .delete(" ")
124
- .gsub("!=", "neq-")
125
- .gsub(">=", "gte-")
126
- .gsub("<=", "lte-")
127
- .gsub("~>", "tw-")
128
- .gsub("^", "tw-")
129
- .gsub("||", "or-")
130
- .gsub("~", "approx-")
131
- .gsub("~=", "tw-")
132
- .gsub(/==*/, "eq-")
133
- .gsub(">", "gt-")
134
- .gsub("<", "lt-")
135
- .gsub("*", "star")
136
- .gsub(",", "-and-")
122
+ T.must(new_library_requirement(dependency))
123
+ .delete(" ")
124
+ .gsub("!=", "neq-")
125
+ .gsub(">=", "gte-")
126
+ .gsub("<=", "lte-")
127
+ .gsub("~>", "tw-")
128
+ .gsub("^", "tw-")
129
+ .gsub("||", "or-")
130
+ .gsub("~", "approx-")
131
+ .gsub("~=", "tw-")
132
+ .gsub(/==*/, "eq-")
133
+ .gsub(">", "gt-")
134
+ .gsub("<", "lt-")
135
+ .gsub("*", "star")
136
+ .gsub(",", "-and-")
137
137
  end
138
138
 
139
139
  sig { params(dependency: Dependabot::Dependency).returns(T.nilable(String)) }
@@ -176,7 +176,7 @@ module Dependabot
176
176
  previous_ref(dependency) != new_ref(dependency)
177
177
  end
178
178
 
179
- sig { params(dependency: Dependabot::Dependency).returns(T.untyped) }
179
+ sig { params(dependency: Dependabot::Dependency).returns(T.nilable(String)) }
180
180
  def new_library_requirement(dependency)
181
181
  updated_reqs =
182
182
  dependency.requirements - T.must(dependency.previous_requirements)
@@ -196,7 +196,7 @@ module Dependabot
196
196
  @pull_requests_for_branch ||=
197
197
  T.let(
198
198
  begin
199
- T.unsafe(github_client_for_source).pull_requests(
199
+ github_client_for_source.pull_requests(
200
200
  source.repo,
201
201
  head: "#{source.repo.split('/').first}:#{branch_name}",
202
202
  state: "all"
@@ -204,13 +204,13 @@ module Dependabot
204
204
  rescue Octokit::InternalServerError
205
205
  # A GitHub bug sometimes means adding `state: all` causes problems.
206
206
  # In that case, fall back to making two separate requests.
207
- open_prs = T.unsafe(github_client_for_source).pull_requests(
207
+ open_prs = github_client_for_source.pull_requests(
208
208
  source.repo,
209
209
  head: "#{source.repo.split('/').first}:#{branch_name}",
210
210
  state: "open"
211
211
  )
212
212
 
213
- closed_prs = T.unsafe(github_client_for_source).pull_requests(
213
+ closed_prs = github_client_for_source.pull_requests(
214
214
  source.repo,
215
215
  head: "#{source.repo.split('/').first}:#{branch_name}",
216
216
  state: "closed"
@@ -254,7 +254,7 @@ module Dependabot
254
254
 
255
255
  sig { returns(T::Boolean) }
256
256
  def repo_exists?
257
- T.unsafe(github_client_for_source).repo(source.repo)
257
+ github_client_for_source.repo(source.repo)
258
258
  true
259
259
  rescue Octokit::NotFound
260
260
  false
@@ -265,7 +265,7 @@ module Dependabot
265
265
  tree = create_tree
266
266
 
267
267
  begin
268
- T.unsafe(github_client_for_source).create_commit(
268
+ github_client_for_source.create_commit(
269
269
  source.repo,
270
270
  commit_message,
271
271
  tree.sha,
@@ -317,8 +317,8 @@ module Dependabot
317
317
  content = if file.operation == Dependabot::DependencyFile::Operation::DELETE
318
318
  { sha: nil }
319
319
  elsif file.binary?
320
- sha = T.unsafe(github_client_for_source).create_blob(
321
- source.repo, file.content, "base64"
320
+ sha = github_client_for_source.create_blob(
321
+ source.repo, T.must(file.content), "base64"
322
322
  )
323
323
  { sha: sha }
324
324
  else
@@ -333,7 +333,7 @@ module Dependabot
333
333
  end
334
334
  end
335
335
 
336
- T.unsafe(github_client_for_source).create_tree(
336
+ github_client_for_source.create_tree(
337
337
  source.repo,
338
338
  file_trees,
339
339
  base_tree: base_commit
@@ -365,7 +365,7 @@ module Dependabot
365
365
 
366
366
  begin
367
367
  branch =
368
- T.unsafe(github_client_for_source).create_ref(source.repo, ref, commit.sha)
368
+ github_client_for_source.create_ref(source.repo, ref, commit.sha)
369
369
  @branch_name = ref.gsub(%r{^refs/heads/}, "")
370
370
  branch
371
371
  rescue Octokit::UnprocessableEntity => e
@@ -385,7 +385,7 @@ module Dependabot
385
385
 
386
386
  sig { params(commit: T.untyped).void }
387
387
  def update_branch(commit)
388
- T.unsafe(github_client_for_source).update_ref(
388
+ github_client_for_source.update_ref(
389
389
  source.repo,
390
390
  "heads/#{branch_name}",
391
391
  commit.sha,
@@ -406,7 +406,7 @@ module Dependabot
406
406
  reviewers_hash =
407
407
  T.must(reviewers).keys.to_h { |k| [k.to_sym, T.must(reviewers)[k]] }
408
408
 
409
- T.unsafe(github_client_for_source).request_pull_request_review(
409
+ github_client_for_source.request_pull_request_review(
410
410
  source.repo,
411
411
  pull_request.number,
412
412
  reviewers: reviewers_hash[:reviewers] || [],
@@ -458,7 +458,7 @@ module Dependabot
458
458
  "#{message}\n" \
459
459
  "```"
460
460
 
461
- T.unsafe(github_client_for_source).add_comment(
461
+ github_client_for_source.add_comment(
462
462
  source.repo,
463
463
  pull_request.number,
464
464
  msg
@@ -467,10 +467,10 @@ module Dependabot
467
467
 
468
468
  sig { params(pull_request: T.untyped).void }
469
469
  def add_assignees_to_pull_request(pull_request)
470
- T.unsafe(github_client_for_source).add_assignees(
470
+ github_client_for_source.add_assignees(
471
471
  source.repo,
472
472
  pull_request.number,
473
- assignees
473
+ T.must(assignees)
474
474
  )
475
475
  rescue Octokit::NotFound
476
476
  # This can happen if a passed assignee login is now an org account
@@ -482,7 +482,7 @@ module Dependabot
482
482
 
483
483
  sig { params(pull_request: T.untyped).void }
484
484
  def add_milestone_to_pull_request(pull_request)
485
- T.unsafe(github_client_for_source).update_issue(
485
+ github_client_for_source.update_issue(
486
486
  source.repo,
487
487
  pull_request.number,
488
488
  milestone: milestone
@@ -493,7 +493,7 @@ module Dependabot
493
493
 
494
494
  sig { returns(T.untyped) }
495
495
  def create_pull_request
496
- T.unsafe(github_client_for_source).create_pull_request(
496
+ github_client_for_source.create_pull_request(
497
497
  source.repo,
498
498
  target_branch,
499
499
  branch_name,
@@ -521,7 +521,7 @@ module Dependabot
521
521
  def default_branch
522
522
  @default_branch ||=
523
523
  T.let(
524
- T.unsafe(github_client_for_source).repo(source.repo).default_branch,
524
+ T.unsafe(github_client_for_source.repo(source.repo)).default_branch,
525
525
  T.nilable(String)
526
526
  )
527
527
  end