dependabot-maven 0.374.0 → 0.376.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: 2bd97fa23973923f5d775a2a7f4ffa266de0eb6cadd1a419ce9e1b899a5a1c22
4
- data.tar.gz: f463dd53e46376f2fb8c8d46d7af7f99b63eb6c5634063c20157a3e0a0bc3844
3
+ metadata.gz: f6766c6eea0f8880538a54f48a87617d19e881622583b8324da63019adaedac9
4
+ data.tar.gz: 31573e51f96b69b76573cfd8b4576268e5c98de779ffacce88023dcb8317e4e0
5
5
  SHA512:
6
- metadata.gz: 63999b4d27a25fac55a369bbb9e9c1565179cf0bc1e1585150eac23879cb2e6d5d30ffe663d084c8a4fe46696b4fd64b52b8540819eaf86e376604a0c34ffdf4
7
- data.tar.gz: ef9a00f454fcf6661d1d3e0e33e16d1d43b141801ef9af125798887cf93531ce4bf34b4632641c58bba6841e2b47111462ac3a840d1a04bb6b8017fbc3dbb841
6
+ metadata.gz: b64dfca75c231cd7dfabc9c37b951006607472e64cd110d5b99ebb992cfd4fce84c72eecfc522df7c04b65ec5983befbeb4f9dc354a87d7914b1bbbef63802be
7
+ data.tar.gz: 2ea4854da94ac4236c9afdcbaee148e93049b8233ccf5d3bfc569e47240ae30172415adf239c10acaaef358eb0dc9a3ef7a4ffa8fe5d59b6b122fa9ee497a945
@@ -0,0 +1,105 @@
1
+ # typed: strong
2
+ # frozen_string_literal: true
3
+
4
+ require "sorbet-runtime"
5
+ require "dependabot/maven/shared/shared_version_finder"
6
+
7
+ module Dependabot
8
+ module Maven
9
+ module Shared
10
+ # Intermediate class for ecosystems (Maven, SBT) that use a package_details-based
11
+ # release pipeline with HEAD-check verification. Gradle uses its own filter chain
12
+ # and inherits directly from SharedVersionFinder.
13
+ class BaseVersionFinder < SharedVersionFinder
14
+ extend T::Sig
15
+ extend T::Helpers
16
+
17
+ abstract!
18
+
19
+ sig { returns(T::Array[Dependabot::Package::PackageRelease]) }
20
+ def releases
21
+ (package_details&.releases || []).reverse
22
+ end
23
+
24
+ sig { returns(T.nilable(T::Hash[T.untyped, T.untyped])) }
25
+ def latest_version_details
26
+ release = fetch_latest_release
27
+ release&.version ? { version: release.version, source_url: release.url } : nil
28
+ end
29
+
30
+ sig { returns(T.nilable(T::Hash[T.untyped, T.untyped])) }
31
+ def lowest_security_fix_version_details
32
+ release = fetch_lowest_security_fix_release
33
+ release&.version ? { version: release.version, source_url: release.url } : nil
34
+ end
35
+
36
+ protected
37
+
38
+ sig do
39
+ params(language_version: T.nilable(T.any(String, Dependabot::Version)))
40
+ .returns(T.nilable(Dependabot::Version))
41
+ end
42
+ def fetch_latest_version(language_version: nil)
43
+ fetch_latest_release(language_version: language_version)&.version
44
+ end
45
+
46
+ sig do
47
+ params(language_version: T.nilable(T.any(String, Dependabot::Version)))
48
+ .returns(T.nilable(Dependabot::Version))
49
+ end
50
+ def fetch_latest_version_with_no_unlock(language_version:)
51
+ fetch_latest_release(language_version: language_version)&.version
52
+ end
53
+
54
+ sig do
55
+ params(language_version: T.nilable(T.any(String, Dependabot::Version)))
56
+ .returns(T.nilable(Dependabot::Version))
57
+ end
58
+ def fetch_lowest_security_fix_version(language_version: nil)
59
+ fetch_lowest_security_fix_release(language_version: language_version)&.version
60
+ end
61
+
62
+ sig do
63
+ params(language_version: T.nilable(T.any(String, Dependabot::Version)))
64
+ .returns(T.nilable(Dependabot::Package::PackageRelease))
65
+ end
66
+ def fetch_latest_release(language_version: nil) # rubocop:disable Lint/UnusedMethodArgument
67
+ possible_releases = filter_prerelease_versions(releases)
68
+ possible_releases = filter_date_based_versions(possible_releases)
69
+ possible_releases = filter_version_types(possible_releases)
70
+ possible_releases = filter_ignored_versions(possible_releases)
71
+ possible_releases = filter_by_cooldown(possible_releases)
72
+ possible_releases_reverse = possible_releases.reverse
73
+
74
+ possible_releases_reverse.find do |r|
75
+ released?(r.version)
76
+ end
77
+ end
78
+
79
+ sig do
80
+ params(language_version: T.nilable(T.any(String, Dependabot::Version)))
81
+ .returns(T.nilable(Dependabot::Package::PackageRelease))
82
+ end
83
+ def fetch_lowest_security_fix_release(language_version: nil) # rubocop:disable Lint/UnusedMethodArgument
84
+ possible_releases = filter_prerelease_versions(releases)
85
+ possible_releases = filter_date_based_versions(possible_releases)
86
+ possible_releases = filter_version_types(possible_releases)
87
+ possible_releases = Dependabot::UpdateCheckers::VersionFilters
88
+ .filter_vulnerable_versions(
89
+ possible_releases,
90
+ security_advisories
91
+ )
92
+ possible_releases = filter_ignored_versions(possible_releases)
93
+ possible_releases = filter_lower_versions(possible_releases)
94
+
95
+ possible_releases.find { |r| released?(r.version) }
96
+ end
97
+
98
+ private
99
+
100
+ sig { abstract.params(version: Dependabot::Version).returns(T::Boolean) }
101
+ def released?(version); end
102
+ end
103
+ end
104
+ end
105
+ end
@@ -66,7 +66,7 @@ module Dependabot
66
66
  "#{dependency_base_url(repository_url)}/#{MAVEN_METADATA_XML}"
67
67
  end
68
68
 
69
- # URL for a specific artifact file (JAR/POM).
69
+ # URL for a specific artifact file (JAR/AAR/etc).
70
70
  #
71
71
  # Example:
72
72
  # "https://repo.maven.apache.org/maven2/com/google/guava/guava/23.6-jre/guava-23.6-jre.jar"
@@ -81,6 +81,15 @@ module Dependabot
81
81
  "#{base_url}/#{version}/#{artifact_id}-#{version}#{actual_classifier}.#{type}"
82
82
  end
83
83
 
84
+ # URL for the POM file of a specific version.
85
+ # Every published Maven artifact has a .pom file regardless of packaging type.
86
+ sig { params(repository_url: String, version: Dependabot::Version).returns(String) }
87
+ def dependency_pom_url(repository_url, version)
88
+ _, artifact_id = dependency_parts
89
+ base_url = dependency_base_url(repository_url)
90
+ "#{base_url}/#{version}/#{artifact_id}-#{version}.pom"
91
+ end
92
+
84
93
  # -- Metadata Fetching (XML) --
85
94
 
86
95
  # Fetches and parses maven-metadata.xml from a repository.
@@ -127,8 +136,11 @@ module Dependabot
127
136
  def fetch_dependency_metadata_from_html(repository_details)
128
137
  url = repository_details.fetch(URL_KEY)
129
138
  headers = repository_details.fetch(AUTH_HEADERS_KEY)
139
+ # Add trailing slash for directory listing
140
+ base_directory_url = dependency_base_url(url)
141
+ base_directory_url += "/" unless base_directory_url.end_with?("/")
130
142
  response = Dependabot::RegistryClient.get(
131
- url: dependency_base_url(url),
143
+ url: base_directory_url,
132
144
  headers: headers
133
145
  )
134
146
  check_response(response, url)
@@ -151,26 +163,44 @@ module Dependabot
151
163
  def extract_version_details_from_html(html_doc)
152
164
  versions_detail_hash = T.let({}, T::Hash[String, T::Hash[Symbol, T.untyped]])
153
165
 
154
- html_doc.css("a[title]").each do |link|
155
- version_string = link["title"]
156
- version = version_string.gsub(%r{/$}, "")
157
-
158
- raw_date_text = link.next.text.strip.split("\n").last.strip
159
-
160
- release_date = begin
161
- Time.parse(raw_date_text)
162
- rescue StandardError
163
- nil
164
- end
165
-
166
+ html_doc.css("a[href]").each do |link|
167
+ version = extract_version_from_link(link)
166
168
  next unless version && version_class.correct?(version)
167
169
 
170
+ release_date = extract_release_date_from_link(link)
171
+
168
172
  versions_detail_hash[version] = { release_date: release_date }
169
173
  end
170
174
 
171
175
  versions_detail_hash
172
176
  end
173
177
 
178
+ sig { params(link: Nokogiri::XML::Element).returns(T.nilable(String)) }
179
+ def extract_version_from_link(link)
180
+ href = link["href"]&.strip
181
+ return unless href&.end_with?("/")
182
+
183
+ identifier = [link["title"], link.text, href].find { |value| value && !value.strip.empty? }
184
+ return unless identifier
185
+
186
+ version = identifier.strip.gsub(%r{/$}, "")
187
+ return if ["..", "."].include?(version)
188
+
189
+ version
190
+ end
191
+
192
+ sig { params(link: Nokogiri::XML::Element).returns(T.nilable(Time)) }
193
+ def extract_release_date_from_link(link)
194
+ raw_date_text = link.next&.text.to_s
195
+ date_match = raw_date_text.match(/\b(?:\d{4}-\d{2}-\d{2}|\d{2}-[A-Za-z]{3}-\d{4}) \d{2}:\d{2}\b/)
196
+
197
+ return Time.parse(date_match[0]) if date_match
198
+
199
+ Time.parse(raw_date_text.strip)
200
+ rescue StandardError
201
+ nil
202
+ end
203
+
174
204
  # -- Response Checking & Error Handling --
175
205
 
176
206
  # Tracks forbidden URLs when receiving 401/403 responses (except for central repo).
@@ -304,7 +334,20 @@ module Dependabot
304
334
  url: dependency_files_url(url, version),
305
335
  headers: headers
306
336
  )
307
- response.status < 400
337
+ next true if response.status < 400
338
+
339
+ # When the artifact file returns 404, fall back to checking the .pom file.
340
+ # This handles artifacts with non-jar packaging (e.g., aar, bundle) where
341
+ # the consumer POM omits <type>, causing the parser to default to "jar".
342
+ # Only fall back when there's no classifier (classifier artifacts are specific).
343
+ next false unless response.status == 404
344
+ next false if dependency.requirements.first&.dig(:metadata, :classifier)
345
+
346
+ pom_response = Dependabot::RegistryClient.head(
347
+ url: dependency_pom_url(url, version),
348
+ headers: headers
349
+ )
350
+ pom_response.status < 400
308
351
  rescue Excon::Error::Socket, Excon::Error::Timeout,
309
352
  Excon::Error::TooManyRedirects
310
353
  false
@@ -0,0 +1,87 @@
1
+ # typed: strict
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
+ # Shared base for text-based property value updaters (Gradle, SBT).
11
+ # Subclasses must override `property_value_finder` to return the
12
+ # ecosystem-specific PropertyValueFinder instance.
13
+ #
14
+ # Maven's PropertyValueUpdater is XML-based and does not share this class.
15
+ class SharedPropertyValueUpdater
16
+ extend T::Sig
17
+ extend T::Helpers
18
+
19
+ abstract!
20
+
21
+ sig { params(dependency_files: T::Array[DependencyFile]).void }
22
+ def initialize(dependency_files:)
23
+ @dependency_files = T.let(dependency_files, T::Array[DependencyFile])
24
+ end
25
+
26
+ sig do
27
+ params(
28
+ property_name: String,
29
+ callsite_buildfile: DependencyFile,
30
+ previous_value: String,
31
+ updated_value: String
32
+ ).returns(T::Array[DependencyFile])
33
+ end
34
+ def update_files_for_property_change(
35
+ property_name:,
36
+ callsite_buildfile:,
37
+ previous_value:,
38
+ updated_value:
39
+ )
40
+ declaration_details = property_value_finder.property_details(
41
+ property_name: property_name,
42
+ callsite_buildfile: callsite_buildfile
43
+ )
44
+ raise "Property '#{property_name}' not found" unless declaration_details
45
+
46
+ declaration_string = T.let(declaration_details.fetch(:declaration_string), String)
47
+ filename = T.let(declaration_details.fetch(:file), String)
48
+
49
+ file_to_update = T.must(dependency_files.find { |f| f.name == filename })
50
+ updated_content = T.must(file_to_update.content).sub(
51
+ declaration_string,
52
+ declaration_string.sub(
53
+ previous_value_regex(previous_value),
54
+ updated_value
55
+ )
56
+ )
57
+
58
+ updated_files = dependency_files.dup
59
+ updated_files[T.must(updated_files.index(file_to_update))] =
60
+ update_file(file: file_to_update, content: updated_content)
61
+
62
+ updated_files
63
+ end
64
+
65
+ private
66
+
67
+ sig { returns(T::Array[DependencyFile]) }
68
+ attr_reader :dependency_files
69
+
70
+ sig { abstract.returns(T.untyped) }
71
+ def property_value_finder; end
72
+
73
+ sig { params(previous_value: String).returns(Regexp) }
74
+ def previous_value_regex(previous_value)
75
+ /(?<=['"])#{Regexp.quote(previous_value)}(?=['"])/
76
+ end
77
+
78
+ sig { params(file: DependencyFile, content: String).returns(DependencyFile) }
79
+ def update_file(file:, content:)
80
+ updated_file = file.dup
81
+ updated_file.content = content
82
+ updated_file
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -11,6 +11,9 @@ module Dependabot
11
11
  module Shared
12
12
  class SharedVersionFinder < Dependabot::Package::PackageLatestVersionFinder
13
13
  extend T::Sig
14
+ extend T::Helpers
15
+
16
+ abstract!
14
17
 
15
18
  # Regex to match common Maven release qualifiers that indicate stable releases.
16
19
  # See https://github.com/apache/maven/blob/848fbb4bf2d427b72bdb2471c22fced7ebd9a7a1/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ComparableVersion.java#L315-L320
@@ -123,6 +126,11 @@ module Dependabot
123
126
  dependency.version_class
124
127
  end
125
128
 
129
+ sig { returns(T::Boolean) }
130
+ def cooldown_enabled?
131
+ true
132
+ end
133
+
126
134
  private
127
135
 
128
136
  # Determines whether two versions have compatible suffixes.
@@ -405,11 +413,6 @@ module Dependabot
405
413
 
406
414
  suffix.empty? ? nil : suffix
407
415
  end
408
-
409
- sig { override.returns(T.nilable(Dependabot::Package::PackageDetails)) }
410
- def package_details
411
- raise NotImplementedError, "Subclasses must implement `package_details`"
412
- end
413
416
  end
414
417
  end
415
418
  end
@@ -60,6 +60,8 @@ module Dependabot
60
60
  next req if property_name && !properties_to_update.include?(property_name)
61
61
 
62
62
  new_req = update_requirement(req[:requirement])
63
+ next req if new_req == req[:requirement]
64
+
63
65
  req.merge(requirement: new_req, source: updated_source)
64
66
  end
65
67
  end
@@ -6,13 +6,13 @@ require "dependabot/package/release_cooldown_options"
6
6
  require "dependabot/update_checkers/version_filters"
7
7
  require "dependabot/maven/package/package_details_fetcher"
8
8
  require "dependabot/maven/update_checker"
9
- require "dependabot/maven/shared/shared_version_finder"
9
+ require "dependabot/maven/shared/base_version_finder"
10
10
  require "sorbet-runtime"
11
11
 
12
12
  module Dependabot
13
13
  module Maven
14
14
  class UpdateChecker
15
- class VersionFinder < Dependabot::Maven::Shared::SharedVersionFinder
15
+ class VersionFinder < Dependabot::Maven::Shared::BaseVersionFinder
16
16
  extend T::Sig
17
17
 
18
18
  sig do
@@ -52,92 +52,13 @@ module Dependabot
52
52
  @package_details ||= package_details_fetcher.fetch
53
53
  end
54
54
 
55
- sig { returns(T::Array[Dependabot::Package::PackageRelease]) }
56
- def releases
57
- (package_details&.releases || []).reverse
58
- end
59
-
60
- sig { returns(T.nilable(T::Hash[T.untyped, T.untyped])) }
61
- def latest_version_details
62
- release = fetch_latest_release
63
- release&.version ? { version: release.version, source_url: release.url } : nil
64
- end
65
-
66
- sig { returns(T.nilable(T::Hash[T.untyped, T.untyped])) }
67
- def lowest_security_fix_version_details
68
- release = fetch_lowest_security_fix_release
69
- release&.version ? { version: release.version, source_url: release.url } : nil
70
- end
71
-
72
- protected
73
-
74
- sig { returns(T::Boolean) }
75
- def cooldown_enabled?
76
- true
77
- end
78
-
79
- sig do
80
- params(language_version: T.nilable(T.any(String, Dependabot::Version)))
81
- .returns(T.nilable(Dependabot::Version))
82
- end
83
- def fetch_latest_version(language_version: nil)
84
- fetch_latest_release(language_version: language_version)&.version
85
- end
86
-
87
- sig do
88
- params(language_version: T.nilable(T.any(String, Dependabot::Version)))
89
- .returns(T.nilable(Dependabot::Version))
90
- end
91
- def fetch_latest_version_with_no_unlock(language_version:)
92
- fetch_latest_release(language_version: language_version)&.version
93
- end
94
-
95
- sig do
96
- params(language_version: T.nilable(T.any(String, Dependabot::Version)))
97
- .returns(T.nilable(Dependabot::Version))
98
- end
99
- def fetch_lowest_security_fix_version(language_version: nil)
100
- fetch_lowest_security_fix_release(language_version: language_version)&.version
101
- end
102
-
103
- sig do
104
- params(language_version: T.nilable(T.any(String, Dependabot::Version)))
105
- .returns(T.nilable(Dependabot::Package::PackageRelease))
106
- end
107
- def fetch_latest_release(language_version: nil) # rubocop:disable Lint/UnusedMethodArgument
108
- possible_releases = filter_prerelease_versions(releases)
109
- possible_releases = filter_date_based_versions(possible_releases)
110
- possible_releases = filter_version_types(possible_releases)
111
- possible_releases = filter_ignored_versions(possible_releases)
112
- possible_releases = filter_by_cooldown(possible_releases)
113
- possible_releases_reverse = possible_releases.reverse
114
-
115
- possible_releases_reverse.find do |r|
116
- package_details_fetcher.released?(r.version)
117
- end
118
- end
119
-
120
- sig do
121
- params(language_version: T.nilable(T.any(String, Dependabot::Version)))
122
- .returns(T.nilable(Dependabot::Package::PackageRelease))
123
- end
124
- def fetch_lowest_security_fix_release(language_version: nil) # rubocop:disable Lint/UnusedMethodArgument
125
- possible_releases = filter_prerelease_versions(releases)
126
- possible_releases = filter_date_based_versions(possible_releases)
127
- possible_releases = filter_version_types(possible_releases)
128
- possible_releases = Dependabot::UpdateCheckers::VersionFilters
129
- .filter_vulnerable_versions(
130
- possible_releases,
131
- security_advisories
132
- )
133
- possible_releases = filter_ignored_versions(possible_releases)
134
- possible_releases = filter_lower_versions(possible_releases)
55
+ private
135
56
 
136
- possible_releases.find { |r| package_details_fetcher.released?(r.version) }
57
+ sig { override.params(version: Dependabot::Version).returns(T::Boolean) }
58
+ def released?(version)
59
+ package_details_fetcher.released?(version)
137
60
  end
138
61
 
139
- private
140
-
141
62
  sig { returns(Package::PackageDetailsFetcher) }
142
63
  def package_details_fetcher
143
64
  @package_details_fetcher ||= Package::PackageDetailsFetcher.new(
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.374.0
4
+ version: 0.376.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.374.0
18
+ version: 0.376.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.374.0
25
+ version: 0.376.0
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: rexml
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -272,8 +272,10 @@ files:
272
272
  - lib/dependabot/maven/package_manager.rb
273
273
  - lib/dependabot/maven/pom.xml
274
274
  - lib/dependabot/maven/requirement.rb
275
+ - lib/dependabot/maven/shared/base_version_finder.rb
275
276
  - lib/dependabot/maven/shared/shared_metadata_finder.rb
276
277
  - lib/dependabot/maven/shared/shared_package_details_fetcher.rb
278
+ - lib/dependabot/maven/shared/shared_property_value_updater.rb
277
279
  - lib/dependabot/maven/shared/shared_requirement.rb
278
280
  - lib/dependabot/maven/shared/shared_version_finder.rb
279
281
  - lib/dependabot/maven/token_bucket.rb
@@ -289,7 +291,7 @@ licenses:
289
291
  - MIT
290
292
  metadata:
291
293
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
292
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.374.0
294
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.376.0
293
295
  rdoc_options: []
294
296
  require_paths:
295
297
  - lib