dependabot-maven 0.385.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: 747f2adc558ba6bdd6ef7398f916407d5046ca6b3be8d59d410c66df01cc729a
4
- data.tar.gz: 16d1cfdad816dfc6a74054fc77d8387a770ac43336aa2b9f8e57c88edfad7ef9
3
+ metadata.gz: 34bb9f1bf25a1546076ede230d4054b240e40c06f05f0e1a217ad27590e10ad8
4
+ data.tar.gz: 92caf114f8fd30d9c2bf6a4cf0ffa6005633415053397d916e268ab87aec68cb
5
5
  SHA512:
6
- metadata.gz: bde79cece2c75a8c20d8fbde87e8c477b536e1dd0986aaf8741bfb3bfbb407ff0c594d2a13f6f0d525ec929e5d8d33e7c5311b9f52e78d23e2ee36d3dc77fea3
7
- data.tar.gz: ad7158fb4e4c40605f0b83c84589b9278d3c8d5eb9f791fffa6438d59a365a53001447a831a1463cfde8d763e3d2c9af4a6fe9df3f07d982410ae6ee1bce50a4
6
+ metadata.gz: a5c5b8fcb9851ddea7113a376c8f5980abada648aad11664465fd7ded2032c3c8d31be08bb86a2369086c7a658d46f4e5cc68eea149eb73f81e55ecc5cdcb48b
7
+ data.tar.gz: 5d7ab6749020ae57b53d0b4d0b8a52309acccbdafbd57202eb0c55ccd014b76b30a7cb2e6b61d1fc868f4807a3f202ae17f6b068c062d8b73f07a1530b400e83
@@ -67,17 +67,17 @@ module Dependabot
67
67
  params(
68
68
  pom: Dependabot::DependencyFile,
69
69
  dependency_set: Dependabot::FileParsers::Base::DependencySet,
70
- dependency_tree: T::Hash[String, T.untyped]
70
+ dependency_tree: T::Hash[String, Object]
71
71
  ).void
72
72
  end
73
73
  def self.extract_dependencies_from_tree(pom, dependency_set, dependency_tree)
74
- traverse_tree = T.let(-> {}, T.proc.params(node: T::Hash[String, T.untyped]).void)
74
+ traverse_tree = T.let(-> {}, T.proc.params(node: T::Hash[String, Object]).void)
75
75
  traverse_tree = lambda do |node|
76
76
  artifact_id = node["artifactId"]
77
77
  group_id = node["groupId"]
78
78
  version = node["version"]
79
79
  type = node["type"]
80
- classifier = node["classifier"].to_s.empty? ? nil : node["classifier"]
80
+ classifier = node["classifier"].to_s.empty? ? nil : node["classifier"].to_s
81
81
  scope = node["scope"]
82
82
 
83
83
  groups = scope == "test" ? ["test"] : []
@@ -98,7 +98,8 @@ module Dependabot
98
98
  }]
99
99
  )
100
100
 
101
- node["children"]&.each(&traverse_tree)
101
+ children = node["children"]
102
+ children.each { |child| traverse_tree.call(child) } if children.is_a?(Array)
102
103
  end
103
104
 
104
105
  traverse_tree.call(dependency_tree)
@@ -21,6 +21,9 @@ module Dependabot
21
21
 
22
22
  DOT_SEPARATOR_REGEX = %r{\.(?!\d+([.\/_\-]|$)+)}
23
23
  MAVEN_PROPERTY_REGEX = /\$\{.+?/
24
+ PropertyDetails = T.type_alias do
25
+ T::Hash[Symbol, T.any(String, Nokogiri::XML::Node)]
26
+ end
24
27
 
25
28
  sig do
26
29
  params(
@@ -44,7 +47,7 @@ module Dependabot
44
47
  property_name: String,
45
48
  callsite_pom: DependencyFile,
46
49
  seen_properties: T::Set[String]
47
- ).returns(T.nilable(T::Hash[Symbol, T.untyped]))
50
+ ).returns(T.nilable(PropertyDetails))
48
51
  end
49
52
  def property_details(property_name:, callsite_pom:, seen_properties: Set.new)
50
53
  pom = callsite_pom
@@ -115,9 +118,9 @@ module Dependabot
115
118
  content: String,
116
119
  callsite_pom: DependencyFile,
117
120
  pom: DependencyFile,
118
- node: T.untyped,
121
+ node: Nokogiri::XML::Node,
119
122
  seen_properties: T::Set[String]
120
- ).returns(T.nilable(T::Hash[Symbol, T.untyped]))
123
+ ).returns(T.nilable(PropertyDetails))
121
124
  end
122
125
  def resolve_property_placeholder(content, callsite_pom, pom, node, seen_properties)
123
126
  resolved_value = content.gsub(/\$\{(.+?)}/) do
@@ -24,6 +24,7 @@ module Dependabot
24
24
 
25
25
  REPOSITORY_SELECTOR = "repositories > repository, " \
26
26
  "pluginRepositories > pluginRepository"
27
+ RepositoryEntry = T.type_alias { T::Hash[Symbol, T.nilable(T.any(String, T::Boolean))] }
27
28
 
28
29
  sig do
29
30
  params(
@@ -44,7 +45,7 @@ module Dependabot
44
45
  @evaluate_properties = evaluate_properties
45
46
  # Aggregates URLs seen in POMs to avoid short term memory loss.
46
47
  # For instance a repository in a child POM might apply to the parent too.
47
- @known_urls = T.let([], T::Array[T::Hash[Symbol, T.untyped]])
48
+ @known_urls = T.let([], T::Array[RepositoryEntry])
48
49
  @property_value_finder = T.let(nil, T.nilable(PropertyValueFinder))
49
50
  end
50
51
 
@@ -75,7 +76,7 @@ module Dependabot
75
76
  @known_urls = @known_urls.uniq
76
77
 
77
78
  urls = urls_from_credentials + @known_urls.reject { |entry| exclude_snapshots && entry[:snapshots] }
78
- .map { |entry| entry[:url] }
79
+ .map { |entry| T.must(entry[:url]).to_s }
79
80
  urls += [central_repo_url] unless @known_urls.any? { |entry| entry[:id] == super_pom[:id] }
80
81
  urls.uniq
81
82
  end
@@ -102,26 +103,26 @@ module Dependabot
102
103
  }
103
104
  end
104
105
 
105
- sig { params(entry: T::Hash[Symbol, T.untyped]).returns(T::Boolean) }
106
+ sig { params(entry: RepositoryEntry).returns(T::Boolean) }
106
107
  def disabled_repo?(entry)
107
108
  entry[:releases] == "false" && entry[:snapshots] == "false"
108
109
  end
109
110
 
110
- sig { params(entry: T::Hash[Symbol, T.untyped]).returns(T::Boolean) }
111
+ sig { params(entry: RepositoryEntry).returns(T::Boolean) }
111
112
  def snapshot_repo(entry)
112
113
  entry[:releases] == "false" && (entry[:snapshots].nil? || entry[:snapshots] == "true")
113
114
  end
114
115
 
115
116
  sig do
116
117
  params(
117
- entry: T::Hash[Symbol, T.untyped],
118
+ entry: RepositoryEntry,
118
119
  pom: Dependabot::DependencyFile
119
120
  )
120
- .returns(T::Hash[Symbol, T.untyped])
121
+ .returns(RepositoryEntry)
121
122
  end
122
123
  def serialize_urls(entry, pom)
123
124
  {
124
- url: evaluated_value(entry[:url], pom).gsub(%r{/$}, ""),
125
+ url: evaluated_value(T.must(entry[:url]).to_s, pom).gsub(%r{/$}, ""),
125
126
  id: entry[:id],
126
127
  snapshots: snapshot_repo(entry)
127
128
  }
@@ -132,7 +133,7 @@ module Dependabot
132
133
  pom: Dependabot::DependencyFile,
133
134
  exclude_inherited: T::Boolean
134
135
  )
135
- .returns(T::Array[T::Hash[Symbol, T.untyped]])
136
+ .returns(T::Array[RepositoryEntry])
136
137
  end
137
138
  def gather_repository_urls(pom:, exclude_inherited: false)
138
139
  repos = repositories_from_pom(pom)
@@ -148,7 +149,7 @@ module Dependabot
148
149
  params(
149
150
  pom: Dependabot::DependencyFile
150
151
  ).returns(
151
- T::Array[T::Hash[Symbol, T.untyped]]
152
+ T::Array[RepositoryEntry]
152
153
  )
153
154
  end
154
155
  def repositories_from_pom(pom)
@@ -163,7 +164,7 @@ module Dependabot
163
164
  params(
164
165
  node: Nokogiri::XML::Node,
165
166
  pom: Dependabot::DependencyFile
166
- ).returns(T.nilable(T::Hash[Symbol, T.untyped]))
167
+ ).returns(T.nilable(RepositoryEntry))
167
168
  end
168
169
  def build_repo_entry(node, pom)
169
170
  url = node.at_css("url")&.text&.strip.to_s
@@ -183,19 +184,20 @@ module Dependabot
183
184
  contains_property?(T.must(entry.fetch(:url))) && !evaluate_properties?
184
185
  end
185
186
 
186
- sig { params(entry: T::Hash[Symbol, T.untyped]).returns(T::Boolean) }
187
+ sig { params(entry: RepositoryEntry).returns(T::Boolean) }
187
188
  def http_url?(entry)
188
- entry.fetch(:url)&.start_with?("http")
189
+ url = entry.fetch(:url)
190
+ url.is_a?(String) && url.start_with?("http")
189
191
  end
190
192
 
191
193
  sig do
192
194
  params(
193
195
  pom: Dependabot::DependencyFile,
194
- repos: T::Array[T::Hash[Symbol, T.untyped]]
196
+ repos: T::Array[RepositoryEntry]
195
197
  ).returns(T.nilable(Dependabot::DependencyFile))
196
198
  end
197
199
  def parent_with_repositories(pom, repos)
198
- urls = repos.map { |r| r[:url] }
200
+ urls = repos.map { |r| T.must(r[:url]).to_s }
199
201
  parent_pom(pom, urls)
200
202
  end
201
203
 
@@ -240,10 +242,10 @@ module Dependabot
240
242
  # rubocop:disable Metrics/PerceivedComplexity
241
243
  sig do
242
244
  params(
243
- pom: T.untyped,
245
+ pom: Dependabot::DependencyFile,
244
246
  repo_urls: T::Array[String]
245
247
  )
246
- .returns(T.untyped)
248
+ .returns(T.nilable(Dependabot::DependencyFile))
247
249
  end
248
250
  def parent_pom(pom, repo_urls)
249
251
  doc = Nokogiri::XML(pom.content)
@@ -280,13 +282,13 @@ module Dependabot
280
282
  value.match?(property_regex)
281
283
  end
282
284
 
283
- sig { params(value: String, pom: Dependabot::DependencyFile).returns(T.untyped) }
285
+ sig { params(value: String, pom: Dependabot::DependencyFile).returns(String) }
284
286
  def evaluated_value(value, pom)
285
287
  return value unless contains_property?(value)
286
288
 
287
289
  match_data = value.match(property_regex)
288
- property_name = T.must(match_data).named_captures.fetch("property")
289
- property_value = value_for_property(T.cast(property_name, String), pom)
290
+ property_name = T.must(T.must(match_data).named_captures.fetch("property"))
291
+ property_value = value_for_property(property_name, pom)
290
292
 
291
293
  value.gsub(property_regex, property_value)
292
294
  end
@@ -300,7 +302,7 @@ module Dependabot
300
302
  callsite_pom: pom
301
303
  )&.fetch(:value)
302
304
 
303
- return value if value
305
+ return value if value.is_a?(String)
304
306
 
305
307
  msg = "Property not found: #{property_name}"
306
308
  raise DependencyFileNotEvaluatable, msg
@@ -415,7 +415,7 @@ module Dependabot
415
415
  .property_details(property_name: property_name, callsite_pom: pom)
416
416
  &.fetch(:file)
417
417
 
418
- return declaring_pom if declaring_pom
418
+ return declaring_pom if declaring_pom.is_a?(String)
419
419
 
420
420
  msg = "Property not found: #{property_name}"
421
421
  raise DependencyFileNotEvaluatable, msg
@@ -428,7 +428,7 @@ module Dependabot
428
428
  .property_details(property_name: property_name, callsite_pom: pom)
429
429
  &.fetch(:value)
430
430
 
431
- return value if value
431
+ return value if value.is_a?(String)
432
432
 
433
433
  msg = "Property not found: #{property_name}"
434
434
  raise DependencyFileNotEvaluatable, msg
@@ -497,7 +497,8 @@ module Dependabot
497
497
  # so we know when certain requirement not a literal value and can differentiate transitive dependencies
498
498
  # from direct dependencies.
499
499
  sig do
500
- params(requirements: T::Array[T::Hash[Symbol, T.untyped]]).returns(T::Array[T::Hash[Symbol, T.untyped]])
500
+ params(requirements: T::Array[Dependabot::DependencyRequirement])
501
+ .returns(T::Array[Dependabot::DependencyRequirement])
501
502
  end
502
503
  def merge_requirements(requirements)
503
504
  return requirements if requirements.length <= 1
@@ -528,7 +529,7 @@ module Dependabot
528
529
  metadata: merge_metadata(dep_scan_req[:metadata], parsing_req[:metadata])
529
530
  }
530
531
 
531
- merged << merged_req
532
+ merged << Dependabot::DependencyRequirement.create(merged_req)
532
533
  used_indices.add(i)
533
534
  used_indices.add(match_index)
534
535
  else
@@ -544,9 +545,9 @@ module Dependabot
544
545
  # Merge metadata from two requirements, combining all keys
545
546
  sig do
546
547
  params(
547
- metadata1: T::Hash[Symbol, T.untyped],
548
- metadata2: T::Hash[Symbol, T.untyped]
549
- ).returns(T::Hash[Symbol, T.untyped])
548
+ metadata1: T::Hash[Symbol, Object],
549
+ metadata2: T::Hash[Symbol, Object]
550
+ ).returns(T::Hash[Symbol, Object])
550
551
  end
551
552
  def merge_metadata(metadata1, metadata2)
552
553
  metadata1.merge(metadata2) do |_key, old_value, new_value|
@@ -20,11 +20,12 @@ module Dependabot
20
20
  <path>.*?</path>|
21
21
  <artifactItem>.*?</artifactItem>
22
22
  }mx
23
+ Requirement = T.type_alias { T.any(Dependabot::DependencyRequirement, T::Hash[Symbol, Object]) }
23
24
 
24
25
  sig { returns(Dependabot::Dependency) }
25
26
  attr_reader :dependency
26
27
 
27
- sig { returns(T::Hash[Symbol, T.untyped]) }
28
+ sig { returns(Requirement) }
28
29
  attr_reader :declaring_requirement
29
30
 
30
31
  sig { returns(T::Array[Dependabot::DependencyFile]) }
@@ -34,7 +35,7 @@ module Dependabot
34
35
  params(
35
36
  dependency: Dependabot::Dependency,
36
37
  dependency_files: T::Array[Dependabot::DependencyFile],
37
- declaring_requirement: T::Hash[Symbol, T.untyped]
38
+ declaring_requirement: Requirement
38
39
  ).void
39
40
  end
40
41
  def initialize(dependency:, dependency_files:, declaring_requirement:)
@@ -191,7 +192,7 @@ module Dependabot
191
192
  callsite_pom: declaring_pom
192
193
  )&.fetch(:value)
193
194
 
194
- return value unless property_value
195
+ return value unless property_value.is_a?(String)
195
196
 
196
197
  value.gsub(
197
198
  match_data.to_s,
@@ -35,6 +35,7 @@ module Dependabot
35
35
  )
36
36
  node = declaration_details&.fetch(:node)
37
37
  filename = declaration_details&.fetch(:file)
38
+ raise "Property node not found" unless node.is_a?(Nokogiri::XML::Node)
38
39
 
39
40
  pom_to_update = dependency_files.find { |f| f.name == filename }
40
41
  property_re = %r{<#{Regexp.quote(node.name)}>
@@ -15,6 +15,10 @@ module Dependabot
15
15
  require_relative "file_updater/declaration_finder"
16
16
  require_relative "file_updater/property_value_updater"
17
17
 
18
+ IndentConfig = T.type_alias do
19
+ { base: String, is_tabs: T::Boolean, levels: T::Hash[Symbol, String] }
20
+ end
21
+
18
22
  sig { override.returns(T::Array[Dependabot::DependencyFile]) }
19
23
  def updated_dependency_files
20
24
  updated_files = T.let(dependency_files.dup, T::Array[Dependabot::DependencyFile])
@@ -86,7 +90,7 @@ module Dependabot
86
90
  sig do
87
91
  params(
88
92
  pomfiles: T::Array[Dependabot::DependencyFile],
89
- req: T::Hash[Symbol, T.untyped]
93
+ req: Dependabot::DependencyRequirement
90
94
  )
91
95
  .returns(T::Array[Dependabot::DependencyFile])
92
96
  end
@@ -105,8 +109,8 @@ module Dependabot
105
109
  params(
106
110
  dependency: Dependabot::Dependency,
107
111
  file: Dependabot::DependencyFile,
108
- previous_req: T::Hash[Symbol, T.untyped],
109
- requirement: T::Hash[Symbol, T.untyped]
112
+ previous_req: Dependabot::DependencyRequirement,
113
+ requirement: Dependabot::DependencyRequirement
110
114
  )
111
115
  .returns(Dependabot::DependencyFile)
112
116
  end
@@ -137,7 +141,7 @@ module Dependabot
137
141
  params(
138
142
  content: String,
139
143
  dependency: Dependabot::Dependency,
140
- requirement: T::Hash[Symbol, T.untyped]
144
+ requirement: Dependabot::DependencyRequirement
141
145
  ).returns(String)
142
146
  end
143
147
  def add_new_declaration(content, dependency, requirement) # rubocop:disable Metrics/AbcSize
@@ -190,7 +194,7 @@ module Dependabot
190
194
  params(
191
195
  dep: Dependabot::Dependency,
192
196
  pom: Dependabot::DependencyFile,
193
- req: T::Hash[Symbol, T.untyped]
197
+ req: Dependabot::DependencyRequirement
194
198
  )
195
199
  .returns(Dependabot::DependencyFile)
196
200
  end
@@ -216,7 +220,7 @@ module Dependabot
216
220
  sig do
217
221
  params(
218
222
  dependency: Dependabot::Dependency,
219
- requirement: T::Hash[Symbol, T.untyped]
223
+ requirement: Dependabot::DependencyRequirement
220
224
  )
221
225
  .returns(T::Array[String])
222
226
  end
@@ -227,7 +231,7 @@ module Dependabot
227
231
  sig do
228
232
  params(
229
233
  dependency: Dependabot::Dependency,
230
- requirement: T::Hash[Symbol, T.untyped]
234
+ requirement: Dependabot::DependencyRequirement
231
235
  )
232
236
  .returns(DeclarationFinder)
233
237
  end
@@ -244,8 +248,8 @@ module Dependabot
244
248
  sig do
245
249
  params(
246
250
  old_declaration: String,
247
- previous_req: T::Hash[Symbol, T.untyped],
248
- requirement: T::Hash[Symbol, T.untyped]
251
+ previous_req: Dependabot::DependencyRequirement,
252
+ requirement: Dependabot::DependencyRequirement
249
253
  )
250
254
  .returns(String)
251
255
  end
@@ -269,7 +273,7 @@ module Dependabot
269
273
  sig do
270
274
  params(
271
275
  project: REXML::Element,
272
- indent_config: T::Hash[Symbol, T.untyped]
276
+ indent_config: IndentConfig
273
277
  ).returns([REXML::Element, T::Boolean])
274
278
  end
275
279
  def ensure_dependency_management_element(project, indent_config)
@@ -288,7 +292,7 @@ module Dependabot
288
292
  sig do
289
293
  params(
290
294
  dependency_management: REXML::Element,
291
- indent_config: T::Hash[Symbol, T.untyped]
295
+ indent_config: IndentConfig
292
296
  ).returns([REXML::Element, T::Boolean])
293
297
  end
294
298
  def ensure_dependencies_element(dependency_management, indent_config)
@@ -307,7 +311,7 @@ module Dependabot
307
311
  sig do
308
312
  params(
309
313
  dependency: Dependabot::Dependency,
310
- requirement: T::Hash[Symbol, T.untyped],
314
+ requirement: Dependabot::DependencyRequirement,
311
315
  dependencies_node: REXML::Element,
312
316
  current_indentation_level: String,
313
317
  parent_indentation_level: String
@@ -343,7 +347,7 @@ module Dependabot
343
347
  end
344
348
  end
345
349
 
346
- sig { params(project: REXML::Element).returns(T::Hash[Symbol, T.untyped]) }
350
+ sig { params(project: REXML::Element).returns(IndentConfig) }
347
351
  def detect_indentation_config(project)
348
352
  sample_indent = project.children.find do |child|
349
353
  child.to_s.match?(/\n(\t+| +)$/)
@@ -31,9 +31,9 @@ module Dependabot
31
31
  @dependency_files = T.let(dependency_files, T::Array[Dependabot::DependencyFile])
32
32
  @credentials = T.let(credentials, T::Array[Dependabot::Credential])
33
33
 
34
- @pom_repository_details = T.let(nil, T.nilable(T::Array[T::Hash[String, T.untyped]]))
34
+ @pom_repository_details = T.let(nil, T.nilable(T::Array[RepositoryDetails]))
35
35
  @repository_finder = T.let(nil, T.nilable(Maven::FileParser::RepositoriesFinder))
36
- @repositories_cache = T.let(nil, T.nilable(T::Array[T::Hash[String, T.untyped]]))
36
+ @repositories_cache = T.let(nil, T.nilable(T::Array[RepositoryDetails]))
37
37
  @package_details = T.let(nil, T.nilable(Dependabot::Package::PackageDetails))
38
38
  end
39
39
 
@@ -66,13 +66,13 @@ module Dependabot
66
66
  @package_details
67
67
  end
68
68
 
69
- sig { returns(T::Array[T.untyped]) }
69
+ sig { returns(T::Array[Dependabot::Package::PackageRelease]) }
70
70
  def releases
71
71
  fetch.releases
72
72
  end
73
73
 
74
74
  # Assembles the list of Maven repositories to search: credential repos + POM repos.
75
- sig { override.returns(T::Array[T::Hash[String, T.untyped]]) }
75
+ sig { override.returns(T::Array[RepositoryDetails]) }
76
76
  def repositories
77
77
  return @repositories_cache if @repositories_cache
78
78
 
@@ -107,7 +107,7 @@ module Dependabot
107
107
  end
108
108
 
109
109
  # Returns the repository details for the POM file.
110
- sig { returns(T::Array[T::Hash[String, T.untyped]]) }
110
+ sig { returns(T::Array[RepositoryDetails]) }
111
111
  def pom_repository_details
112
112
  return @pom_repository_details if @pom_repository_details
113
113
 
@@ -21,13 +21,20 @@ module Dependabot
21
21
  (package_details&.releases || []).reverse
22
22
  end
23
23
 
24
- sig { returns(T.nilable(T::Hash[T.untyped, T.untyped])) }
24
+ VersionDetails = T.type_alias do
25
+ {
26
+ version: Dependabot::Version,
27
+ source_url: T.nilable(String)
28
+ }
29
+ end
30
+
31
+ sig { returns(T.nilable(VersionDetails)) }
25
32
  def latest_version_details
26
33
  release = fetch_latest_release
27
34
  release&.version ? { version: release.version, source_url: release.url } : nil
28
35
  end
29
36
 
30
- sig { returns(T.nilable(T::Hash[T.untyped, T.untyped])) }
37
+ sig { returns(T.nilable(VersionDetails)) }
31
38
  def lowest_security_fix_version_details
32
39
  release = fetch_lowest_security_fix_release
33
40
  release&.version ? { version: release.version, source_url: release.url } : nil
@@ -0,0 +1,29 @@
1
+ # typed: strong
2
+ # frozen_string_literal: true
3
+
4
+ require "sorbet-runtime"
5
+ require "dependabot/dependency_file"
6
+
7
+ module Dependabot
8
+ module Maven
9
+ module Shared
10
+ # Interface implemented by the ecosystem-specific PropertyValueFinder
11
+ # classes (Gradle, SBT) that SharedPropertyValueUpdater delegates to.
12
+ # Living in the shared namespace keeps the abstract return type load-safe:
13
+ # each ecosystem gem loads Maven's shared code without loading its sibling.
14
+ module PropertyValueFinding
15
+ extend T::Sig
16
+ extend T::Helpers
17
+
18
+ interface!
19
+
20
+ sig do
21
+ abstract
22
+ .params(property_name: String, callsite_buildfile: Dependabot::DependencyFile)
23
+ .returns(T.nilable(T::Hash[Symbol, String]))
24
+ end
25
+ def property_details(property_name:, callsite_buildfile:); end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -22,6 +22,15 @@ module Dependabot
22
22
  URL_KEY = T.let("url", String)
23
23
  AUTH_HEADERS_KEY = T.let("auth_headers", String)
24
24
  DEFAULT_CENTRAL_REPO_URL = T.let("https://repo.maven.apache.org/maven2", String)
25
+ RepositoryDetails = T.type_alias { T::Hash[String, T.any(String, T::Hash[String, String])] }
26
+ VersionDetails = T.type_alias do
27
+ {
28
+ version: Dependabot::Version,
29
+ source_url: String,
30
+ release_date: T.nilable(Time)
31
+ }
32
+ end
33
+ HtmlVersionDetails = T.type_alias { { release_date: T.nilable(Time) } }
25
34
 
26
35
  sig { abstract.returns(Dependabot::Dependency) }
27
36
  def dependency; end
@@ -31,7 +40,7 @@ module Dependabot
31
40
 
32
41
  # Subclasses must define how repositories are assembled.
33
42
  # Typically: credentials_repository_details + ecosystem-specific repos.
34
- sig { abstract.returns(T::Array[T::Hash[String, T.untyped]]) }
43
+ sig { abstract.returns(T::Array[RepositoryDetails]) }
35
44
  def repositories; end
36
45
 
37
46
  # -- URL Construction --
@@ -93,10 +102,10 @@ module Dependabot
93
102
  # -- Metadata Fetching (XML) --
94
103
 
95
104
  # Fetches and parses maven-metadata.xml from a repository.
96
- sig { params(repository_details: T::Hash[String, T.untyped]).returns(T.nilable(Nokogiri::XML::Document)) }
105
+ sig { params(repository_details: RepositoryDetails).returns(T.nilable(Nokogiri::XML::Document)) }
97
106
  def fetch_dependency_metadata(repository_details)
98
- url = repository_details.fetch(URL_KEY)
99
- headers = repository_details.fetch(AUTH_HEADERS_KEY)
107
+ url = repository_url(repository_details)
108
+ headers = repository_auth_headers(repository_details)
100
109
  response = Dependabot::RegistryClient.get(
101
110
  url: dependency_metadata_url(url),
102
111
  headers: headers
@@ -109,7 +118,7 @@ module Dependabot
109
118
  nil
110
119
  rescue Excon::Error::Socket, Excon::Error::Timeout,
111
120
  Excon::Error::TooManyRedirects => e
112
- handle_registry_error(url, e, response)
121
+ handle_registry_error(T.must(url), e, response)
113
122
  nil
114
123
  end
115
124
 
@@ -118,24 +127,24 @@ module Dependabot
118
127
  params(
119
128
  xml: Nokogiri::XML::Document,
120
129
  url: String
121
- ).returns(T::Array[T::Hash[Symbol, T.untyped]])
130
+ ).returns(T::Array[VersionDetails])
122
131
  end
123
132
  def extract_metadata_from_xml(xml, url)
124
133
  xml.css("versions > version")
125
134
  .select { |node| version_class.correct?(node.content) }
126
135
  .map { |node| version_class.new(node.content) }
127
- .map { |version| { version: version, source_url: url } }
136
+ .map { |version| { version: version, source_url: url, release_date: nil } }
128
137
  end
129
138
 
130
139
  # -- Metadata Fetching (HTML directory listing) --
131
140
 
132
141
  # Fetches an HTML directory listing page from a repository.
133
142
  sig do
134
- params(repository_details: T::Hash[String, T.untyped]).returns(T.nilable(Nokogiri::HTML::Document))
143
+ params(repository_details: RepositoryDetails).returns(T.nilable(Nokogiri::HTML::Document))
135
144
  end
136
145
  def fetch_dependency_metadata_from_html(repository_details)
137
- url = repository_details.fetch(URL_KEY)
138
- headers = repository_details.fetch(AUTH_HEADERS_KEY)
146
+ url = repository_url(repository_details)
147
+ headers = repository_auth_headers(repository_details)
139
148
  # Add trailing slash for directory listing
140
149
  base_directory_url = dependency_base_url(url)
141
150
  base_directory_url += "/" unless base_directory_url.end_with?("/")
@@ -151,17 +160,17 @@ module Dependabot
151
160
  nil
152
161
  rescue Excon::Error::Socket, Excon::Error::Timeout,
153
162
  Excon::Error::TooManyRedirects => e
154
- handle_registry_error(url, e, response)
163
+ handle_registry_error(T.must(url), e, response)
155
164
  nil
156
165
  end
157
166
 
158
167
  # Parses release dates from an HTML directory listing page.
159
168
  sig do
160
169
  params(html_doc: Nokogiri::HTML::Document)
161
- .returns(T::Hash[String, T::Hash[Symbol, T.untyped]])
170
+ .returns(T::Hash[String, HtmlVersionDetails])
162
171
  end
163
172
  def extract_version_details_from_html(html_doc)
164
- versions_detail_hash = T.let({}, T::Hash[String, T::Hash[Symbol, T.untyped]])
173
+ versions_detail_hash = T.let({}, T::Hash[String, HtmlVersionDetails])
165
174
 
166
175
  html_doc.css("a[href]").each do |link|
167
176
  version = extract_version_from_link(link)
@@ -239,9 +248,9 @@ module Dependabot
239
248
  # Aggregates version details from XML metadata and enriches with
240
249
  # release dates from HTML directory listings. Returns a sorted array
241
250
  # of version detail hashes.
242
- sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
251
+ sig { returns(T::Array[VersionDetails]) }
243
252
  def versions
244
- @version_details = T.let(@version_details, T.nilable(T::Array[T::Hash[Symbol, T.untyped]]))
253
+ @version_details = T.let(@version_details, T.nilable(T::Array[VersionDetails]))
245
254
  return @version_details if @version_details
246
255
 
247
256
  @version_details = versions_details_from_xml
@@ -276,11 +285,11 @@ module Dependabot
276
285
  end
277
286
 
278
287
  # Fetches version details from maven-metadata.xml across all repositories.
279
- sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
288
+ sig { returns(T::Array[VersionDetails]) }
280
289
  def versions_details_from_xml
281
290
  forbidden_urls.clear
282
291
  version_details = repositories.flat_map do |repository_details|
283
- url = repository_details.fetch(URL_KEY)
292
+ url = repository_url(repository_details)
284
293
  xml = dependency_metadata(repository_details)
285
294
  next [] if xml.nil?
286
295
 
@@ -293,12 +302,12 @@ module Dependabot
293
302
  end
294
303
 
295
304
  # Fetches version details (release dates) from HTML directory listings.
296
- sig { returns(T::Hash[String, T::Hash[Symbol, T.untyped]]) }
305
+ sig { returns(T::Hash[String, HtmlVersionDetails]) }
297
306
  def versions_details_hash_from_html
298
307
  forbidden_urls.clear
299
308
 
300
309
  versions_detail_hash = T.let(
301
- {}, T::Hash[String, T::Hash[Symbol, T.untyped]]
310
+ {}, T::Hash[String, HtmlVersionDetails]
302
311
  )
303
312
  repositories.each do |repository_details|
304
313
  html = dependency_metadata_from_html(repository_details)
@@ -328,8 +337,8 @@ module Dependabot
328
337
 
329
338
  @released_check[version] =
330
339
  repositories.any? do |repository_details|
331
- url = repository_details.fetch(URL_KEY)
332
- headers = repository_details.fetch(AUTH_HEADERS_KEY)
340
+ url = repository_url(repository_details)
341
+ headers = repository_auth_headers(repository_details)
333
342
  response = Dependabot::RegistryClient.head(
334
343
  url: dependency_files_url(url, version),
335
344
  headers: headers
@@ -359,7 +368,7 @@ module Dependabot
359
368
  # -- Credential & Repository Helpers --
360
369
 
361
370
  # Builds repository details from credentials of type "maven_repository".
362
- sig { returns(T::Array[T::Hash[String, T.untyped]]) }
371
+ sig { returns(T::Array[RepositoryDetails]) }
363
372
  def credentials_repository_details
364
373
  credentials
365
374
  .select { |cred| cred["type"] == REPOSITORY_TYPE && cred[URL_KEY] }
@@ -398,6 +407,22 @@ module Dependabot
398
407
  auth_headers_finder.auth_headers(maven_repo_url)
399
408
  end
400
409
 
410
+ sig { params(repository_details: RepositoryDetails).returns(String) }
411
+ def repository_url(repository_details)
412
+ url = repository_details.fetch(URL_KEY)
413
+ return url if url.is_a?(String)
414
+
415
+ raise "Repository URL must be a string"
416
+ end
417
+
418
+ sig { params(repository_details: RepositoryDetails).returns(T::Hash[String, String]) }
419
+ def repository_auth_headers(repository_details)
420
+ headers = repository_details.fetch(AUTH_HEADERS_KEY)
421
+ return headers if headers.is_a?(Hash)
422
+
423
+ raise "Repository auth headers must be a hash"
424
+ end
425
+
401
426
  sig { returns(Utils::AuthHeadersFinder) }
402
427
  def auth_headers_finder
403
428
  @auth_headers_finder ||= T.let(Utils::AuthHeadersFinder.new(credentials), T.nilable(Utils::AuthHeadersFinder))
@@ -406,10 +431,10 @@ module Dependabot
406
431
  # -- Metadata Caching --
407
432
 
408
433
  # Fetches and caches XML metadata per repository.
409
- sig { params(repository_details: T::Hash[String, T.untyped]).returns(T.nilable(Nokogiri::XML::Document)) }
434
+ sig { params(repository_details: RepositoryDetails).returns(T.nilable(Nokogiri::XML::Document)) }
410
435
  def dependency_metadata(repository_details)
411
436
  @dependency_metadata = T.let(
412
- @dependency_metadata, T.nilable(T::Hash[T.untyped, Nokogiri::XML::Document])
437
+ @dependency_metadata, T.nilable(T::Hash[Integer, Nokogiri::XML::Document])
413
438
  )
414
439
  @dependency_metadata ||= {}
415
440
  repository_key = repository_details.hash
@@ -421,10 +446,10 @@ module Dependabot
421
446
  end
422
447
 
423
448
  # Fetches and caches HTML metadata per repository.
424
- sig { params(repository_details: T::Hash[String, T.untyped]).returns(T.nilable(Nokogiri::HTML::Document)) }
449
+ sig { params(repository_details: RepositoryDetails).returns(T.nilable(Nokogiri::HTML::Document)) }
425
450
  def dependency_metadata_from_html(repository_details)
426
451
  @dependency_metadata_from_html = T.let(
427
- @dependency_metadata_from_html, T.nilable(T::Hash[T.untyped, Nokogiri::HTML::Document])
452
+ @dependency_metadata_from_html, T.nilable(T::Hash[Integer, Nokogiri::HTML::Document])
428
453
  )
429
454
  @dependency_metadata_from_html ||= {}
430
455
  repository_key = repository_details.hash
@@ -1,8 +1,9 @@
1
- # typed: strict
1
+ # typed: strong
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "sorbet-runtime"
5
5
  require "dependabot/dependency_file"
6
+ require "dependabot/maven/shared/property_value_finding"
6
7
 
7
8
  module Dependabot
8
9
  module Maven
@@ -67,7 +68,7 @@ module Dependabot
67
68
  sig { returns(T::Array[DependencyFile]) }
68
69
  attr_reader :dependency_files
69
70
 
70
- sig { abstract.returns(T.untyped) }
71
+ sig { abstract.returns(Dependabot::Maven::Shared::PropertyValueFinding) }
71
72
  def property_value_finder; end
72
73
 
73
74
  sig { params(previous_value: String).returns(Regexp) }
@@ -22,7 +22,7 @@ module Dependabot
22
22
  sig { abstract.returns(Regexp) }
23
23
  def self.ruby_style_pattern; end
24
24
 
25
- sig { params(requirements: T.untyped).void }
25
+ sig { params(requirements: T.nilable(String)).void }
26
26
  def initialize(*requirements)
27
27
  requirements = requirements.flatten.flat_map do |req_string|
28
28
  convert_java_constraint_to_ruby_constraint(req_string)
@@ -13,14 +13,15 @@ module Dependabot
13
13
  extend T::Helpers
14
14
  include Comparable
15
15
 
16
- prop :tokens, T::Array[T.untyped]
16
+ prop :tokens, T::Array[Object]
17
17
  prop :addition, T.nilable(TokenBucket)
18
18
 
19
- sig { returns(T::Array[T.untyped]) }
19
+ sig { returns(T::Array[Object]) }
20
20
  def to_a
21
21
  return tokens if addition.nil?
22
22
 
23
- tokens.clone.append(addition.to_a)
23
+ result = T.let(tokens.clone, T::Array[Object])
24
+ result.append(addition.to_a)
24
25
  end
25
26
 
26
27
  sig { params(other: TokenBucket).returns(T.nilable(Integer)) }
@@ -33,8 +34,8 @@ module Dependabot
33
34
 
34
35
  sig do
35
36
  params(
36
- first: T::Array[T.any(String, Integer)],
37
- second: T::Array[T.any(String, Integer)]
37
+ first: T::Array[Object],
38
+ second: T::Array[Object]
38
39
  ).returns(T.nilable(Integer))
39
40
  end
40
41
  def compare_tokens(first, second)
@@ -48,8 +49,8 @@ module Dependabot
48
49
 
49
50
  sig do
50
51
  params(
51
- first: T.nilable(T.any(String, Integer)),
52
- second: T.nilable(T.any(String, Integer))
52
+ first: T.nilable(Object),
53
+ second: T.nilable(Object)
53
54
  ).returns(T.nilable(Integer))
54
55
  end
55
56
  def compare_token_pair(first = 0, second = 0) # rubocop:disable Metrics/PerceivedComplexity,Metrics/CyclomaticComplexity
@@ -22,7 +22,7 @@ module Dependabot
22
22
  dependency_files: T::Array[Dependabot::DependencyFile],
23
23
  credentials: T::Array[Dependabot::Credential],
24
24
  ignored_versions: T::Array[String],
25
- target_version_details: T.nilable(T::Hash[T.untyped, T.untyped]),
25
+ target_version_details: T.nilable(UpdateChecker::VersionDetails),
26
26
  update_cooldown: T.nilable(Dependabot::Package::ReleaseCooldownOptions)
27
27
  ).void
28
28
  end
@@ -38,8 +38,10 @@ module Dependabot
38
38
  @dependency_files = dependency_files
39
39
  @credentials = credentials
40
40
  @ignored_versions = ignored_versions
41
- @target_version = T.let(target_version_details&.fetch(:version), T.nilable(Dependabot::Maven::Version))
42
- @source_url = T.let(target_version_details&.fetch(:source_url), T.nilable(String))
41
+ target_version = target_version_details&.fetch(:version)
42
+ target_version = nil unless target_version.is_a?(Dependabot::Maven::Version)
43
+ @target_version = T.let(target_version, T.nilable(Dependabot::Maven::Version))
44
+ @source_url = T.let(target_version_details&.fetch(:source_url), T.nilable(String))
43
45
  @update_cooldown = update_cooldown
44
46
  @property_value_finder = T.let(nil, T.nilable(Dependabot::Maven::FileParser::PropertyValueFinder))
45
47
  end
@@ -206,7 +208,7 @@ module Dependabot
206
208
  raise DependencyFileNotEvaluatable, "Property not found: #{property_name}"
207
209
  end
208
210
 
209
- sig { params(dep: Dependabot::Dependency).returns(T::Hash[Symbol, T.untyped]) }
211
+ sig { params(dep: Dependabot::Dependency).returns(Dependabot::DependencyRequirement) }
210
212
  def declaring_property_requirement(dep)
211
213
  declaring_requirement =
212
214
  dep.requirements.find do |r|
@@ -221,9 +223,9 @@ module Dependabot
221
223
  "Requirement not found for property #{property_name} from #{property_source || 'unknown source'}"
222
224
  end
223
225
 
224
- sig { params(dep: Dependabot::Dependency).returns(T::Array[T::Hash[Symbol, T.untyped]]) }
226
+ sig { params(dep: Dependabot::Dependency).returns(T::Array[Dependabot::DependencyRequirement]) }
225
227
  def updated_requirements(dep)
226
- @updated_requirements ||= T.let({}, T.nilable(T::Hash[String, T::Array[T::Hash[Symbol, T.untyped]]]))
228
+ @updated_requirements ||= T.let({}, T.nilable(T::Hash[String, T::Array[Dependabot::DependencyRequirement]]))
227
229
  @updated_requirements[dep.name] ||=
228
230
  RequirementsUpdater.new(
229
231
  requirements: dep.requirements,
@@ -36,11 +36,17 @@ module Dependabot
36
36
  raise_on_ignored: false
37
37
  )
38
38
  @forbidden_urls = T.let([], T::Array[String])
39
- @dependency_metadata = T.let({}, T::Hash[T.untyped, Nokogiri::XML::Document])
39
+ @dependency_metadata = T.let({}, T::Hash[Integer, Nokogiri::XML::Document])
40
40
  @auth_headers_finder = T.let(nil, T.nilable(Utils::AuthHeadersFinder))
41
- @pom_repository_details = T.let(nil, T.nilable(T::Array[T::Hash[String, T.untyped]]))
41
+ @pom_repository_details = T.let(
42
+ nil,
43
+ T.nilable(T::Array[Dependabot::Maven::Shared::SharedPackageDetailsFetcher::RepositoryDetails])
44
+ )
42
45
  @repository_finder = T.let(nil, T.nilable(Maven::FileParser::RepositoriesFinder))
43
- @repositories = T.let(nil, T.nilable(T::Array[T::Hash[String, T.untyped]]))
46
+ @repositories = T.let(
47
+ nil,
48
+ T.nilable(T::Array[Dependabot::Maven::Shared::SharedPackageDetailsFetcher::RepositoryDetails])
49
+ )
44
50
  @released_check = T.let({}, T::Hash[Version, T::Boolean])
45
51
  @package_details_fetcher = T.let(nil, T.nilable(Package::PackageDetailsFetcher))
46
52
  @package_details = T.let(nil, T.nilable(Dependabot::Package::PackageDetails))
@@ -12,6 +12,13 @@ module Dependabot
12
12
  require_relative "update_checker/version_finder"
13
13
  require_relative "update_checker/property_updater"
14
14
 
15
+ VersionDetails = T.type_alias do
16
+ {
17
+ version: T.nilable(Dependabot::Version),
18
+ source_url: T.nilable(String)
19
+ }
20
+ end
21
+
15
22
  sig do
16
23
  params(
17
24
  dependency: Dependabot::Dependency,
@@ -24,7 +31,7 @@ module Dependabot
24
31
  requirements_update_strategy: T.nilable(Dependabot::RequirementsUpdateStrategy),
25
32
  dependency_group: T.nilable(Dependabot::DependencyGroup),
26
33
  update_cooldown: T.nilable(Dependabot::Package::ReleaseCooldownOptions),
27
- options: T::Hash[Symbol, T.untyped]
34
+ options: T::Hash[Symbol, T.anything]
28
35
  )
29
36
  .void
30
37
  end
@@ -46,13 +53,16 @@ module Dependabot
46
53
  @version_finder = T.let(nil, T.nilable(VersionFinder))
47
54
  @property_updater = T.let(nil, T.nilable(PropertyUpdater))
48
55
  @property_value_finder = T.let(nil, T.nilable(Maven::FileParser::PropertyValueFinder))
49
- @declarations_using_a_property = T.let(nil, T.nilable(T::Array[T::Hash[Symbol, T.untyped]]))
56
+ @declarations_using_a_property = T.let(nil, T.nilable(T::Array[Dependabot::DependencyRequirement]))
50
57
  @all_property_based_dependencies = T.let(nil, T.nilable(T::Array[Dependabot::Dependency]))
51
58
  end
52
59
 
53
60
  sig { override.returns(T.nilable(Dependabot::Version)) }
54
61
  def latest_version
55
- latest_version_details&.fetch(:version)
62
+ version = latest_version_details&.fetch(:version)
63
+ return version if version.is_a?(Dependabot::Version)
64
+
65
+ nil
56
66
  end
57
67
 
58
68
  sig { override.returns(T.nilable(Dependabot::Version)) }
@@ -70,7 +80,10 @@ module Dependabot
70
80
 
71
81
  sig { override.returns(T.nilable(Dependabot::Version)) }
72
82
  def lowest_security_fix_version
73
- lowest_security_fix_version_details&.fetch(:version)
83
+ version = lowest_security_fix_version_details&.fetch(:version)
84
+ return version if version.is_a?(Dependabot::Version)
85
+
86
+ nil
74
87
  end
75
88
 
76
89
  sig { override.returns(T.nilable(Dependabot::Version)) }
@@ -150,19 +163,19 @@ module Dependabot
150
163
  super
151
164
  end
152
165
 
153
- sig { returns(T.nilable(T::Hash[T.untyped, T.untyped])) }
166
+ sig { returns(T.nilable(VersionDetails)) }
154
167
  def preferred_version_details
155
168
  return lowest_security_fix_version_details if vulnerable?
156
169
 
157
170
  latest_version_details
158
171
  end
159
172
 
160
- sig { returns(T.nilable(T::Hash[T.untyped, T.untyped])) }
173
+ sig { returns(T.nilable(VersionDetails)) }
161
174
  def latest_version_details
162
175
  version_finder.latest_version_details
163
176
  end
164
177
 
165
- sig { returns(T.nilable(T::Hash[T.untyped, T.untyped])) }
178
+ sig { returns(T.nilable(VersionDetails)) }
166
179
  def lowest_security_fix_version_details
167
180
  version_finder.lowest_security_fix_version_details
168
181
  end
@@ -220,7 +233,7 @@ module Dependabot
220
233
  end
221
234
  end
222
235
 
223
- sig { returns(T::Array[T::Hash[Symbol, T.untyped]]) }
236
+ sig { returns(T::Array[Dependabot::DependencyRequirement]) }
224
237
  def declarations_using_a_property
225
238
  @declarations_using_a_property ||=
226
239
  dependency.requirements
@@ -37,7 +37,7 @@ module Dependabot
37
37
  sig { returns(T::Array[Dependabot::Credential]) }
38
38
  attr_reader :credentials
39
39
 
40
- sig { params(maven_repo_url: T.any(URI::Generic, String)).returns(T::Hash[T.untyped, T.untyped]) }
40
+ sig { params(maven_repo_url: T.any(URI::Generic, String)).returns(T::Hash[String, String]) }
41
41
  def gitlab_auth_headers(maven_repo_url)
42
42
  return {} unless gitlab_maven_repo?(T.must(URI(maven_repo_url).path))
43
43
 
@@ -1,4 +1,4 @@
1
- # typed: strict
1
+ # typed: strong
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "dependabot/maven/version_parser"
@@ -84,9 +84,12 @@ module Dependabot
84
84
  parts = token_bucket.tokens # e.g [1,2,3] if version is 1.2.3-alpha3
85
85
  return [] if parts.empty? # for non-semver versions
86
86
 
87
- version_parts = parts.fill("0", parts.length...2)
87
+ version_parts = T.let(parts.fill("0", parts.length...2), T::Array[Object])
88
88
  # the a0 is so we can get the next earliest prerelease patch version
89
- upper_parts = version_parts.first(1) + [version_parts[1].to_i + 1] + [lowest_prerelease_suffix]
89
+ upper_parts = T.let(
90
+ version_parts.first(1) + [numeric_token(version_parts[1]) + 1] + [lowest_prerelease_suffix],
91
+ T::Array[Object]
92
+ )
90
93
  lower_bound = "> #{to_semver}"
91
94
  upper_bound = "< #{upper_parts.join('.')}"
92
95
 
@@ -98,9 +101,15 @@ module Dependabot
98
101
  parts = token_bucket.tokens # e.g [1,2,3] if version is 1.2.3-alpha3
99
102
  return [] if parts.empty? # for non-semver versions
100
103
 
101
- version_parts = parts.fill("0", parts.length...2)
102
- lower_parts = version_parts.first(1) + [version_parts[1].to_i + 1] + [lowest_prerelease_suffix]
103
- upper_parts = version_parts.first(0) + [version_parts[0].to_i + 1] + [lowest_prerelease_suffix]
104
+ version_parts = T.let(parts.fill("0", parts.length...2), T::Array[Object])
105
+ lower_parts = T.let(
106
+ version_parts.first(1) + [numeric_token(version_parts[1]) + 1] + [lowest_prerelease_suffix],
107
+ T::Array[Object]
108
+ )
109
+ upper_parts = T.let(
110
+ version_parts.first(0) + [numeric_token(version_parts[0]) + 1] + [lowest_prerelease_suffix],
111
+ T::Array[Object]
112
+ )
104
113
  lower_bound = ">= #{lower_parts.join('.')}"
105
114
  upper_bound = "< #{upper_parts.join('.')}"
106
115
 
@@ -112,7 +121,10 @@ module Dependabot
112
121
  version_parts = token_bucket.tokens # e.g [1,2,3] if version is 1.2.3-alpha3
113
122
  return [] if version_parts.empty? # for non-semver versions
114
123
 
115
- lower_parts = [version_parts[0].to_i + 1] + [lowest_prerelease_suffix] # earliest next major version prerelease
124
+ lower_parts = T.let(
125
+ [numeric_token(version_parts[0]) + 1] + [lowest_prerelease_suffix],
126
+ T::Array[Object]
127
+ ) # earliest next major version prerelease
116
128
  lower_bound = ">= #{lower_parts.join('.')}"
117
129
 
118
130
  [lower_bound]
@@ -122,6 +134,11 @@ module Dependabot
122
134
 
123
135
  sig { returns(String) }
124
136
  attr_reader :version_string
137
+
138
+ sig { params(token: Object).returns(Integer) }
139
+ def numeric_token(token)
140
+ token.to_s.to_i
141
+ end
125
142
  end
126
143
  end
127
144
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-maven
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.385.0
4
+ version: 0.386.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - '='
17
17
  - !ruby/object:Gem::Version
18
- version: 0.385.0
18
+ version: 0.386.0
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - '='
24
24
  - !ruby/object:Gem::Version
25
- version: 0.385.0
25
+ version: 0.386.0
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: rexml
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -273,6 +273,7 @@ files:
273
273
  - lib/dependabot/maven/pom.xml
274
274
  - lib/dependabot/maven/requirement.rb
275
275
  - lib/dependabot/maven/shared/base_version_finder.rb
276
+ - lib/dependabot/maven/shared/property_value_finding.rb
276
277
  - lib/dependabot/maven/shared/shared_metadata_finder.rb
277
278
  - lib/dependabot/maven/shared/shared_package_details_fetcher.rb
278
279
  - lib/dependabot/maven/shared/shared_property_value_updater.rb
@@ -291,7 +292,7 @@ licenses:
291
292
  - MIT
292
293
  metadata:
293
294
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
294
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.385.0
295
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.386.0
295
296
  rdoc_options: []
296
297
  require_paths:
297
298
  - lib