dependabot-gradle 0.352.0 → 0.354.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: 9167450605c90c479bfbd32b2f4a0e68458e25a411cc58cee54a380870c3d073
4
- data.tar.gz: 6162f15731d05b8d9f041d3101d39b47071caaac5e9b78e3b4ae1393d1fb0dfb
3
+ metadata.gz: 7db2a419f742bd2979d5a1725f23be6bc2a10462405c3f6d1c43062e1634d5d8
4
+ data.tar.gz: e3146c6d0f3940b32a7d051d537d85f2c9d6053c1bf02d968d5ded8c6d1fa851
5
5
  SHA512:
6
- metadata.gz: 772120fb47bab993074d800657abff25723b064f4b4b15b776ed26acc41bb87292fbc8bf092d1793527d07295f80e9418fc4defa20ee9e21a356f8b4a2d949a2
7
- data.tar.gz: 643749b490126dac40f3602a6d7bb428e9072897c0945b6985ddd9163a17460685dd1830ef69fb392343cea06d1e51dcfd15ed225a81b6e26b048e7e4e1f1f1c
6
+ metadata.gz: 6be8055ca12fb8c042f8e773b41de99c9b84109dbe4ca9cb366d740b28f88c1758435feba240acc711230bcf4507355697c39ca15924830b2f476706a6c98a86
7
+ data.tar.gz: 19f0de7c5b7638b4dbee8703ecffe083a1abae88b0981e2bc59f0999b6942339477d1f9b7e48dff91cbb4ccd9c713657ea5260e6a0b3b28164a7b3d0a5578011
@@ -192,6 +192,7 @@ module Dependabot
192
192
  file.content = Base64.encode64(T.must(file.content)) if file.content
193
193
  file.content_encoding = DependencyFile::ContentEncoding::BASE64
194
194
  end
195
+ file.mode = DependencyFile::Mode::EXECUTABLE if file.name.end_with?("gradlew", "gradlew.bat")
195
196
  file
196
197
  rescue Dependabot::DependencyFileNotFound
197
198
  # Gradle itself doesn't worry about missing subprojects, so we don't
@@ -12,6 +12,7 @@ require "dependabot/gradle/distributions"
12
12
  require "dependabot/maven/utils/auth_headers_finder"
13
13
  require "sorbet-runtime"
14
14
  require "dependabot/gradle/metadata_finder"
15
+ require "dependabot/gradle/package/release_date_extractor"
15
16
 
16
17
  module Dependabot
17
18
  module Gradle
@@ -101,37 +102,16 @@ module Dependabot
101
102
 
102
103
  sig { returns(T::Hash[String, T::Hash[Symbol, T.untyped]]) }
103
104
  def release_details
104
- release_date_info = T.let({}, T::Hash[String, T::Hash[Symbol, T.untyped]])
105
-
106
- begin
107
- repositories.map do |repository_details|
108
- url = repository_details.fetch("url")
109
- next unless url == Gradle::FileParser::RepositoriesFinder::CENTRAL_REPO_URL
110
-
111
- release_info_metadata(repository_details).css("a[title]").each do |link|
112
- version_string = link["title"]
113
- version = version_string.gsub(%r{/$}, "")
114
- raw_date_text = link.next.text.strip.split("\n").last.strip
115
-
116
- release_date = begin
117
- Time.parse(raw_date_text)
118
- rescue StandardError
119
- nil
120
- end
121
-
122
- next unless version && version_class.correct?(version)
123
-
124
- release_date_info[version] = {
125
- release_date: release_date
126
- }
127
- end
128
- end
105
+ extractor = ReleaseDateExtractor.new(
106
+ dependency_name: dependency.name,
107
+ version_class: version_class
108
+ )
129
109
 
130
- release_date_info
131
- rescue StandardError
132
- Dependabot.logger.error("Failed to get release date")
133
- {}
134
- end
110
+ extractor.extract(
111
+ repositories: repositories,
112
+ dependency_metadata_fetcher: ->(repo) { dependency_metadata(repo) },
113
+ release_info_metadata_fetcher: ->(repo) { release_info_metadata(repo) }
114
+ )
135
115
  end
136
116
 
137
117
  sig { returns(T::Array[T::Hash[String, T.untyped]]) }
@@ -226,6 +206,8 @@ module Dependabot
226
206
  end
227
207
  end
228
208
 
209
+ # Fetches HTML directory listing from Maven-compatible repositories.
210
+ # Uses CSS selector "a[title]" to extract versions and dates. Caches results per repository.
229
211
  sig { params(repository_details: T::Hash[T.untyped, T.untyped]).returns(T.untyped) }
230
212
  def release_info_metadata(repository_details)
231
213
  @release_info_metadata ||= T.let({}, T.nilable(T::Hash[Integer, T.untyped]))
@@ -237,14 +219,14 @@ module Dependabot
237
219
  )
238
220
 
239
221
  check_response(response, repository_details.fetch("url"))
240
- Nokogiri::XML(response.body)
222
+ Nokogiri::HTML(response.body)
241
223
  rescue URI::InvalidURIError
242
- Nokogiri::XML("")
224
+ Nokogiri::HTML("")
243
225
  rescue Excon::Error::Socket, Excon::Error::Timeout,
244
226
  Excon::Error::TooManyRedirects
245
227
  raise if central_repo_urls.include?(repository_details["url"])
246
228
 
247
- Nokogiri::XML("")
229
+ Nokogiri::HTML("")
248
230
  end
249
231
  end
250
232
 
@@ -0,0 +1,166 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ require "nokogiri"
5
+ require "time"
6
+ require "sorbet-runtime"
7
+ require "dependabot/logger"
8
+
9
+ module Dependabot
10
+ module Gradle
11
+ module Package
12
+ # Extracts release dates from repository metadata to support the cooldown feature.
13
+ # Handles multiple repository formats (Maven Central HTML listings, Gradle Plugin Portal XML).
14
+ class ReleaseDateExtractor
15
+ extend T::Sig
16
+
17
+ sig do
18
+ params(
19
+ dependency_name: String,
20
+ version_class: T.class_of(Dependabot::Version)
21
+ ).void
22
+ end
23
+ def initialize(dependency_name:, version_class:)
24
+ @dependency_name = dependency_name
25
+ @version_class = version_class
26
+ end
27
+
28
+ # Extracts release dates from all repositories.
29
+ # Attempts both parsing strategies for all repositories:
30
+ # 1. Gradle Plugin Portal style: maven-metadata.xml with lastUpdated timestamp (latest version only)
31
+ # 2. Maven repository style: HTML directory listings with per-version dates
32
+ # This supports mirrors/proxies of both Maven Central and Gradle Plugin Portal.
33
+ sig do
34
+ params(
35
+ repositories: T::Array[T::Hash[String, T.untyped]],
36
+ dependency_metadata_fetcher: T.proc.params(
37
+ repo: T::Hash[String, T.untyped]
38
+ ).returns(Nokogiri::XML::Document),
39
+ release_info_metadata_fetcher: T.proc.params(
40
+ repo: T::Hash[String, T.untyped]
41
+ ).returns(Nokogiri::HTML::Document)
42
+ ).returns(T::Hash[String, T::Hash[Symbol, T.untyped]])
43
+ end
44
+ def extract(repositories:, dependency_metadata_fetcher:, release_info_metadata_fetcher:)
45
+ release_date_info = T.let({}, T::Hash[String, T::Hash[Symbol, T.untyped]])
46
+
47
+ begin
48
+ repositories.each do |repository_details|
49
+ parse_gradle_plugin_portal_release(
50
+ repository_details,
51
+ release_date_info,
52
+ dependency_metadata_fetcher
53
+ )
54
+
55
+ parse_maven_central_releases(
56
+ repository_details,
57
+ release_date_info,
58
+ release_info_metadata_fetcher
59
+ )
60
+ end
61
+
62
+ release_date_info
63
+ rescue StandardError => e
64
+ Dependabot.logger.error(
65
+ "Failed to get release date for #{@dependency_name}: #{e.class} - #{e.message}"
66
+ )
67
+ Dependabot.logger.error(e.backtrace&.join("\n") || "No backtrace available")
68
+ {}
69
+ end
70
+ end
71
+
72
+ private
73
+
74
+ sig { returns(String) }
75
+ attr_reader :dependency_name
76
+
77
+ sig { returns(T.class_of(Dependabot::Version)) }
78
+ attr_reader :version_class
79
+
80
+ # Parses Maven-style HTML directory listings to extract release dates.
81
+ sig do
82
+ params(
83
+ repository_details: T::Hash[String, T.untyped],
84
+ release_date_info: T::Hash[String, T::Hash[Symbol, T.untyped]],
85
+ metadata_fetcher: T.proc.params(
86
+ repo: T::Hash[String, T.untyped]
87
+ ).returns(Nokogiri::HTML::Document)
88
+ ).void
89
+ end
90
+ def parse_maven_central_releases(repository_details, release_date_info, metadata_fetcher)
91
+ metadata_fetcher.call(repository_details).css("a[title]").each do |link|
92
+ title = link["title"]
93
+ next unless title
94
+
95
+ version = title.gsub(%r{/$}, "")
96
+ next unless version_class.correct?(version)
97
+ next if release_date_info.key?(version)
98
+
99
+ release_date = extract_release_date_from_link(link, version)
100
+ release_date_info[version] = { release_date: release_date }
101
+ end
102
+ rescue StandardError => e
103
+ Dependabot.logger.debug(
104
+ "Could not parse Maven-style release dates from #{repository_details.fetch('url')} " \
105
+ "for #{dependency_name}: #{e.message}"
106
+ )
107
+ end
108
+
109
+ # Parses Gradle Plugin Portal maven-metadata.xml for release dates.
110
+ sig do
111
+ params(
112
+ repository_details: T::Hash[String, T.untyped],
113
+ release_date_info: T::Hash[String, T::Hash[Symbol, T.untyped]],
114
+ metadata_fetcher: T.proc.params(
115
+ repo: T::Hash[String, T.untyped]
116
+ ).returns(Nokogiri::XML::Document)
117
+ ).void
118
+ end
119
+ def parse_gradle_plugin_portal_release(repository_details, release_date_info, metadata_fetcher)
120
+ metadata_xml = metadata_fetcher.call(repository_details)
121
+ last_updated = metadata_xml.at_xpath("//metadata/versioning/lastUpdated")&.text&.strip
122
+ latest_version = metadata_xml.at_xpath("//metadata/versioning/latest")&.text&.strip
123
+
124
+ return unless latest_version && version_class.correct?(latest_version)
125
+ return if release_date_info.key?(latest_version)
126
+
127
+ release_date = parse_gradle_timestamp(last_updated)
128
+ Dependabot.logger.info(
129
+ "Parsed Gradle Plugin Portal release for #{dependency_name}: #{latest_version} at #{release_date}"
130
+ )
131
+ release_date_info[latest_version] = { release_date: release_date }
132
+ rescue StandardError => e
133
+ Dependabot.logger.debug(
134
+ "Could not parse Gradle Plugin Portal metadata from #{repository_details.fetch('url')} " \
135
+ "for #{dependency_name}: #{e.message}"
136
+ )
137
+ end
138
+
139
+ # Extracts release date from HTML link element's adjacent text.
140
+ sig { params(link: Nokogiri::XML::Element, version: String).returns(T.nilable(Time)) }
141
+ def extract_release_date_from_link(link, version)
142
+ raw_date_text = link.next.text.strip.split("\n").last.strip
143
+ Time.parse(raw_date_text)
144
+ rescue StandardError => e
145
+ Dependabot.logger.debug(
146
+ "Failed to parse release date for #{dependency_name} version #{version}: #{e.message}"
147
+ )
148
+ nil
149
+ end
150
+
151
+ # Parses Gradle Plugin Portal timestamp format (YYYYMMDDHHmmss).
152
+ sig { params(timestamp: T.nilable(String)).returns(T.nilable(Time)) }
153
+ def parse_gradle_timestamp(timestamp)
154
+ return nil if timestamp.nil? || timestamp.empty?
155
+
156
+ Time.strptime(timestamp, "%Y%m%d%H%M%S")
157
+ rescue ArgumentError => e
158
+ Dependabot.logger.warn(
159
+ "Failed to parse Gradle timestamp for #{dependency_name}: '#{timestamp}' - #{e.message}"
160
+ )
161
+ nil
162
+ end
163
+ end
164
+ end
165
+ end
166
+ end
@@ -253,8 +253,13 @@ module Dependabot
253
253
  sig { params(release: Dependabot::Package::PackageRelease).returns(T::Boolean) }
254
254
  def in_cooldown_period?(release)
255
255
  unless release.released_at
256
- Dependabot.logger.info("Release date not available for version #{release.version}")
257
- return false
256
+ if cooldown_options
257
+ Dependabot.logger.info("Release date not available for version #{release.version} - filtering out")
258
+ return true
259
+ else
260
+ Dependabot.logger.info("Release date not available for version #{release.version}")
261
+ return false
262
+ end
258
263
  end
259
264
 
260
265
  current_version = version_class.correct?(dependency.version) ? version_class.new(dependency.version) : nil
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-gradle
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.352.0
4
+ version: 0.354.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
@@ -15,28 +15,28 @@ dependencies:
15
15
  requirements:
16
16
  - - '='
17
17
  - !ruby/object:Gem::Version
18
- version: 0.352.0
18
+ version: 0.354.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.352.0
25
+ version: 0.354.0
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: dependabot-maven
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
30
30
  - - '='
31
31
  - !ruby/object:Gem::Version
32
- version: 0.352.0
32
+ version: 0.354.0
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - '='
38
38
  - !ruby/object:Gem::Version
39
- version: 0.352.0
39
+ version: 0.354.0
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: debug
42
42
  requirement: !ruby/object:Gem::Requirement
@@ -272,6 +272,7 @@ files:
272
272
  - lib/dependabot/gradle/metadata_finder.rb
273
273
  - lib/dependabot/gradle/package/distributions_fetcher.rb
274
274
  - lib/dependabot/gradle/package/package_details_fetcher.rb
275
+ - lib/dependabot/gradle/package/release_date_extractor.rb
275
276
  - lib/dependabot/gradle/package_manager.rb
276
277
  - lib/dependabot/gradle/requirement.rb
277
278
  - lib/dependabot/gradle/update_checker.rb
@@ -284,7 +285,7 @@ licenses:
284
285
  - MIT
285
286
  metadata:
286
287
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
287
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.352.0
288
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.354.0
288
289
  rdoc_options: []
289
290
  require_paths:
290
291
  - lib