dependabot-common 0.384.0 → 0.386.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4011821492cf0ae915acc4d9b0783f699f5522946eac07bbef8973e8692df1f9
4
- data.tar.gz: 7502e7687e79b39ec94fad1c9318e1b40b7cdf7965c8c1818ebda3a7a914b8ee
3
+ metadata.gz: 4e4c26ec485eed8ebb4e35d9edfa4ab996658f450708439941ff8ca253ce0457
4
+ data.tar.gz: '045951912dda5a814efcf305b11ae28e5c6cd97a1e7f72f1c610650d2f9031cb'
5
5
  SHA512:
6
- metadata.gz: c5f9708f6197bf0fe6e6dd22b971e41522f7deb6af1963786276dd5246d3177741768e4065d437c4ad3906ff0d0d91afd10b41a0108c0e553a14be2ae1dfde5f
7
- data.tar.gz: 1e9ebca6d67ec61d619f36e71cfd02cd92c1aca3d6701b47ff4a94c95f2abcdb05277de57902d4dea2b1d5bb6410cabbc027c81bb0e8884bbee84d31cd43e2f4
6
+ metadata.gz: bb49cbf946335c722ca445b0c314909eb0cf1790b241b68461881873cf254afddb7b7b10a168879ded348af64bdb30f5093882c1221b8f3c7e3ca69bbf6bd59b
7
+ data.tar.gz: ed0b8a8a019adeed81707ee2aae27e1e7e50d8f4c0da2d66cfca4a952df713173706d091062d02cb5a5aa4c18b819747b76ec5f114595fdbb804c4bef9df208b
@@ -20,46 +20,46 @@ module Dependabot
20
20
  end
21
21
 
22
22
  OutputObserver = T.type_alias do
23
- T.nilable(T.proc.params(data: String).returns(T::Hash[Symbol, T.untyped]))
23
+ T.nilable(T.proc.params(data: String).returns(T::Hash[Symbol, T.anything]))
24
24
  end
25
25
 
26
26
  EnvCmdItem = T.type_alias do
27
27
  T.any(
28
28
  String,
29
- T::Hash[T.any(String, Symbol), T.untyped]
29
+ T::Hash[T.any(String, Symbol), T.anything]
30
30
  )
31
31
  end
32
32
 
33
33
  class ProcessStatus
34
34
  extend T::Sig
35
35
 
36
- sig { params(process_status: Process::Status, custom_exitstatus: T.nilable(Integer)).void }
36
+ sig { params(process_status: T.nilable(Process::Status), custom_exitstatus: T.nilable(Integer)).void }
37
37
  def initialize(process_status, custom_exitstatus = nil)
38
- @process_status = process_status
38
+ @process_status = T.let(process_status, T.nilable(Process::Status))
39
39
  @custom_exitstatus = custom_exitstatus
40
40
  end
41
41
 
42
42
  # Return the exit status, either from the process status or the custom one
43
43
  sig { returns(Integer) }
44
44
  def exitstatus
45
- @custom_exitstatus || @process_status.exitstatus || 0
45
+ @custom_exitstatus || @process_status&.exitstatus || 0
46
46
  end
47
47
 
48
48
  # Determine if the process was successful
49
49
  sig { returns(T::Boolean) }
50
50
  def success?
51
- @custom_exitstatus.nil? ? @process_status.success? || false : @custom_exitstatus.zero?
51
+ @custom_exitstatus.nil? ? @process_status&.success? || false : @custom_exitstatus.zero?
52
52
  end
53
53
 
54
54
  # Return the PID of the process (if available)
55
55
  sig { returns(T.nilable(Integer)) }
56
56
  def pid
57
- @process_status.pid
57
+ @process_status&.pid
58
58
  end
59
59
 
60
60
  sig { returns(T.nilable(Integer)) }
61
61
  def termsig
62
- @process_status.termsig
62
+ @process_status&.termsig
63
63
  end
64
64
 
65
65
  # String representation of the status
@@ -68,7 +68,7 @@ module Dependabot
68
68
  if @custom_exitstatus
69
69
  "pid #{pid || 'unknown'}: exit #{@custom_exitstatus} (custom status)"
70
70
  else
71
- @process_status.to_s
71
+ @process_status&.to_s || "unknown status"
72
72
  end
73
73
  end
74
74
  end
@@ -3,6 +3,8 @@
3
3
 
4
4
  require "sorbet-runtime"
5
5
 
6
+ require "dependabot/dependency_file"
7
+
6
8
  module Dependabot
7
9
  module DependencyGraphers
8
10
  # This is a small value class that specifies the information we expect to be returned for each
@@ -20,6 +22,29 @@ module Dependabot
20
22
  const :dependencies, T::Array[String]
21
23
  end
22
24
 
25
+ # A manifest group is a subset of a directory's dependency files that stands on its own as a valid
26
+ # parser input, plus the single file that the group's dependencies should be attributed to.
27
+ #
28
+ # - `primary` is the attribution target (the file that owns the group's dependencies in the snapshot).
29
+ # - `files` is everything the parser needs to resolve the group, including the primary and any sibling
30
+ # files pulled in only to satisfy cross-references.
31
+ #
32
+ # Most ecosystems have exactly one group per directory (a manifest + optional lockfile).
33
+ #
34
+ # Ecosystems where multiple independent manifests routinely share a directory override `manifest_groups`
35
+ # to return one group per independent manifest using ecosystem-specific rules (e.g. Python layered requirements)
36
+ class ManifestGroup < T::ImmutableStruct
37
+ const :primary, Dependabot::DependencyFile
38
+ const :files, T::Array[Dependabot::DependencyFile]
39
+ end
40
+
41
+ # The resolved output for a single manifest group: the file to attribute to, and the dependencies
42
+ # resolved from that group's files.
43
+ class ManifestGroupSnapshot < T::ImmutableStruct
44
+ const :manifest_file, Dependabot::DependencyFile
45
+ const :resolved_dependencies, T::Hash[String, ResolvedDependency]
46
+ end
47
+
23
48
  class Base
24
49
  extend T::Sig
25
50
  extend T::Helpers
@@ -78,8 +103,86 @@ module Dependabot
78
103
  end
79
104
  end
80
105
 
106
+ # Partitions the parsed directory into one or more manifest groups.
107
+ #
108
+ # The default is a single group spanning the whole directory, attributed to `relevant_dependency_file`.
109
+ #
110
+ # Ecosystems where multiple independent manifests share a directory should override this to return
111
+ # one group per manifest.
112
+ sig { overridable.returns(T::Array[ManifestGroup]) }
113
+ def manifest_groups
114
+ [ManifestGroup.new(primary: relevant_dependency_file, files: dependency_files)]
115
+ end
116
+
117
+ # Resolves each manifest group into a snapshot.
118
+ #
119
+ # When there is a single group, the common case for most ecosystems, we attribute all resolved dependencies
120
+ # to the group's primary without further work required.
121
+ #
122
+ # When there are multiple groups, we instantiate a new scoped grapher for the group's files and resolve each
123
+ # independently.
124
+ sig { returns(T::Array[ManifestGroupSnapshot]) }
125
+ def manifest_group_snapshots
126
+ @manifest_group_snapshots ||= T.let(
127
+ build_manifest_group_snapshots,
128
+ T.nilable(T::Array[ManifestGroupSnapshot])
129
+ )
130
+ end
131
+
81
132
  private
82
133
 
134
+ sig { returns(T::Array[ManifestGroupSnapshot]) }
135
+ def build_manifest_group_snapshots
136
+ groups = manifest_groups
137
+
138
+ if groups.one?
139
+ group = T.must(groups.first)
140
+ return [ManifestGroupSnapshot.new(
141
+ manifest_file: group.primary,
142
+ resolved_dependencies: resolved_dependencies
143
+ )]
144
+ end
145
+
146
+ groups.map do |group|
147
+ scoped = scoped_grapher(group.files)
148
+ snapshot = ManifestGroupSnapshot.new(
149
+ manifest_file: group.primary,
150
+ resolved_dependencies: scoped.resolved_dependencies
151
+ )
152
+ # Ensure we propagate any error flags from the scoped grapher.
153
+ absorb_error_state(scoped)
154
+ snapshot
155
+ end
156
+ end
157
+
158
+ # Propagates a scoped grapher's subdependency error state onto this grapher so callers can inspect the
159
+ # aggregate result of resolving every group.
160
+ sig { params(scoped: Dependabot::DependencyGraphers::Base).void }
161
+ def absorb_error_state(scoped)
162
+ return unless scoped.errored_fetching_subdependencies
163
+
164
+ errored_fetching_subdependencies!
165
+ # We keep the last subdependency error we see - the full error dialogue will be present in the logs,
166
+ # this just ensures job summary dialogues have something to show.
167
+ @subdependency_error = scoped.subdependency_error unless scoped.subdependency_error.nil?
168
+ end
169
+
170
+ # Builds a grapher of the same class scoped to a subset of the directory's files, reusing the current
171
+ # file parser's configuration. Used to resolve a single manifest group in isolation.
172
+ sig { params(files: T::Array[Dependabot::DependencyFile]).returns(Dependabot::DependencyGraphers::Base) }
173
+ def scoped_grapher(files)
174
+ scoped_parser = file_parser.class.new(
175
+ dependency_files: files,
176
+ source: file_parser.source,
177
+ repo_contents_path: file_parser.repo_contents_path,
178
+ credentials: file_parser.credentials,
179
+ reject_external_code: file_parser.reject_external_code?,
180
+ options: file_parser.options
181
+ )
182
+
183
+ self.class.new(file_parser: scoped_parser)
184
+ end
185
+
83
186
  sig { returns(Dependabot::FileParsers::Base) }
84
187
  attr_reader :file_parser
85
188
 
@@ -23,7 +23,7 @@ module Dependabot
23
23
 
24
24
  # rubocop:disable Metrics/MethodLength
25
25
  # rubocop:disable Metrics/CyclomaticComplexity
26
- sig { params(error: StandardError).returns(T.nilable(T::Hash[Symbol, T.untyped])) }
26
+ sig { params(error: StandardError).returns(T.nilable(T::Hash[Symbol, T.anything])) }
27
27
  def self.fetcher_error_details(error)
28
28
  case error
29
29
  when Dependabot::ToolVersionNotSupported
@@ -142,7 +142,7 @@ module Dependabot
142
142
  end
143
143
  # rubocop:enable Metrics/CyclomaticComplexity
144
144
 
145
- sig { params(error: StandardError).returns(T.nilable(T::Hash[Symbol, T.untyped])) }
145
+ sig { params(error: StandardError).returns(T.nilable(T::Hash[Symbol, T.anything])) }
146
146
  def self.parser_error_details(error)
147
147
  case error
148
148
  when Dependabot::ToolFeatureNotSupported
@@ -226,7 +226,7 @@ module Dependabot
226
226
  # rubocop:disable Lint/RedundantCopDisableDirective
227
227
  # rubocop:disable Metrics/CyclomaticComplexity
228
228
  # rubocop:disable Metrics/AbcSize
229
- sig { params(error: StandardError).returns(T.nilable(T::Hash[Symbol, T.untyped])) }
229
+ sig { params(error: StandardError).returns(T.nilable(T::Hash[Symbol, T.anything])) }
230
230
  def self.updater_error_details(error)
231
231
  case error
232
232
  when Dependabot::ToolFeatureNotSupported
@@ -416,7 +416,7 @@ module Dependabot
416
416
 
417
417
  interface!
418
418
 
419
- sig { abstract.returns(T::Hash[Symbol, T.untyped]) }
419
+ sig { abstract.returns(T::Hash[Symbol, T.anything]) }
420
420
  def sentry_context; end
421
421
  end
422
422
 
@@ -484,7 +484,7 @@ module Dependabot
484
484
  super(message || error_type)
485
485
  end
486
486
 
487
- sig { params(hash: T.nilable(T::Hash[Symbol, T.untyped])).returns(T::Hash[Symbol, T.untyped]) }
487
+ sig { params(hash: T.nilable(T::Hash[Symbol, T.anything])).returns(T::Hash[Symbol, T.anything]) }
488
488
  def detail(hash = nil)
489
489
  {
490
490
  "error-type": error_type,
@@ -1,4 +1,4 @@
1
- # typed: strict
1
+ # typed: strong
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "sorbet-runtime"
@@ -7,21 +7,21 @@ module Dependabot
7
7
  module Experiments
8
8
  extend T::Sig
9
9
 
10
- @experiments = T.let({}, T::Hash[T.any(String, Symbol), T.untyped])
10
+ @experiments = T.let({}, T::Hash[T.any(String, Symbol), T.anything])
11
11
 
12
- sig { returns(T::Hash[T.any(String, Symbol), T.untyped]) }
12
+ sig { returns(T::Hash[T.any(String, Symbol), T.anything]) }
13
13
  def self.reset!
14
14
  @experiments = {}
15
15
  end
16
16
 
17
- sig { params(name: T.any(String, Symbol), value: T.untyped).void }
17
+ sig { params(name: T.any(String, Symbol), value: T.anything).void }
18
18
  def self.register(name, value)
19
19
  @experiments[name.to_sym] = value
20
20
  end
21
21
 
22
22
  sig { params(name: T.any(String, Symbol)).returns(T::Boolean) }
23
23
  def self.enabled?(name)
24
- !!@experiments[name.to_sym]
24
+ @experiments[name.to_sym] ? true : false
25
25
  end
26
26
  end
27
27
  end
@@ -25,7 +25,7 @@ module Dependabot
25
25
  sig { returns(T.nilable(Dependabot::Source)) }
26
26
  attr_reader :source
27
27
 
28
- sig { returns(T::Hash[Symbol, T.untyped]) }
28
+ sig { returns(T::Hash[Symbol, T.anything]) }
29
29
  attr_reader :options
30
30
 
31
31
  sig { returns(T::Boolean) }
@@ -40,7 +40,7 @@ module Dependabot
40
40
  repo_contents_path: T.nilable(String),
41
41
  credentials: T::Array[Dependabot::Credential],
42
42
  reject_external_code: T::Boolean,
43
- options: T::Hash[Symbol, T.untyped]
43
+ options: T::Hash[Symbol, T.anything]
44
44
  )
45
45
  .void
46
46
  end
@@ -26,7 +26,7 @@ module Dependabot
26
26
  sig { returns(T::Array[Dependabot::Credential]) }
27
27
  attr_reader :credentials
28
28
 
29
- sig { returns(T::Hash[Symbol, T.untyped]) }
29
+ sig { returns(T::Hash[Symbol, T.anything]) }
30
30
  attr_reader :options
31
31
 
32
32
  sig do
@@ -35,7 +35,7 @@ module Dependabot
35
35
  dependency_files: T::Array[Dependabot::DependencyFile],
36
36
  credentials: T::Array[Dependabot::Credential],
37
37
  repo_contents_path: T.nilable(String),
38
- options: T::Hash[Symbol, T.untyped]
38
+ options: T::Hash[Symbol, T.anything]
39
39
  ).void
40
40
  end
41
41
  def initialize(dependencies:, dependency_files:, credentials:, repo_contents_path: nil, options: {})
@@ -2,6 +2,7 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "excon"
5
+ require "time"
5
6
  require "sorbet-runtime"
6
7
  require "gitlab"
7
8
  require "dependabot/clients/github_with_retries"
@@ -15,10 +16,15 @@ require "dependabot/dependency"
15
16
  require "dependabot/credential"
16
17
  require "dependabot/git_metadata_fetcher"
17
18
  require "dependabot/git_tag_details"
19
+ require "dependabot/package/package_release"
20
+ require "dependabot/package/release_cooldown_options"
21
+ require "dependabot/update_checkers/cooldown_calculation"
22
+ require "dependabot/git_cooldown_date_resolver"
18
23
  module Dependabot
19
24
  # rubocop:disable Metrics/ClassLength
20
25
  class GitCommitChecker
21
26
  extend T::Sig
27
+ include Dependabot::GitCooldownDateResolver
22
28
 
23
29
  VERSION_REGEX = /
24
30
  (?<version>
@@ -174,9 +180,35 @@ module Dependabot
174
180
  max_local_tag_for_lower_precision(allowed_refs)
175
181
  end
176
182
 
177
- sig { returns(T.nilable(Dependabot::GitTagDetails)) }
178
- def local_tag_for_latest_version
179
- max_local_tag(allowed_version_tags)
183
+ # Returns the latest allowed version tag, or nil when every candidate tag is
184
+ # still within its cooldown window. All cooldown handling — the nil /
185
+ # disabled / excluded short-circuits and the logging — lives in
186
+ # #apply_cooldown, so this method stays a thin orchestration step.
187
+ sig do
188
+ params(cooldown_options: T.nilable(Dependabot::Package::ReleaseCooldownOptions))
189
+ .returns(T.nilable(Dependabot::GitTagDetails))
190
+ end
191
+ def local_tag_for_latest_version(cooldown_options = nil)
192
+ filtered_tags = apply_cooldown(allowed_version_tags, cooldown_options)
193
+ return nil if filtered_tags.nil?
194
+
195
+ max_local_tag(filtered_tags)
196
+ end
197
+
198
+ # Returns the latest allowed version tag, but only when the dependency is
199
+ # pinned to a ref that looks like a version. Most ecosystems share this
200
+ # precondition before resolving a newer version tag for a git dependency,
201
+ # so it lives here instead of being repeated at each call site. Returns nil
202
+ # for dependencies that aren't pinned to a version (e.g. branch- or
203
+ # SHA-pinned), which never want a version-tag update.
204
+ sig do
205
+ params(cooldown_options: T.nilable(Dependabot::Package::ReleaseCooldownOptions))
206
+ .returns(T.nilable(Dependabot::GitTagDetails))
207
+ end
208
+ def local_tag_for_pinned_version_ref(cooldown_options = nil)
209
+ return nil unless pinned_ref_looks_like_version?
210
+
211
+ local_tag_for_latest_version(cooldown_options)
180
212
  end
181
213
 
182
214
  sig { returns(T::Array[Dependabot::GitTagDetails]) }
@@ -285,6 +317,30 @@ module Dependabot
285
317
  allowed_versions(local_tags, filter_by_prefix: false)
286
318
  end
287
319
 
320
+ # Returns the allowed version tags paired with their parsed release
321
+ # dates as a single list, so callers don't have to re-correlate two
322
+ # separate lists (tags and tag-dates) by tag name themselves.
323
+ sig { returns(T::Array[Dependabot::Package::PackageRelease]) }
324
+ def allowed_version_tags_with_release_dates
325
+ allowed_version_tags.map do |tag|
326
+ Dependabot::Package::PackageRelease.new(
327
+ version: T.cast(version_from_tag(tag), Dependabot::Version),
328
+ tag: tag.name,
329
+ released_at: release_date_for_tag_name(tag.name)
330
+ )
331
+ end
332
+ end
333
+
334
+ sig { override.returns(T.nilable(String)) }
335
+ def cooldown_source_url
336
+ dependency_source_details&.fetch(:url, nil)
337
+ end
338
+
339
+ sig { override.returns(T::Array[Dependabot::Credential]) }
340
+ def cooldown_credentials
341
+ credentials
342
+ end
343
+
288
344
  private
289
345
 
290
346
  sig { returns(Dependabot::Dependency) }
@@ -689,7 +745,9 @@ module Dependabot
689
745
  source: T.must(source),
690
746
  credentials: credentials
691
747
  )
692
- client.releases(T.must(source).repo, per_page: 100)
748
+ # The Octokit RBI types this as non-nil, but it can be nil at runtime
749
+ # (e.g. an empty/unexpected registry response), so guard against it.
750
+ T.unsafe(client.releases(T.must(source).repo, per_page: 100)) || []
693
751
  rescue Octokit::Error
694
752
  []
695
753
  end,
@@ -712,6 +770,107 @@ module Dependabot
712
770
  T.must(T.must(name.match(VERSION_REGEX)).named_captures.fetch("version"))
713
771
  end
714
772
 
773
+ # Filters out git tags that are still within their cooldown window. Returns
774
+ # the candidate tags unchanged when cooldown does not apply (no options,
775
+ # disabled, or the dependency is excluded), and nil when every candidate tag
776
+ # is still within its cooldown window, so the caller proposes no update.
777
+ sig do
778
+ params(
779
+ candidate_tags: T::Array[Dependabot::GitRef],
780
+ cooldown_options: T.nilable(Dependabot::Package::ReleaseCooldownOptions)
781
+ ).returns(T.nilable(T::Array[Dependabot::GitRef]))
782
+ end
783
+ def apply_cooldown(candidate_tags, cooldown_options)
784
+ if Dependabot::UpdateCheckers::CooldownCalculation.skip_cooldown?(cooldown_options, dependency.name)
785
+ return candidate_tags
786
+ end
787
+
788
+ cooldown = T.must(cooldown_options)
789
+ filtered_tags = candidate_tags.reject { |tag| tag_in_cooldown_period?(tag, cooldown) }
790
+
791
+ if filtered_tags.empty? && candidate_tags.any?
792
+ Dependabot.logger.info(
793
+ "All git tags for #{dependency.name} are within their cooldown period; skipping update"
794
+ )
795
+ return nil
796
+ end
797
+
798
+ filtered_tags
799
+ end
800
+
801
+ sig do
802
+ params(tag: Dependabot::GitRef, cooldown: Dependabot::Package::ReleaseCooldownOptions)
803
+ .returns(T::Boolean)
804
+ end
805
+ def tag_in_cooldown_period?(tag, cooldown)
806
+ released_at = release_date_for_tag_name(tag.name)
807
+ return false unless released_at
808
+
809
+ cooldown_days = Dependabot::UpdateCheckers::CooldownCalculation.cooldown_days_for(
810
+ cooldown,
811
+ T.cast(current_version, T.nilable(Dependabot::Version)),
812
+ T.cast(version_from_tag(tag), Dependabot::Version)
813
+ )
814
+
815
+ in_cooldown = Dependabot::UpdateCheckers::CooldownCalculation
816
+ .within_cooldown_window?(released_at, cooldown_days)
817
+
818
+ if in_cooldown
819
+ passed_days = (Time.now.to_i - released_at.to_i) /
820
+ Dependabot::UpdateCheckers::CooldownCalculation::DAY_IN_SECONDS
821
+ Dependabot.logger.info(
822
+ "Filtered git tag #{tag.name} for #{dependency.name}: released " \
823
+ "#{released_at.strftime('%Y-%m-%d')} (#{passed_days}/#{cooldown_days} cooldown days)"
824
+ )
825
+ end
826
+
827
+ in_cooldown
828
+ end
829
+
830
+ # The allowed version tags may carry a "tags/" prefix (when the dependency
831
+ # is pinned via "tags/<ref>"), whereas refs_for_tag_with_detail returns the
832
+ # raw tag names, so we try both forms to line dates up regardless of prefix.
833
+ #
834
+ # A GitHub Release's published_at is preferred when available, falling back
835
+ # to the tag creation date from refs_for_tag_with_detail. This mirrors the
836
+ # priority used by Dependabot::GitCooldownDateResolver.
837
+ sig { params(tag_name: String).returns(T.nilable(Time)) }
838
+ def release_date_for_tag_name(tag_name)
839
+ normalized = normalize_tag_name(tag_name)
840
+
841
+ github_release_published_at(normalized) ||
842
+ release_dates_by_tag_name[tag_name] ||
843
+ release_dates_by_tag_name[normalized]
844
+ end
845
+
846
+ sig { returns(T::Hash[String, Time]) }
847
+ def release_dates_by_tag_name
848
+ @release_dates_by_tag_name ||= T.let(
849
+ build_release_dates_by_tag_name,
850
+ T.nilable(T::Hash[String, Time])
851
+ )
852
+ end
853
+
854
+ sig { returns(T::Hash[String, Time]) }
855
+ def build_release_dates_by_tag_name
856
+ dates = T.let({}, T::Hash[String, Time])
857
+ refs_for_tag_with_detail.each do |detail|
858
+ released_at = parse_release_date(detail.release_date)
859
+ dates[detail.tag] = released_at if released_at
860
+ end
861
+ dates
862
+ end
863
+
864
+ sig { params(release_date: T.nilable(String)).returns(T.nilable(Time)) }
865
+ def parse_release_date(release_date)
866
+ return nil if release_date.nil? || release_date.empty?
867
+
868
+ Time.parse(release_date)
869
+ rescue ArgumentError => e
870
+ Dependabot.logger.error("Invalid release date format: #{release_date} (#{e.message})")
871
+ nil
872
+ end
873
+
715
874
  sig { returns(T.class_of(Gem::Version)) }
716
875
  def version_class
717
876
  @version_class ||= T.let(
@@ -39,7 +39,7 @@ module Dependabot
39
39
  sig { returns(T.nilable(ReleaseCooldownOptions)) }
40
40
  attr_reader :cooldown_options
41
41
 
42
- sig { returns(T::Hash[Symbol, T.untyped]) }
42
+ sig { returns(T::Hash[Symbol, T.anything]) }
43
43
  attr_reader :options
44
44
 
45
45
  sig do
@@ -51,7 +51,7 @@ module Dependabot
51
51
  security_advisories: T::Array[Dependabot::SecurityAdvisory],
52
52
  cooldown_options: T.nilable(ReleaseCooldownOptions),
53
53
  raise_on_ignored: T::Boolean,
54
- options: T::Hash[Symbol, T.untyped]
54
+ options: T::Hash[Symbol, T.anything]
55
55
  ).void
56
56
  end
57
57
  def initialize(
@@ -335,7 +335,7 @@ module Dependabot
335
335
  end
336
336
  end
337
337
 
338
- sig { returns(T::Array[T.untyped]) }
338
+ sig { returns(T::Array[Dependabot::Requirement]) }
339
339
  def ignore_requirements
340
340
  ignored_versions.flat_map { |req| requirement_class.requirements_array(req) }
341
341
  end
@@ -24,7 +24,7 @@ module Dependabot
24
24
  package_type: T.nilable(String),
25
25
  language: T.nilable(Dependabot::Package::PackageLanguage),
26
26
  tag: T.nilable(String),
27
- details: T::Hash[String, T.untyped]
27
+ details: T::Hash[String, T.anything]
28
28
  ).void
29
29
  end
30
30
  def initialize(
@@ -50,7 +50,7 @@ module Dependabot
50
50
  @package_type = T.let(package_type, T.nilable(String))
51
51
  @language = T.let(language, T.nilable(Dependabot::Package::PackageLanguage))
52
52
  @tag = T.let(tag, T.nilable(String))
53
- @details = T.let(details, T::Hash[String, T.untyped])
53
+ @details = T.let(details, T::Hash[String, T.anything])
54
54
  end
55
55
 
56
56
  sig { returns(Dependabot::Version) }
@@ -83,7 +83,7 @@ module Dependabot
83
83
  sig { returns(T.nilable(String)) }
84
84
  attr_reader :tag
85
85
 
86
- sig { returns(T::Hash[String, T.untyped]) }
86
+ sig { returns(T::Hash[String, T.anything]) }
87
87
  attr_reader :details
88
88
 
89
89
  sig { returns(T::Boolean) }