dependabot-go_modules 0.308.0 → 0.310.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: 781d565e569738ce7a26a085c917036cb61d9491b3b6288cc131a8f8362d20d3
4
- data.tar.gz: 4689184ef1f74ee7178c6544e8c10bd53a00c810586a57efd15a59d308cac8df
3
+ metadata.gz: '0584130933245e950367cb0ccdbbb7f62b3789316c32965452a103b6b705516b'
4
+ data.tar.gz: b0b12c5d0ce02e625a82aaeeb3503b2afc0c1349598edd97fe32f2be4a8a0947
5
5
  SHA512:
6
- metadata.gz: 412570a735d8c82f8f77afa163a330798302453ae8f1f9238dc67fdd8866f0da997cd8c3925997df393252f49d2acf476d4d76633ebba861ded4b76b0aae3cab
7
- data.tar.gz: 75a08ca3bf310a8aec0658619823960bfd68f141da5e558391e5632db516ee05e2ae4554bd950fc2f3b55f64ff6601b90d3a2b78bcffeb2bf94b566695add1ab
6
+ metadata.gz: f086a3ba6f21b2532cd2ae8e84db5caf971db67f1d1cc9d566e00c89029c89862408acbcbd08128ea92df162f6d402abc123a5464c5bc6eaff06825edbe00375
7
+ data.tar.gz: f7f8d638f4e7db951e1faee9ec10e1a0db5c587d21e29e7d46b11002797dfae18ffc20887d456ac37ce77310541e323b3b563c8f81b84488f13981c5e82fbe83
@@ -0,0 +1,173 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ require "excon"
5
+ require "sorbet-runtime"
6
+
7
+ require "dependabot/go_modules/update_checker"
8
+ require "dependabot/update_checkers/version_filters"
9
+ require "dependabot/shared_helpers"
10
+ require "dependabot/errors"
11
+ require "dependabot/go_modules/requirement"
12
+ require "dependabot/go_modules/resolvability_errors"
13
+
14
+ module Dependabot
15
+ module GoModules
16
+ module Package
17
+ class PackageDetailsFetcher
18
+ extend T::Sig
19
+
20
+ RESOLVABILITY_ERROR_REGEXES = T.let(
21
+ [
22
+ # Package url/proxy doesn't include any redirect meta tags
23
+ /no go-import meta tags/,
24
+ # Package url 404s
25
+ /404 Not Found/,
26
+ /Repository not found/,
27
+ /unrecognized import path/,
28
+ /malformed module path/,
29
+ # (Private) module could not be fetched
30
+ /module .*: git ls-remote .*: exit status 128/m
31
+ ].freeze,
32
+ T::Array[Regexp]
33
+ )
34
+ # The module was retracted from the proxy
35
+ # OR the version of Go required is greater than what Dependabot supports
36
+ # OR other go.mod version errors
37
+ INVALID_VERSION_REGEX = /(go: loading module retractions for)|(version "[^"]+" invalid)/m
38
+ PSEUDO_VERSION_REGEX = /\b\d{14}-[0-9a-f]{12}$/
39
+
40
+ sig do
41
+ params(
42
+ dependency: Dependabot::Dependency,
43
+ dependency_files: T::Array[Dependabot::DependencyFile],
44
+ credentials: T::Array[Dependabot::Credential],
45
+ goprivate: String
46
+ ).void
47
+ end
48
+ def initialize(dependency:, dependency_files:, credentials:, goprivate:)
49
+ @dependency = dependency
50
+ @dependency_files = dependency_files
51
+ @credentials = credentials
52
+ @goprivate = T.let(goprivate, String)
53
+
54
+ @source_type = T.let(nil, T.nilable(String))
55
+ end
56
+
57
+ sig { returns(Dependabot::Dependency) }
58
+ attr_reader :dependency
59
+
60
+ sig { returns(T::Array[T.untyped]) }
61
+ attr_reader :dependency_files
62
+
63
+ sig { returns(T::Array[T.untyped]) }
64
+ attr_reader :credentials
65
+
66
+ sig { returns(String) }
67
+ attr_reader :goprivate
68
+
69
+ # rubocop:disable Metrics/AbcSize,Metrics/PerceivedComplexity
70
+ sig { returns(T::Array[Dependabot::Package::PackageRelease]) }
71
+ def fetch_available_versions
72
+ SharedHelpers.in_a_temporary_directory do
73
+ SharedHelpers.with_git_configured(credentials: credentials) do
74
+ manifest = parse_manifest
75
+
76
+ # Set up an empty go.mod so 'go list -m' won't attempt to download dependencies. This
77
+ # appears to be a side effect of operating with modules included in GOPRIVATE. We'll
78
+ # retain any exclude directives to omit those versions.
79
+ File.write("go.mod", "module dummy\n")
80
+ manifest["Exclude"]&.each do |r|
81
+ SharedHelpers.run_shell_command("go mod edit -exclude=#{r['Path']}@#{r['Version']}")
82
+ end
83
+
84
+ # Turn off the module proxy for private dependencies
85
+ env = { "GOPRIVATE" => @goprivate }
86
+
87
+ versions_json = SharedHelpers.run_shell_command(
88
+ "go list -m -versions -json #{dependency.name}",
89
+ fingerprint: "go list -m -versions -json <dependency_name>",
90
+ env: env
91
+ )
92
+ version_strings = JSON.parse(versions_json)["Versions"]
93
+
94
+ return [package_release(version: T.must(dependency.version))] if version_strings.nil?
95
+
96
+ version_info = version_strings.select { |v| version_class.correct?(v) }
97
+ .map { |v| version_class.new(v) }
98
+
99
+ package_releases = []
100
+
101
+ version_info.map do |version|
102
+ package_releases << package_release(
103
+ version: version.to_s
104
+ )
105
+ end
106
+
107
+ return package_releases
108
+ end
109
+ end
110
+ rescue SharedHelpers::HelperSubprocessFailed => e
111
+ retry_count ||= 0
112
+ retry_count += 1
113
+ retry if transitory_failure?(e) && retry_count < 2
114
+
115
+ ResolvabilityErrors.handle(e.message, goprivate: @goprivate)
116
+ [package_release(version: T.must(dependency.version))]
117
+ end
118
+ # rubocop:enable Metrics/AbcSize,Metrics/PerceivedComplexity
119
+
120
+ sig { params(error: StandardError).returns(T::Boolean) }
121
+ def transitory_failure?(error)
122
+ return true if error.message.include?("EOF")
123
+
124
+ error.message.include?("Internal Server Error")
125
+ end
126
+
127
+ sig { returns(T.nilable(Dependabot::DependencyFile)) }
128
+ def go_mod
129
+ @go_mod ||= T.let(dependency_files.find { |f| f.name == "go.mod" }, T.nilable(Dependabot::DependencyFile))
130
+ end
131
+
132
+ sig do
133
+ params(
134
+ version: String
135
+ ).returns(Dependabot::Package::PackageRelease)
136
+ end
137
+ def package_release(version:)
138
+ Dependabot::Package::PackageRelease.new(
139
+ version: GoModules::Version.new(version)
140
+ )
141
+ end
142
+
143
+ sig { returns(T::Hash[String, T.untyped]) }
144
+ def parse_manifest
145
+ SharedHelpers.in_a_temporary_directory do
146
+ File.write("go.mod", T.must(go_mod).content)
147
+ json = SharedHelpers.run_shell_command("go mod edit -json")
148
+
149
+ JSON.parse(json) || {}
150
+ end
151
+ end
152
+
153
+ sig { returns(T.class_of(Dependabot::Version)) }
154
+ def version_class
155
+ dependency.version_class
156
+ end
157
+
158
+ sig do
159
+ params(releases: T::Array[Dependabot::Package::PackageRelease])
160
+ .returns(Dependabot::Package::PackageDetails)
161
+ end
162
+ def package_details(releases)
163
+ @package_details ||= T.let(
164
+ Dependabot::Package::PackageDetails.new(
165
+ dependency: dependency,
166
+ releases: releases.reverse.uniq(&:version)
167
+ ), T.nilable(Dependabot::Package::PackageDetails)
168
+ )
169
+ end
170
+ end
171
+ end
172
+ end
173
+ end
@@ -10,11 +10,13 @@ require "dependabot/shared_helpers"
10
10
  require "dependabot/errors"
11
11
  require "dependabot/go_modules/requirement"
12
12
  require "dependabot/go_modules/resolvability_errors"
13
+ require "dependabot/go_modules/package/package_details_fetcher"
14
+ require "dependabot/package/package_latest_version_finder"
13
15
 
14
16
  module Dependabot
15
17
  module GoModules
16
18
  class UpdateChecker
17
- class LatestVersionFinder
19
+ class LatestVersionFinder < Dependabot::Package::PackageLatestVersionFinder
18
20
  extend T::Sig
19
21
 
20
22
  RESOLVABILITY_ERROR_REGEXES = T.let(
@@ -67,14 +69,22 @@ module Dependabot
67
69
  @goprivate = goprivate
68
70
  end
69
71
 
70
- sig { returns(T.nilable(Dependabot::Version)) }
71
- def latest_version
72
- @latest_version ||= T.let(fetch_latest_version, T.nilable(Dependabot::Version))
72
+ sig do
73
+ override.params(language_version: T.nilable(T.any(String, Dependabot::Version)))
74
+ .returns(T.nilable(Dependabot::Version))
75
+ end
76
+ def latest_version(language_version: nil)
77
+ @latest_version ||= T.let(fetch_latest_version(language_version: language_version),
78
+ T.nilable(Dependabot::Version))
73
79
  end
74
80
 
75
- sig { returns(T.nilable(Dependabot::Version)) }
76
- def lowest_security_fix_version
77
- @lowest_security_fix_version ||= T.let(fetch_lowest_security_fix_version, T.nilable(Dependabot::Version))
81
+ sig do
82
+ override.params(language_version: T.nilable(T.any(String, Dependabot::Version)))
83
+ .returns(T.nilable(Dependabot::Version))
84
+ end
85
+ def lowest_security_fix_version(language_version: nil)
86
+ @lowest_security_fix_version ||= T.let(fetch_lowest_security_fix_version(language_version: language_version),
87
+ T.nilable(Dependabot::Version))
78
88
  end
79
89
 
80
90
  private
@@ -94,126 +104,64 @@ module Dependabot
94
104
  sig { returns(T::Array[Dependabot::SecurityAdvisory]) }
95
105
  attr_reader :security_advisories
96
106
 
97
- sig { returns(T.nilable(Dependabot::Version)) }
98
- def fetch_latest_version
99
- candidate_versions = available_versions
107
+ sig { returns(String) }
108
+ attr_reader :goprivate
109
+
110
+ # rubocop:disable Lint/UnusedMethodArgument
111
+ sig do
112
+ params(language_version: T.nilable(T.any(String, Dependabot::Version)))
113
+ .returns(T.nilable(Dependabot::Version))
114
+ end
115
+ def fetch_latest_version(language_version: nil)
116
+ candidate_versions = available_versions_details
100
117
  candidate_versions = filter_prerelease_versions(candidate_versions)
101
118
  candidate_versions = filter_ignored_versions(candidate_versions)
102
119
  # Adding the psuedo-version to the list to avoid downgrades
103
- candidate_versions << version_class.new(dependency.version) if PSEUDO_VERSION_REGEX.match?(dependency.version)
120
+ if PSEUDO_VERSION_REGEX.match?(dependency.version)
121
+ candidate_versions << Dependabot::Package::PackageRelease.new(
122
+ version: GoModules::Version.new(dependency.version)
123
+ )
124
+ end
125
+
126
+ candidate_versions.max_by(&:version)&.version
127
+ end
104
128
 
105
- candidate_versions.max
129
+ sig do
130
+ override.returns(T.nilable(Dependabot::Package::PackageDetails))
131
+ end
132
+ def package_details
133
+ @package_details ||= T.let(
134
+ Dependabot::Package::PackageDetails.new(
135
+ dependency: dependency,
136
+ releases: available_versions_details.reverse.uniq(&:version)
137
+ ), T.nilable(Dependabot::Package::PackageDetails)
138
+ )
106
139
  end
107
140
 
108
- sig { returns(T.nilable(Dependabot::Version)) }
109
- def fetch_lowest_security_fix_version
110
- relevant_versions = available_versions
141
+ sig do
142
+ params(language_version: T.nilable(T.any(String, Dependabot::Version)))
143
+ .returns(T.nilable(Dependabot::Version))
144
+ end
145
+ def fetch_lowest_security_fix_version(language_version: nil)
146
+ relevant_versions = available_versions_details
111
147
  relevant_versions = filter_prerelease_versions(relevant_versions)
112
148
  relevant_versions = Dependabot::UpdateCheckers::VersionFilters.filter_vulnerable_versions(relevant_versions,
113
149
  security_advisories)
114
150
  relevant_versions = filter_ignored_versions(relevant_versions)
115
151
  relevant_versions = filter_lower_versions(relevant_versions)
116
152
 
117
- relevant_versions.min
118
- end
119
-
120
- sig { returns(T::Array[Dependabot::Version]) }
121
- def available_versions
122
- @available_versions ||= T.let(fetch_available_versions, T.nilable(T::Array[Dependabot::Version]))
123
- end
124
-
125
- sig { returns(T::Array[Dependabot::Version]) }
126
- def fetch_available_versions
127
- SharedHelpers.in_a_temporary_directory do
128
- SharedHelpers.with_git_configured(credentials: credentials) do
129
- manifest = parse_manifest
130
-
131
- # Set up an empty go.mod so 'go list -m' won't attempt to download dependencies. This
132
- # appears to be a side effect of operating with modules included in GOPRIVATE. We'll
133
- # retain any exclude directives to omit those versions.
134
- File.write("go.mod", "module dummy\n")
135
- manifest["Exclude"]&.each do |r|
136
- SharedHelpers.run_shell_command("go mod edit -exclude=#{r['Path']}@#{r['Version']}")
137
- end
138
-
139
- # Turn off the module proxy for private dependencies
140
- env = { "GOPRIVATE" => @goprivate }
141
-
142
- versions_json = SharedHelpers.run_shell_command(
143
- "go list -m -versions -json #{dependency.name}",
144
- fingerprint: "go list -m -versions -json <dependency_name>",
145
- env: env
146
- )
147
- version_strings = JSON.parse(versions_json)["Versions"]
148
-
149
- return [version_class.new(dependency.version)] if version_strings.nil?
150
-
151
- version_strings.select { |v| version_class.correct?(v) }
152
- .map { |v| version_class.new(v) }
153
- end
154
- end
155
- rescue SharedHelpers::HelperSubprocessFailed => e
156
- retry_count ||= 0
157
- retry_count += 1
158
- retry if transitory_failure?(e) && retry_count < 2
159
-
160
- ResolvabilityErrors.handle(e.message, goprivate: @goprivate)
161
- end
162
-
163
- sig { params(error: StandardError).returns(T::Boolean) }
164
- def transitory_failure?(error)
165
- return true if error.message.include?("EOF")
166
-
167
- error.message.include?("Internal Server Error")
153
+ relevant_versions.min_by(&:version)&.version
168
154
  end
155
+ # rubocop:enable Lint/UnusedMethodArgument
169
156
 
170
- sig { returns(T.nilable(Dependabot::DependencyFile)) }
171
- def go_mod
172
- @go_mod ||= T.let(dependency_files.find { |f| f.name == "go.mod" }, T.nilable(Dependabot::DependencyFile))
173
- end
174
-
175
- sig { returns(T::Hash[String, T.untyped]) }
176
- def parse_manifest
177
- SharedHelpers.in_a_temporary_directory do
178
- File.write("go.mod", T.must(go_mod).content)
179
- json = SharedHelpers.run_shell_command("go mod edit -json")
180
-
181
- JSON.parse(json) || {}
182
- end
183
- end
184
-
185
- sig { params(versions_array: T::Array[Dependabot::Version]).returns(T::Array[Dependabot::Version]) }
186
- def filter_prerelease_versions(versions_array)
187
- return versions_array if wants_prerelease?
188
-
189
- filtered = versions_array.reject(&:prerelease?)
190
- if versions_array.count > filtered.count
191
- Dependabot.logger.info("Filtered out #{versions_array.count - filtered.count} pre-release versions")
192
- end
193
- filtered
194
- end
195
-
196
- sig { params(versions_array: T::Array[Dependabot::Version]).returns(T::Array[Dependabot::Version]) }
197
- def filter_lower_versions(versions_array)
198
- return versions_array unless dependency.numeric_version
199
-
200
- versions_array
201
- .select { |version| version > dependency.numeric_version }
202
- end
203
-
204
- sig { params(versions_array: T::Array[Dependabot::Version]).returns(T::Array[Dependabot::Version]) }
205
- def filter_ignored_versions(versions_array)
206
- filtered = versions_array
207
- .reject { |v| ignore_requirements.any? { |r| r.satisfied_by?(v) } }
208
- if @raise_on_ignored && filter_lower_versions(filtered).empty? && filter_lower_versions(versions_array).any?
209
- raise AllVersionsIgnored
210
- end
211
-
212
- if versions_array.count > filtered.count
213
- Dependabot.logger.info("Filtered out #{versions_array.count - filtered.count} ignored versions")
214
- end
215
-
216
- filtered
157
+ sig { returns(T::Array[Dependabot::Package::PackageRelease]) }
158
+ def available_versions_details
159
+ @available_versions_details ||= T.let(Package::PackageDetailsFetcher.new(
160
+ dependency: dependency,
161
+ dependency_files: dependency_files,
162
+ credentials: credentials,
163
+ goprivate: goprivate
164
+ ).fetch_available_versions, T.nilable(T::Array[Dependabot::Package::PackageRelease]))
217
165
  end
218
166
 
219
167
  sig { returns(T::Boolean) }
@@ -226,21 +174,6 @@ module Dependabot
226
174
  T.nilable(T::Boolean)
227
175
  )
228
176
  end
229
-
230
- sig { returns(T::Array[Dependabot::Requirement]) }
231
- def ignore_requirements
232
- ignored_versions.flat_map { |req| requirement_class.requirements_array(req) }
233
- end
234
-
235
- sig { returns(T.class_of(Dependabot::Requirement)) }
236
- def requirement_class
237
- dependency.requirement_class
238
- end
239
-
240
- sig { returns(T.class_of(Dependabot::Version)) }
241
- def version_class
242
- dependency.version_class
243
- end
244
177
  end
245
178
  end
246
179
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-go_modules
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.308.0
4
+ version: 0.310.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-04-12 00:00:00.000000000 Z
10
+ date: 2025-04-24 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: dependabot-common
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - '='
17
17
  - !ruby/object:Gem::Version
18
- version: 0.308.0
18
+ version: 0.310.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.308.0
25
+ version: 0.310.0
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: debug
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -257,6 +257,7 @@ files:
257
257
  - lib/dependabot/go_modules/language.rb
258
258
  - lib/dependabot/go_modules/metadata_finder.rb
259
259
  - lib/dependabot/go_modules/native_helpers.rb
260
+ - lib/dependabot/go_modules/package/package_details_fetcher.rb
260
261
  - lib/dependabot/go_modules/package_manager.rb
261
262
  - lib/dependabot/go_modules/path_converter.rb
262
263
  - lib/dependabot/go_modules/replace_stubber.rb
@@ -270,7 +271,7 @@ licenses:
270
271
  - MIT
271
272
  metadata:
272
273
  bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
273
- changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.308.0
274
+ changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.310.0
274
275
  rdoc_options: []
275
276
  require_paths:
276
277
  - lib