Skip to content

Commit 637b597

Browse files
authored
Merge pull request #12747 from dependabot/jurre/go-proxy-support
Add support for goproxy_server and go.env files
2 parents 494e396 + 641565c commit 637b597

File tree

15 files changed

+196
-65
lines changed

15 files changed

+196
-65
lines changed

go_modules/lib/dependabot/go_modules/file_fetcher.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ def fetch_files
4141
fetched_files = go_mod ? [go_mod] : []
4242
# Fetch the (optional) go.sum
4343
fetched_files << T.must(go_sum) if go_sum
44+
fetched_files << T.must(go_env) if go_env
4445
fetched_files
4546
end
4647
end
@@ -56,6 +57,14 @@ def go_mod
5657
def go_sum
5758
@go_sum ||= T.let(fetch_file_if_present("go.sum"), T.nilable(Dependabot::DependencyFile))
5859
end
60+
61+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
62+
def go_env
63+
return @go_env if defined?(@go_env)
64+
65+
@go_env = T.let(fetch_support_file("go.env"), T.nilable(Dependabot::DependencyFile))
66+
@go_env
67+
end
5968
end
6069
end
6170
end

go_modules/lib/dependabot/go_modules/file_parser.rb

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,18 @@ module GoModules
2020
class FileParser < Dependabot::FileParsers::Base
2121
extend T::Sig
2222

23+
sig do
24+
params(dependency_files: T::Array[Dependabot::DependencyFile], source: T.nilable(Dependabot::Source),
25+
repo_contents_path: T.nilable(String), credentials: T::Array[Dependabot::Credential],
26+
reject_external_code: T::Boolean, options: T::Hash[Symbol, T.untyped]).void
27+
end
28+
def initialize(dependency_files:, source: nil, repo_contents_path: nil,
29+
credentials: [], reject_external_code: false, options: {})
30+
super
31+
32+
set_go_environment_variables
33+
end
34+
2335
sig { override.returns(T::Array[Dependabot::Dependency]) }
2436
def parse
2537
dependency_set = Dependabot::FileParsers::Base::DependencySet.new
@@ -50,6 +62,48 @@ def ecosystem
5062

5163
private
5264

65+
sig { void }
66+
def set_go_environment_variables
67+
set_goenv_variable
68+
set_goproxy_variable
69+
set_goprivate_variable
70+
end
71+
72+
sig { void }
73+
def set_goenv_variable
74+
return unless go_env
75+
76+
env_file = T.must(go_env)
77+
File.write(env_file.name, env_file.content)
78+
ENV["GOENV"] = Pathname.new(env_file.name).realpath.to_s
79+
end
80+
81+
sig { void }
82+
def set_goprivate_variable
83+
return if go_env&.content&.include?("GOPRIVATE")
84+
return if go_env&.content&.include?("GOPROXY")
85+
return if goproxy_credentials.any?
86+
87+
goprivate = options.fetch(:goprivate, "*")
88+
ENV["GOPRIVATE"] = goprivate if goprivate
89+
end
90+
91+
sig { void }
92+
def set_goproxy_variable
93+
return if go_env&.content&.include?("GOPROXY")
94+
return if goproxy_credentials.empty?
95+
96+
urls = goproxy_credentials.filter_map { |cred| cred["url"] }
97+
ENV["GOPROXY"] = "#{urls.join(',')},direct"
98+
end
99+
100+
sig { returns(T::Array[Dependabot::Credential]) }
101+
def goproxy_credentials
102+
@goproxy_credentials ||= T.let(credentials.select do |cred|
103+
cred["type"] == "goproxy_server"
104+
end, T.nilable(T::Array[Dependabot::Credential]))
105+
end
106+
53107
sig { returns(Ecosystem::VersionManager) }
54108
def package_manager
55109
@package_manager ||= T.let(
@@ -85,6 +139,11 @@ def go_mod
85139
@go_mod ||= T.let(get_original_file("go.mod"), T.nilable(Dependabot::DependencyFile))
86140
end
87141

142+
sig { returns(T.nilable(Dependabot::DependencyFile)) }
143+
def go_env
144+
@go_env ||= T.let(get_original_file("go.env"), T.nilable(Dependabot::DependencyFile))
145+
end
146+
88147
sig { override.void }
89148
def check_required_files
90149
raise "No go.mod!" unless go_mod

go_modules/lib/dependabot/go_modules/file_updater.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ class FileUpdater < Dependabot::FileUpdaters::Base
2929
def initialize(dependencies:, dependency_files:, credentials:, repo_contents_path: nil, options: {})
3030
super
3131

32-
@goprivate = T.let(options.fetch(:goprivate, "*"), String)
3332
use_repo_contents_stub if repo_contents_path.nil?
3433
end
3534

@@ -149,7 +148,7 @@ def file_updater
149148
credentials: credentials,
150149
repo_contents_path: repo_contents_path,
151150
directory: T.must(directory),
152-
options: { tidy: tidy?, vendor: vendor?, goprivate: @goprivate }
151+
options: { tidy: tidy?, vendor: vendor? }
153152
),
154153
T.nilable(Dependabot::GoModules::FileUpdater::GoModUpdater)
155154
)

go_modules/lib/dependabot/go_modules/file_updater/go_mod_updater.rb

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ def initialize(dependencies:, dependency_files:, credentials:, repo_contents_pat
9696
@directory = directory
9797
@tidy = T.let(options.fetch(:tidy, false), T::Boolean)
9898
@vendor = T.let(options.fetch(:vendor, false), T::Boolean)
99-
@goprivate = T.let(options.fetch(:goprivate), T.nilable(String))
10099
end
101100

102101
sig { returns(T.nilable(String)) }
@@ -188,7 +187,7 @@ def run_go_mod_tidy
188187
# continue with an info log here. `go mod tidy` shouldn't block
189188
# updating versions because there are some edge cases where it's OK to fail
190189
# (such as generated files not available yet to us).
191-
_, stderr, status = Open3.capture3(environment, command)
190+
_, stderr, status = Open3.capture3(command)
192191
if status.success?
193192
Dependabot.logger.info "`go mod tidy` succeeded"
194193
else
@@ -201,7 +200,7 @@ def run_go_vendor
201200
return unless vendor?
202201

203202
command = "go mod vendor"
204-
_, stderr, status = Open3.capture3(environment, command)
203+
_, stderr, status = Open3.capture3(command)
205204
handle_subprocess_error(stderr) unless status.success?
206205
end
207206

@@ -225,7 +224,7 @@ def run_go_get(dependencies = [])
225224
end
226225
command = SharedHelpers.escape_command(command)
227226

228-
_, stderr, status = Open3.capture3(environment, command)
227+
_, stderr, status = Open3.capture3(command)
229228
handle_subprocess_error(stderr) unless status.success?
230229
ensure
231230
FileUtils.rm_f(T.must(tmp_go_file))
@@ -234,7 +233,7 @@ def run_go_get(dependencies = [])
234233
sig { returns(T::Hash[String, T.untyped]) }
235234
def parse_manifest
236235
command = "go mod edit -json"
237-
stdout, stderr, status = Open3.capture3(environment, command)
236+
stdout, stderr, status = Open3.capture3(command)
238237
handle_subprocess_error(stderr) unless status.success?
239238

240239
JSON.parse(stdout) || {}
@@ -305,7 +304,7 @@ def handle_subprocess_error(stderr) # rubocop:disable Metrics/AbcSize
305304
end
306305

307306
repo_error_regex = REPO_RESOLVABILITY_ERROR_REGEXES.find { |r| stderr =~ r }
308-
ResolvabilityErrors.handle(stderr, goprivate: @goprivate) if repo_error_regex
307+
ResolvabilityErrors.handle(stderr) if repo_error_regex
309308

310309
path_regex = MODULE_PATH_MISMATCH_REGEXES.find { |r| stderr =~ r }
311310
if path_regex
@@ -366,11 +365,6 @@ def tidy?
366365
def vendor?
367366
!!@vendor
368367
end
369-
370-
sig { returns(T::Hash[String, T.untyped]) }
371-
def environment
372-
{ "GOPRIVATE" => @goprivate }
373-
end
374368
end
375369
end
376370
end

go_modules/lib/dependabot/go_modules/package/package_details_fetcher.rb

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,13 @@ class PackageDetailsFetcher
4141
params(
4242
dependency: Dependabot::Dependency,
4343
dependency_files: T::Array[Dependabot::DependencyFile],
44-
credentials: T::Array[Dependabot::Credential],
45-
goprivate: String
44+
credentials: T::Array[Dependabot::Credential]
4645
).void
4746
end
48-
def initialize(dependency:, dependency_files:, credentials:, goprivate:)
47+
def initialize(dependency:, dependency_files:, credentials:)
4948
@dependency = dependency
5049
@dependency_files = dependency_files
5150
@credentials = credentials
52-
@goprivate = T.let(goprivate, String)
5351

5452
@source_type = T.let(nil, T.nilable(String))
5553
end
@@ -63,9 +61,6 @@ def initialize(dependency:, dependency_files:, credentials:, goprivate:)
6361
sig { returns(T::Array[T.untyped]) }
6462
attr_reader :credentials
6563

66-
sig { returns(String) }
67-
attr_reader :goprivate
68-
6964
# rubocop:disable Metrics/AbcSize,Metrics/PerceivedComplexity
7065
sig { returns(T::Array[Dependabot::Package::PackageRelease]) }
7166
def fetch_available_versions
@@ -82,12 +77,9 @@ def fetch_available_versions
8277
end
8378

8479
# Turn off the module proxy for private dependencies
85-
env = { "GOPRIVATE" => @goprivate }
86-
8780
versions_json = SharedHelpers.run_shell_command(
8881
"go list -m -versions -json #{dependency.name}",
89-
fingerprint: "go list -m -versions -json <dependency_name>",
90-
env: env
82+
fingerprint: "go list -m -versions -json <dependency_name>"
9183
)
9284
version_strings = JSON.parse(versions_json)["Versions"]
9385

@@ -112,7 +104,7 @@ def fetch_available_versions
112104
retry_count += 1
113105
retry if transitory_failure?(e) && retry_count < 2
114106

115-
ResolvabilityErrors.handle(e.message, goprivate: @goprivate)
107+
ResolvabilityErrors.handle(e.message)
116108
[package_release(version: T.must(dependency.version))]
117109
end
118110
# rubocop:enable Metrics/AbcSize,Metrics/PerceivedComplexity

go_modules/lib/dependabot/go_modules/resolvability_errors.rb

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ module ResolvabilityErrors
1010

1111
GITHUB_REPO_REGEX = %r{github.com/[^:@ ]*}
1212

13-
sig { params(message: String, goprivate: T.untyped).void }
14-
def self.handle(message, goprivate:)
13+
sig { params(message: String).void }
14+
def self.handle(message)
1515
mod_path = message.scan(GITHUB_REPO_REGEX).last
1616
unless mod_path && message.include?("If this is a private repository")
1717
raise Dependabot::DependencyFileNotResolvable, message
@@ -30,8 +30,7 @@ def self.handle(message, goprivate:)
3030
mod_path
3131
end
3232

33-
env = { "GOPRIVATE" => goprivate }
34-
_, _, status = Open3.capture3(env, SharedHelpers.escape_command("go list -m -versions #{repo_path}"))
33+
_, _, status = Open3.capture3(SharedHelpers.escape_command("go list -m -versions #{repo_path}"))
3534
raise Dependabot::DependencyFileNotResolvable, message if status.success?
3635

3736
raise Dependabot::GitDependenciesNotReachable, [repo_path]

go_modules/lib/dependabot/go_modules/update_checker.rb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# typed: strict
1+
# typed: strong
22
# frozen_string_literal: true
33

44
require "sorbet-runtime"
@@ -66,8 +66,7 @@ def latest_version_finder
6666
ignored_versions: ignored_versions,
6767
security_advisories: security_advisories,
6868
raise_on_ignored: raise_on_ignored,
69-
cooldown_options: update_cooldown,
70-
goprivate: options.fetch(:goprivate, "*")
69+
cooldown_options: update_cooldown
7170
),
7271
T.nilable(Dependabot::GoModules::UpdateChecker::LatestVersionFinder)
7372
)

go_modules/lib/dependabot/go_modules/update_checker/latest_version_finder.rb

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ class LatestVersionFinder < Dependabot::Package::PackageLatestVersionFinder
4646
credentials: T::Array[Dependabot::Credential],
4747
ignored_versions: T::Array[String],
4848
security_advisories: T::Array[Dependabot::SecurityAdvisory],
49-
goprivate: String,
5049
raise_on_ignored: T::Boolean,
5150
cooldown_options: T.nilable(Dependabot::Package::ReleaseCooldownOptions)
5251
)
@@ -58,7 +57,6 @@ def initialize(
5857
credentials:,
5958
ignored_versions:,
6059
security_advisories:,
61-
goprivate:,
6260
raise_on_ignored: false,
6361
cooldown_options: nil
6462
)
@@ -68,7 +66,6 @@ def initialize(
6866
@ignored_versions = ignored_versions
6967
@security_advisories = security_advisories
7068
@raise_on_ignored = raise_on_ignored
71-
@goprivate = goprivate
7269
@cooldown_options = cooldown_options
7370
super(
7471
dependency: dependency,
@@ -122,9 +119,6 @@ def cooldown_enabled?
122119
sig { returns(T::Array[Dependabot::SecurityAdvisory]) }
123120
attr_reader :security_advisories
124121

125-
sig { returns(String) }
126-
attr_reader :goprivate
127-
128122
sig { returns(T.nilable(Dependabot::Package::ReleaseCooldownOptions)) }
129123
attr_reader :cooldown_options
130124

@@ -133,8 +127,7 @@ def available_versions_details
133127
@available_versions_details ||= T.let(Package::PackageDetailsFetcher.new(
134128
dependency: dependency,
135129
dependency_files: dependency_files,
136-
credentials: credentials,
137-
goprivate: goprivate
130+
credentials: credentials
138131
).fetch_available_versions, T.nilable(T::Array[Dependabot::Package::PackageRelease]))
139132
end
140133

@@ -197,13 +190,10 @@ def lazy_filter_cooldown_versions(releases, check_max: true)
197190
# rubocop:disable Metrics/AbcSize
198191
sig { params(release: Dependabot::Package::PackageRelease).returns(T::Boolean) }
199192
def in_cooldown_period?(release)
200-
env = { "GOPRIVATE" => @goprivate }
201-
202193
begin
203194
release_info = SharedHelpers.run_shell_command(
204195
"go list -m -json #{dependency.name}@#{release.details.[]('version_string')}",
205-
fingerprint: "go list -m -json <dependency_name>",
206-
env: env
196+
fingerprint: "go list -m -json <dependency_name>"
207197
)
208198
rescue Dependabot::SharedHelpers::HelperSubprocessFailed => e
209199
Dependabot.logger.info("Error while fetching release date info: #{e.message}")

go_modules/spec/dependabot/go_modules/file_fetcher_spec.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@
5757
end
5858
end
5959

60+
context "with a go.env file" do
61+
let(:branch) { "with-go-env" }
62+
63+
it "fetches the go.env file" do
64+
expect(file_fetcher_instance.files.map(&:name)).to include("go.env")
65+
end
66+
end
67+
6068
context "when directory is missing" do
6169
let(:directory) { "/missing" }
6270

0 commit comments

Comments
 (0)