dependabot-go_modules 0.248.0 → 0.249.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 +4 -4
- data/lib/dependabot/go_modules/file_fetcher.rb +11 -10
- data/lib/dependabot/go_modules/file_parser.rb +37 -20
- data/lib/dependabot/go_modules/file_updater/go_mod_updater.rb +71 -22
- data/lib/dependabot/go_modules/replace_stubber.rb +15 -2
- data/lib/dependabot/go_modules/requirement.rb +15 -4
- data/lib/dependabot/go_modules/update_checker/latest_version_finder.rb +5 -1
- metadata +5 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 77f553b4e68fb575402246aa93d1e4a0af7ff93800c8e0fb87ef7911620fab86
|
|
4
|
+
data.tar.gz: 61a0572e24be4761a15df1862b690b1e55853af8f5b279402b3adf139c83d8b3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1f7f18f8f1634b1f79ac995a2f65bbbc851d2f910cb941879f9bd8a788b3dda1e28df82667b70c0aaf48033122342b0375e0b27713a3bc3c4e262b799e5db180
|
|
7
|
+
data.tar.gz: ccc34edf59769d78b49f224fcc9831042d9f13037fb5e445d1d04046c7a19dddb63bfe287eedd2aaa55f74058406bf16c09b9a0e93221e3f607fc17e662bb513
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# typed:
|
|
1
|
+
# typed: strong
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
require "sorbet-runtime"
|
|
@@ -11,18 +11,21 @@ module Dependabot
|
|
|
11
11
|
extend T::Sig
|
|
12
12
|
extend T::Helpers
|
|
13
13
|
|
|
14
|
+
sig { override.params(filenames: T::Array[String]).returns(T::Boolean) }
|
|
14
15
|
def self.required_files_in?(filenames)
|
|
15
16
|
filenames.include?("go.mod")
|
|
16
17
|
end
|
|
17
18
|
|
|
19
|
+
sig { override.returns(String) }
|
|
18
20
|
def self.required_files_message
|
|
19
21
|
"Repo must contain a go.mod."
|
|
20
22
|
end
|
|
21
23
|
|
|
24
|
+
sig { override.returns(T::Hash[Symbol, T.untyped]) }
|
|
22
25
|
def ecosystem_versions
|
|
23
26
|
{
|
|
24
27
|
package_managers: {
|
|
25
|
-
"gomod" => go_mod
|
|
28
|
+
"gomod" => go_mod&.content&.match(/^go\s(\d+\.\d+)/)&.captures&.first || "unknown"
|
|
26
29
|
}
|
|
27
30
|
}
|
|
28
31
|
end
|
|
@@ -35,25 +38,23 @@ module Dependabot
|
|
|
35
38
|
directory,
|
|
36
39
|
clone_repo_contents
|
|
37
40
|
) do
|
|
38
|
-
fetched_files = [go_mod]
|
|
41
|
+
fetched_files = go_mod ? [go_mod] : []
|
|
39
42
|
# Fetch the (optional) go.sum
|
|
40
|
-
fetched_files << go_sum if go_sum
|
|
43
|
+
fetched_files << T.must(go_sum) if go_sum
|
|
41
44
|
fetched_files
|
|
42
45
|
end
|
|
43
46
|
end
|
|
44
47
|
|
|
45
48
|
private
|
|
46
49
|
|
|
50
|
+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
|
47
51
|
def go_mod
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
@go_mod = fetch_file_if_present("go.mod")
|
|
52
|
+
@go_mod ||= T.let(fetch_file_if_present("go.mod"), T.nilable(Dependabot::DependencyFile))
|
|
51
53
|
end
|
|
52
54
|
|
|
55
|
+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
|
53
56
|
def go_sum
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
@go_sum = fetch_file_if_present("go.sum")
|
|
57
|
+
@go_sum ||= T.let(fetch_file_if_present("go.sum"), T.nilable(Dependabot::DependencyFile))
|
|
57
58
|
end
|
|
58
59
|
end
|
|
59
60
|
end
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
# typed:
|
|
1
|
+
# typed: strict
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
+
require "sorbet-runtime"
|
|
5
|
+
|
|
4
6
|
require "open3"
|
|
5
7
|
require "dependabot/dependency"
|
|
6
8
|
require "dependabot/file_parsers/base/dependency_set"
|
|
@@ -14,6 +16,9 @@ require "dependabot/go_modules/version"
|
|
|
14
16
|
module Dependabot
|
|
15
17
|
module GoModules
|
|
16
18
|
class FileParser < Dependabot::FileParsers::Base
|
|
19
|
+
extend T::Sig
|
|
20
|
+
|
|
21
|
+
sig { override.returns(T::Array[Dependabot::Dependency]) }
|
|
17
22
|
def parse
|
|
18
23
|
set_gotoolchain_env
|
|
19
24
|
|
|
@@ -29,8 +34,9 @@ module Dependabot
|
|
|
29
34
|
private
|
|
30
35
|
|
|
31
36
|
# set GOTOOLCHAIN=local if go version >= 1.21
|
|
37
|
+
sig { void }
|
|
32
38
|
def set_gotoolchain_env
|
|
33
|
-
go_directive = go_mod
|
|
39
|
+
go_directive = go_mod&.content&.match(/^go\s(\d+\.\d+)/)&.captures&.first
|
|
34
40
|
return ENV["GOTOOLCHAIN"] = ENV.fetch("GO_LEGACY") unless go_directive
|
|
35
41
|
|
|
36
42
|
go_version = Dependabot::GoModules::Version.new(go_directive)
|
|
@@ -41,21 +47,24 @@ module Dependabot
|
|
|
41
47
|
end
|
|
42
48
|
end
|
|
43
49
|
|
|
50
|
+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
|
|
44
51
|
def go_mod
|
|
45
|
-
@go_mod ||= get_original_file("go.mod")
|
|
52
|
+
@go_mod ||= T.let(get_original_file("go.mod"), T.nilable(Dependabot::DependencyFile))
|
|
46
53
|
end
|
|
47
54
|
|
|
55
|
+
sig { override.void }
|
|
48
56
|
def check_required_files
|
|
49
57
|
raise "No go.mod!" unless go_mod
|
|
50
58
|
end
|
|
51
59
|
|
|
60
|
+
sig { params(details: T::Hash[String, T.untyped]).returns(Dependabot::Dependency) }
|
|
52
61
|
def dependency_from_details(details)
|
|
53
62
|
source = { type: "default", source: details["Path"] }
|
|
54
63
|
version = details["Version"]&.sub(/^v?/, "")
|
|
55
64
|
|
|
56
65
|
reqs = [{
|
|
57
66
|
requirement: details["Version"],
|
|
58
|
-
file: go_mod
|
|
67
|
+
file: go_mod&.name,
|
|
59
68
|
source: source,
|
|
60
69
|
groups: []
|
|
61
70
|
}]
|
|
@@ -68,9 +77,10 @@ module Dependabot
|
|
|
68
77
|
)
|
|
69
78
|
end
|
|
70
79
|
|
|
80
|
+
sig { returns(T::Array[T::Hash[String, T.untyped]]) }
|
|
71
81
|
def required_packages
|
|
72
82
|
@required_packages ||=
|
|
73
|
-
SharedHelpers.in_a_temporary_directory do |path|
|
|
83
|
+
T.let(SharedHelpers.in_a_temporary_directory do |path|
|
|
74
84
|
# Create a fake empty module for each local module so that
|
|
75
85
|
# `go mod edit` works, even if some modules have been `replace`d with
|
|
76
86
|
# a local module that we don't have access to.
|
|
@@ -86,55 +96,62 @@ module Dependabot
|
|
|
86
96
|
stdout, stderr, status = Open3.capture3(command)
|
|
87
97
|
handle_parser_error(path, stderr) unless status.success?
|
|
88
98
|
JSON.parse(stdout)["Require"] || []
|
|
89
|
-
end
|
|
99
|
+
end, T.nilable(T::Array[T::Hash[String, T.untyped]]))
|
|
90
100
|
end
|
|
91
101
|
|
|
102
|
+
sig { returns(T::Hash[String, String]) }
|
|
92
103
|
def local_replacements
|
|
93
104
|
@local_replacements ||=
|
|
94
105
|
# Find all the local replacements, and return them with a stub path
|
|
95
106
|
# we can use in their place. Using generated paths is safer as it
|
|
96
107
|
# means we don't need to worry about references to parent
|
|
97
108
|
# directories, etc.
|
|
98
|
-
ReplaceStubber.new(repo_contents_path).stub_paths(manifest, go_mod
|
|
109
|
+
T.let(ReplaceStubber.new(repo_contents_path).stub_paths(manifest, go_mod&.directory),
|
|
110
|
+
T.nilable(T::Hash[String, String]))
|
|
99
111
|
end
|
|
100
112
|
|
|
113
|
+
sig { returns(T::Hash[String, T.untyped]) }
|
|
101
114
|
def manifest
|
|
102
115
|
@manifest ||=
|
|
103
|
-
SharedHelpers.in_a_temporary_directory do |path|
|
|
104
|
-
|
|
116
|
+
T.let(SharedHelpers.in_a_temporary_directory do |path|
|
|
117
|
+
File.write("go.mod", go_mod&.content)
|
|
105
118
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
119
|
+
# Parse the go.mod to get a JSON representation of the replace
|
|
120
|
+
# directives
|
|
121
|
+
command = "go mod edit -json"
|
|
109
122
|
|
|
110
|
-
|
|
111
|
-
|
|
123
|
+
stdout, stderr, status = Open3.capture3(command)
|
|
124
|
+
handle_parser_error(path, stderr) unless status.success?
|
|
112
125
|
|
|
113
|
-
|
|
114
|
-
|
|
126
|
+
JSON.parse(stdout)
|
|
127
|
+
end, T.nilable(T::Hash[String, T.untyped]))
|
|
115
128
|
end
|
|
116
129
|
|
|
130
|
+
sig { returns(T.nilable(String)) }
|
|
117
131
|
def go_mod_content
|
|
118
|
-
local_replacements.reduce(go_mod
|
|
119
|
-
body
|
|
132
|
+
local_replacements.reduce(go_mod&.content) do |body, (path, stub_path)|
|
|
133
|
+
body&.sub(path, stub_path)
|
|
120
134
|
end
|
|
121
135
|
end
|
|
122
136
|
|
|
137
|
+
sig { params(path: T.any(Pathname, String), stderr: String).returns(T.noreturn) }
|
|
123
138
|
def handle_parser_error(path, stderr)
|
|
124
139
|
msg = stderr.gsub(path.to_s, "").strip
|
|
125
|
-
raise Dependabot::DependencyFileNotParseable.new(go_mod.path, msg)
|
|
140
|
+
raise Dependabot::DependencyFileNotParseable.new(T.must(go_mod).path, msg)
|
|
126
141
|
end
|
|
127
142
|
|
|
143
|
+
sig { params(dep: T::Hash[String, T.untyped]).returns(T::Boolean) }
|
|
128
144
|
def skip_dependency?(dep)
|
|
129
145
|
# Updating replaced dependencies is not supported
|
|
130
146
|
return true if dependency_is_replaced(dep)
|
|
131
147
|
|
|
132
148
|
path_uri = URI.parse("https://#{dep['Path']}")
|
|
133
|
-
!path_uri.host
|
|
149
|
+
!path_uri.host&.include?(".")
|
|
134
150
|
rescue URI::InvalidURIError
|
|
135
151
|
false
|
|
136
152
|
end
|
|
137
153
|
|
|
154
|
+
sig { params(details: T::Hash[String, T.untyped]).returns(T::Boolean) }
|
|
138
155
|
def dependency_is_replaced(details)
|
|
139
156
|
# Mark dependency as replaced if the requested dependency has a
|
|
140
157
|
# "replace" directive and that either has the same version, or no
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
# typed:
|
|
1
|
+
# typed: strict
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
+
require "sorbet-runtime"
|
|
5
|
+
|
|
4
6
|
require "dependabot/shared_helpers"
|
|
5
7
|
require "dependabot/errors"
|
|
6
8
|
require "dependabot/logger"
|
|
@@ -12,7 +14,9 @@ module Dependabot
|
|
|
12
14
|
module GoModules
|
|
13
15
|
class FileUpdater
|
|
14
16
|
class GoModUpdater
|
|
15
|
-
|
|
17
|
+
extend T::Sig
|
|
18
|
+
|
|
19
|
+
RESOLVABILITY_ERROR_REGEXES = T.let([
|
|
16
20
|
# The checksum in go.sum does not match the downloaded content
|
|
17
21
|
/verifying .*: checksum mismatch/,
|
|
18
22
|
/go(?: get)?: .*: go.mod has post-v\d+ module path/,
|
|
@@ -28,9 +32,9 @@ module Dependabot
|
|
|
28
32
|
/can't find reason for requirement on/,
|
|
29
33
|
# import path doesn't exist
|
|
30
34
|
/package \S+ is not in GOROOT/
|
|
31
|
-
].freeze
|
|
35
|
+
].freeze, T::Array[Regexp])
|
|
32
36
|
|
|
33
|
-
REPO_RESOLVABILITY_ERROR_REGEXES = [
|
|
37
|
+
REPO_RESOLVABILITY_ERROR_REGEXES = T.let([
|
|
34
38
|
/fatal: The remote end hung up unexpectedly/,
|
|
35
39
|
/repository '.+' not found/,
|
|
36
40
|
%r{net/http: TLS handshake timeout},
|
|
@@ -48,22 +52,32 @@ module Dependabot
|
|
|
48
52
|
/go(?: get)?: .*: unknown revision/m,
|
|
49
53
|
# Package pointing to a proxy that 404s
|
|
50
54
|
/go(?: get)?: .*: unrecognized import path/m
|
|
51
|
-
].freeze
|
|
55
|
+
].freeze, T::Array[Regexp])
|
|
52
56
|
|
|
53
|
-
MODULE_PATH_MISMATCH_REGEXES = [
|
|
57
|
+
MODULE_PATH_MISMATCH_REGEXES = T.let([
|
|
54
58
|
/go(?: get)?: ([^@\s]+)(?:@[^\s]+)?: .* has non-.* module path "(.*)" at/,
|
|
55
59
|
/go(?: get)?: ([^@\s]+)(?:@[^\s]+)?: .* unexpected module path "(.*)"/,
|
|
56
60
|
/go(?: get)?: ([^@\s]+)(?:@[^\s]+)?:? .* declares its path as: ([\S]*)/m
|
|
57
|
-
].freeze
|
|
61
|
+
].freeze, T::Array[Regexp])
|
|
58
62
|
|
|
59
|
-
OUT_OF_DISK_REGEXES = [
|
|
63
|
+
OUT_OF_DISK_REGEXES = T.let([
|
|
60
64
|
%r{input/output error},
|
|
61
65
|
/no space left on device/,
|
|
62
66
|
/Out of diskspace/
|
|
63
|
-
].freeze
|
|
67
|
+
].freeze, T::Array[Regexp])
|
|
64
68
|
|
|
65
69
|
GO_MOD_VERSION = /^go 1\.\d+(\.\d+)?$/
|
|
66
70
|
|
|
71
|
+
sig do
|
|
72
|
+
params(
|
|
73
|
+
dependencies: T::Array[Dependabot::Dependency],
|
|
74
|
+
dependency_files: T::Array[Dependabot::DependencyFile],
|
|
75
|
+
credentials: T::Array[Dependabot::Credential],
|
|
76
|
+
repo_contents_path: T.nilable(String),
|
|
77
|
+
directory: String,
|
|
78
|
+
options: T::Hash[Symbol, T.untyped]
|
|
79
|
+
).void
|
|
80
|
+
end
|
|
67
81
|
def initialize(dependencies:, dependency_files:, credentials:, repo_contents_path:,
|
|
68
82
|
directory:, options:)
|
|
69
83
|
@dependencies = dependencies
|
|
@@ -71,28 +85,44 @@ module Dependabot
|
|
|
71
85
|
@credentials = credentials
|
|
72
86
|
@repo_contents_path = repo_contents_path
|
|
73
87
|
@directory = directory
|
|
74
|
-
@tidy = options.fetch(:tidy, false)
|
|
75
|
-
@vendor = options.fetch(:vendor, false)
|
|
76
|
-
@goprivate = options.fetch(:goprivate)
|
|
88
|
+
@tidy = T.let(options.fetch(:tidy, false), T::Boolean)
|
|
89
|
+
@vendor = T.let(options.fetch(:vendor, false), T::Boolean)
|
|
90
|
+
@goprivate = T.let(options.fetch(:goprivate), T.nilable(String))
|
|
77
91
|
end
|
|
78
92
|
|
|
93
|
+
sig { returns(T.nilable(String)) }
|
|
79
94
|
def updated_go_mod_content
|
|
80
95
|
updated_files[:go_mod]
|
|
81
96
|
end
|
|
82
97
|
|
|
98
|
+
sig { returns(T.nilable(String)) }
|
|
83
99
|
def updated_go_sum_content
|
|
84
100
|
updated_files[:go_sum]
|
|
85
101
|
end
|
|
86
102
|
|
|
87
103
|
private
|
|
88
104
|
|
|
89
|
-
|
|
90
|
-
|
|
105
|
+
sig { returns(T::Array[Dependabot::Dependency]) }
|
|
106
|
+
attr_reader :dependencies
|
|
107
|
+
|
|
108
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
|
109
|
+
attr_reader :dependency_files
|
|
91
110
|
|
|
111
|
+
sig { returns(T::Array[Dependabot::Credential]) }
|
|
112
|
+
attr_reader :credentials
|
|
113
|
+
|
|
114
|
+
sig { returns(T.nilable(String)) }
|
|
115
|
+
attr_reader :repo_contents_path
|
|
116
|
+
|
|
117
|
+
sig { returns(String) }
|
|
118
|
+
attr_reader :directory
|
|
119
|
+
|
|
120
|
+
sig { returns(T::Hash[Symbol, String]) }
|
|
92
121
|
def updated_files
|
|
93
|
-
@updated_files ||= update_files
|
|
122
|
+
@updated_files ||= T.let(update_files, T.nilable(T::Hash[Symbol, String]))
|
|
94
123
|
end
|
|
95
124
|
|
|
125
|
+
sig { returns(T::Hash[Symbol, String]) }
|
|
96
126
|
def update_files # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity
|
|
97
127
|
in_repo_path do
|
|
98
128
|
# During grouped updates, the dependency_files are from a previous dependency
|
|
@@ -140,7 +170,7 @@ module Dependabot
|
|
|
140
170
|
original_go_version = original_go_mod.match(GO_MOD_VERSION)&.to_a&.first
|
|
141
171
|
updated_go_version = updated_go_mod.match(GO_MOD_VERSION)&.to_a&.first
|
|
142
172
|
if original_go_version != updated_go_version
|
|
143
|
-
go_mod_lines = updated_go_mod.lines
|
|
173
|
+
go_mod_lines = T.let(updated_go_mod.lines, T::Array[T.nilable(String)])
|
|
144
174
|
go_mod_lines.each_with_index do |line, i|
|
|
145
175
|
next unless line&.match?(GO_MOD_VERSION)
|
|
146
176
|
|
|
@@ -157,6 +187,7 @@ module Dependabot
|
|
|
157
187
|
end
|
|
158
188
|
end
|
|
159
189
|
|
|
190
|
+
sig { void }
|
|
160
191
|
def run_go_mod_tidy
|
|
161
192
|
return unless tidy?
|
|
162
193
|
|
|
@@ -170,6 +201,7 @@ module Dependabot
|
|
|
170
201
|
Dependabot.logger.info "Failed to `go mod tidy`: #{stderr}" unless status.success?
|
|
171
202
|
end
|
|
172
203
|
|
|
204
|
+
sig { void }
|
|
173
205
|
def run_go_vendor
|
|
174
206
|
return unless vendor?
|
|
175
207
|
|
|
@@ -178,6 +210,7 @@ module Dependabot
|
|
|
178
210
|
handle_subprocess_error(stderr) unless status.success?
|
|
179
211
|
end
|
|
180
212
|
|
|
213
|
+
sig { params(dependencies: T.untyped).void }
|
|
181
214
|
def run_go_get(dependencies = [])
|
|
182
215
|
# `go get` will fail if there are no go files in the directory.
|
|
183
216
|
# For example, if a `//go:build` tag excludes all files when run
|
|
@@ -200,9 +233,10 @@ module Dependabot
|
|
|
200
233
|
_, stderr, status = Open3.capture3(environment, command)
|
|
201
234
|
handle_subprocess_error(stderr) unless status.success?
|
|
202
235
|
ensure
|
|
203
|
-
FileUtils.rm_f(tmp_go_file)
|
|
236
|
+
FileUtils.rm_f(T.must(tmp_go_file))
|
|
204
237
|
end
|
|
205
238
|
|
|
239
|
+
sig { returns(T::Hash[String, T.untyped]) }
|
|
206
240
|
def parse_manifest
|
|
207
241
|
command = "go mod edit -json"
|
|
208
242
|
stdout, stderr, status = Open3.capture3(environment, command)
|
|
@@ -211,12 +245,18 @@ module Dependabot
|
|
|
211
245
|
JSON.parse(stdout) || {}
|
|
212
246
|
end
|
|
213
247
|
|
|
248
|
+
sig do
|
|
249
|
+
type_parameters(:T)
|
|
250
|
+
.params(block: T.proc.returns(T.type_parameter(:T)))
|
|
251
|
+
.returns(T.type_parameter(:T))
|
|
252
|
+
end
|
|
214
253
|
def in_repo_path(&block)
|
|
215
254
|
SharedHelpers.in_a_temporary_repo_directory(directory, repo_contents_path) do
|
|
216
255
|
SharedHelpers.with_git_configured(credentials: credentials, &block)
|
|
217
256
|
end
|
|
218
257
|
end
|
|
219
258
|
|
|
259
|
+
sig { params(stub_paths: T::Array[String]).void }
|
|
220
260
|
def build_module_stubs(stub_paths)
|
|
221
261
|
# Create a fake empty module for each local module so that
|
|
222
262
|
# `go get` works, even if some modules have been `replace`d
|
|
@@ -236,12 +276,14 @@ module Dependabot
|
|
|
236
276
|
# the layout of the filesystem with a structure we can reproduce (i.e.
|
|
237
277
|
# no paths such as ../../../foo), run the Go tooling, then reverse the
|
|
238
278
|
# process afterwards.
|
|
279
|
+
sig { params(manifest: T::Hash[String, T.untyped]).returns(T::Hash[String, String]) }
|
|
239
280
|
def replace_directive_substitutions(manifest)
|
|
240
281
|
@replace_directive_substitutions ||=
|
|
241
|
-
Dependabot::GoModules::ReplaceStubber.new(repo_contents_path)
|
|
242
|
-
.stub_paths(manifest, directory)
|
|
282
|
+
T.let(Dependabot::GoModules::ReplaceStubber.new(repo_contents_path)
|
|
283
|
+
.stub_paths(manifest, directory), T.nilable(T::Hash[String, String]))
|
|
243
284
|
end
|
|
244
285
|
|
|
286
|
+
sig { params(substitutions: T::Hash[String, String]).void }
|
|
245
287
|
def substitute_all(substitutions)
|
|
246
288
|
body = substitutions.reduce(File.read("go.mod")) do |text, (a, b)|
|
|
247
289
|
text.sub(a, b)
|
|
@@ -250,7 +292,8 @@ module Dependabot
|
|
|
250
292
|
write_go_mod(body)
|
|
251
293
|
end
|
|
252
294
|
|
|
253
|
-
|
|
295
|
+
sig { params(stderr: String).returns(T.noreturn) }
|
|
296
|
+
def handle_subprocess_error(stderr) # rubocop:disable Metrics/AbcSize
|
|
254
297
|
stderr = stderr.gsub(Dir.getwd, "")
|
|
255
298
|
|
|
256
299
|
# Package version doesn't match the module major version
|
|
@@ -269,9 +312,9 @@ module Dependabot
|
|
|
269
312
|
|
|
270
313
|
path_regex = MODULE_PATH_MISMATCH_REGEXES.find { |r| stderr =~ r }
|
|
271
314
|
if path_regex
|
|
272
|
-
match = path_regex.match(stderr)
|
|
315
|
+
match = T.must(path_regex.match(stderr))
|
|
273
316
|
raise Dependabot::GoModulePathMismatch
|
|
274
|
-
.new(go_mod_path, match[1], match[2])
|
|
317
|
+
.new(go_mod_path, T.must(match[1]), T.must(match[2]))
|
|
275
318
|
end
|
|
276
319
|
|
|
277
320
|
out_of_disk_regex = OUT_OF_DISK_REGEXES.find { |r| stderr =~ r }
|
|
@@ -285,6 +328,7 @@ module Dependabot
|
|
|
285
328
|
raise Dependabot::DependabotError, msg
|
|
286
329
|
end
|
|
287
330
|
|
|
331
|
+
sig { params(message: String, regex: Regexp).returns(String) }
|
|
288
332
|
def filter_error_message(message:, regex:)
|
|
289
333
|
lines = message.lines.select { |l| regex =~ l }
|
|
290
334
|
return lines.join if lines.any?
|
|
@@ -293,24 +337,29 @@ module Dependabot
|
|
|
293
337
|
message.match(regex).to_s
|
|
294
338
|
end
|
|
295
339
|
|
|
340
|
+
sig { returns(String) }
|
|
296
341
|
def go_mod_path
|
|
297
342
|
return "go.mod" if directory == "/"
|
|
298
343
|
|
|
299
344
|
File.join(directory, "go.mod")
|
|
300
345
|
end
|
|
301
346
|
|
|
347
|
+
sig { params(body: Object).void }
|
|
302
348
|
def write_go_mod(body)
|
|
303
349
|
File.write("go.mod", body)
|
|
304
350
|
end
|
|
305
351
|
|
|
352
|
+
sig { returns(T::Boolean) }
|
|
306
353
|
def tidy?
|
|
307
354
|
!!@tidy
|
|
308
355
|
end
|
|
309
356
|
|
|
357
|
+
sig { returns(T::Boolean) }
|
|
310
358
|
def vendor?
|
|
311
359
|
!!@vendor
|
|
312
360
|
end
|
|
313
361
|
|
|
362
|
+
sig { returns(T::Hash[String, T.untyped]) }
|
|
314
363
|
def environment
|
|
315
364
|
{ "GOPRIVATE" => @goprivate }
|
|
316
365
|
end
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
# typed:
|
|
1
|
+
# typed: strict
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
+
require "sorbet-runtime"
|
|
5
|
+
|
|
4
6
|
module Dependabot
|
|
5
7
|
module GoModules
|
|
6
8
|
# Given a go.mod file, find all `replace` directives pointing to a path
|
|
@@ -12,10 +14,16 @@ module Dependabot
|
|
|
12
14
|
# no paths such as ../../../foo), run the Go tooling, then reverse the
|
|
13
15
|
# process afterwards.
|
|
14
16
|
class ReplaceStubber
|
|
17
|
+
extend T::Sig
|
|
18
|
+
|
|
19
|
+
sig { params(repo_contents_path: T.nilable(String)).void }
|
|
15
20
|
def initialize(repo_contents_path)
|
|
16
21
|
@repo_contents_path = repo_contents_path
|
|
17
22
|
end
|
|
18
23
|
|
|
24
|
+
sig do
|
|
25
|
+
params(manifest: T::Hash[String, T.untyped], directory: T.nilable(String)).returns(T::Hash[String, String])
|
|
26
|
+
end
|
|
19
27
|
def stub_paths(manifest, directory)
|
|
20
28
|
(manifest["Replace"] || [])
|
|
21
29
|
.filter_map { |r| r["New"]["Path"] }
|
|
@@ -25,6 +33,7 @@ module Dependabot
|
|
|
25
33
|
|
|
26
34
|
private
|
|
27
35
|
|
|
36
|
+
sig { params(path: String, directory: T.nilable(String)).returns(T::Boolean) }
|
|
28
37
|
def stub_replace_path?(path, directory)
|
|
29
38
|
return true if absolute_path?(path)
|
|
30
39
|
return false unless relative_replacement_path?(path)
|
|
@@ -37,17 +46,21 @@ module Dependabot
|
|
|
37
46
|
true
|
|
38
47
|
end
|
|
39
48
|
|
|
49
|
+
sig { params(path: String).returns(T::Boolean) }
|
|
40
50
|
def absolute_path?(path)
|
|
41
51
|
path.start_with?("/")
|
|
42
52
|
end
|
|
43
53
|
|
|
54
|
+
sig { params(path: String).returns(T::Boolean) }
|
|
44
55
|
def relative_replacement_path?(path)
|
|
45
56
|
# https://golang.org/ref/mod#go-mod-file-replace
|
|
46
57
|
path.start_with?("./", "../")
|
|
47
58
|
end
|
|
48
59
|
|
|
60
|
+
sig { params(directory: T.nilable(String)).returns(Pathname) }
|
|
49
61
|
def module_pathname(directory)
|
|
50
|
-
@module_pathname ||= Pathname.new(@repo_contents_path).join(directory.sub(%r{^/}, ""))
|
|
62
|
+
@module_pathname ||= T.let(Pathname.new(@repo_contents_path).join(T.must(directory).sub(%r{^/}, "")),
|
|
63
|
+
T.nilable(Pathname))
|
|
51
64
|
end
|
|
52
65
|
end
|
|
53
66
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# typed:
|
|
1
|
+
# typed: strict
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
################################################################################
|
|
@@ -25,11 +25,12 @@ module Dependabot
|
|
|
25
25
|
quoted = OPS.keys.map { |k| Regexp.quote(k) }.join("|")
|
|
26
26
|
version_pattern = "v?#{Version::VERSION_PATTERN}"
|
|
27
27
|
|
|
28
|
-
PATTERN_RAW = "\\s*(#{quoted})?\\s*(#{version_pattern})\\s*".freeze
|
|
28
|
+
PATTERN_RAW = T.let("\\s*(#{quoted})?\\s*(#{version_pattern})\\s*".freeze, String)
|
|
29
29
|
PATTERN = /\A#{PATTERN_RAW}\z/
|
|
30
30
|
|
|
31
31
|
# Use GoModules::Version rather than Gem::Version to ensure that
|
|
32
32
|
# pre-release versions aren't transformed.
|
|
33
|
+
sig { params(obj: T.untyped).returns([String, Gem::Version]) }
|
|
33
34
|
def self.parse(obj)
|
|
34
35
|
return ["=", Version.new(obj.to_s)] if obj.is_a?(Gem::Version)
|
|
35
36
|
|
|
@@ -54,9 +55,12 @@ module Dependabot
|
|
|
54
55
|
end
|
|
55
56
|
end
|
|
56
57
|
|
|
58
|
+
sig do
|
|
59
|
+
params(requirements: T.nilable(String)).void
|
|
60
|
+
end
|
|
57
61
|
def initialize(*requirements)
|
|
58
62
|
requirements = requirements.flatten.flat_map do |req_string|
|
|
59
|
-
req_string
|
|
63
|
+
req_string&.split(",")&.map(&:strip)&.map do |r|
|
|
60
64
|
convert_go_constraint_to_ruby_constraint(r.strip)
|
|
61
65
|
end
|
|
62
66
|
end
|
|
@@ -66,6 +70,7 @@ module Dependabot
|
|
|
66
70
|
|
|
67
71
|
private
|
|
68
72
|
|
|
73
|
+
sig { params(req_string: String).returns(T.any(String, T::Array[String])) }
|
|
69
74
|
def convert_go_constraint_to_ruby_constraint(req_string)
|
|
70
75
|
req_string = convert_wildcard_characters(req_string)
|
|
71
76
|
|
|
@@ -80,6 +85,7 @@ module Dependabot
|
|
|
80
85
|
end
|
|
81
86
|
end
|
|
82
87
|
|
|
88
|
+
sig { params(req_string: String).returns(String) }
|
|
83
89
|
def convert_wildcard_characters(req_string)
|
|
84
90
|
if req_string.match?(/^[\dv^>~]/)
|
|
85
91
|
replace_wildcard_in_lower_bound(req_string)
|
|
@@ -96,8 +102,9 @@ module Dependabot
|
|
|
96
102
|
end
|
|
97
103
|
end
|
|
98
104
|
|
|
105
|
+
sig { params(req_string: String).returns(String) }
|
|
99
106
|
def replace_wildcard_in_lower_bound(req_string)
|
|
100
|
-
after_wildcard = false
|
|
107
|
+
after_wildcard = T.let(false, T::Boolean)
|
|
101
108
|
|
|
102
109
|
req_string = req_string.gsub(/(?:(?:\.|^)[xX*])(\.[xX*])+/, "") if req_string.start_with?("~")
|
|
103
110
|
|
|
@@ -114,6 +121,7 @@ module Dependabot
|
|
|
114
121
|
end.join(".")
|
|
115
122
|
end
|
|
116
123
|
|
|
124
|
+
sig { params(req_string: String).returns(String) }
|
|
117
125
|
def convert_tilde_req(req_string)
|
|
118
126
|
version = req_string.gsub(/^~/, "")
|
|
119
127
|
parts = version.split(".")
|
|
@@ -121,11 +129,13 @@ module Dependabot
|
|
|
121
129
|
"~> #{parts.join('.')}"
|
|
122
130
|
end
|
|
123
131
|
|
|
132
|
+
sig { params(req_string: String).returns(T::Array[String]) }
|
|
124
133
|
def convert_hyphen_req(req_string)
|
|
125
134
|
lower_bound, upper_bound = req_string.split(/\s+-\s+/)
|
|
126
135
|
[">= #{lower_bound}", "<= #{upper_bound}"]
|
|
127
136
|
end
|
|
128
137
|
|
|
138
|
+
sig { params(req_string: String).returns(String) }
|
|
129
139
|
def ruby_range(req_string)
|
|
130
140
|
parts = req_string.split(".")
|
|
131
141
|
|
|
@@ -142,6 +152,7 @@ module Dependabot
|
|
|
142
152
|
|
|
143
153
|
# NOTE: Dep's caret notation implementation doesn't distinguish between
|
|
144
154
|
# pre and post-1.0.0 requirements (unlike in JS)
|
|
155
|
+
sig { params(req_string: String).returns(T::Array[String]) }
|
|
145
156
|
def convert_caret_req(req_string)
|
|
146
157
|
version = req_string.gsub(/^\^?v?/, "")
|
|
147
158
|
parts = version.split(".")
|
|
@@ -56,7 +56,11 @@ module Dependabot
|
|
|
56
56
|
|
|
57
57
|
private
|
|
58
58
|
|
|
59
|
-
attr_reader :dependency
|
|
59
|
+
attr_reader :dependency
|
|
60
|
+
attr_reader :dependency_files
|
|
61
|
+
attr_reader :credentials
|
|
62
|
+
attr_reader :ignored_versions
|
|
63
|
+
attr_reader :security_advisories
|
|
60
64
|
|
|
61
65
|
def fetch_latest_version
|
|
62
66
|
candidate_versions = available_versions
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dependabot-go_modules
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.249.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dependabot
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2024-03-
|
|
11
|
+
date: 2024-03-28 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: dependabot-common
|
|
@@ -16,14 +16,14 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - '='
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: 0.
|
|
19
|
+
version: 0.249.0
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - '='
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: 0.
|
|
26
|
+
version: 0.249.0
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: debug
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -267,7 +267,7 @@ licenses:
|
|
|
267
267
|
- Nonstandard
|
|
268
268
|
metadata:
|
|
269
269
|
bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
|
|
270
|
-
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.
|
|
270
|
+
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.249.0
|
|
271
271
|
post_install_message:
|
|
272
272
|
rdoc_options: []
|
|
273
273
|
require_paths:
|