diff --git a/common/lib/dependabot/shared_helpers.rb b/common/lib/dependabot/shared_helpers.rb index fb4cd64c592..38533ff37b9 100644 --- a/common/lib/dependabot/shared_helpers.rb +++ b/common/lib/dependabot/shared_helpers.rb @@ -10,6 +10,7 @@ require "shellwords" require "sorbet-runtime" require "tmpdir" +require "securerandom" require "dependabot/credential" require "dependabot/simple_instrumentor" @@ -22,7 +23,6 @@ module Dependabot module SharedHelpers extend T::Sig - GIT_CONFIG_GLOBAL_PATH = T.let(File.expand_path(".gitconfig", Utils::BUMP_TMP_DIR_PATH), String) USER_AGENT = T.let( "dependabot-core/#{Dependabot::VERSION} " \ "#{Excon::USER_AGENT} ruby/#{RUBY_VERSION} " \ @@ -258,10 +258,13 @@ def self.with_git_configured(credentials:, &_block) FileUtils.mkdir_p(Utils::BUMP_TMP_DIR_PATH) previous_config = ENV.fetch("GIT_CONFIG_GLOBAL", nil) + # adding a random suffix to avoid conflicts when running in parallel + # some package managers like bundler will modify the global git config + git_config_global_path = File.expand_path("#{SecureRandom.hex(16)}.gitconfig", Utils::BUMP_TMP_DIR_PATH) begin - ENV["GIT_CONFIG_GLOBAL"] = GIT_CONFIG_GLOBAL_PATH - configure_git_to_use_https_with_credentials(credentials, safe_directories) + ENV["GIT_CONFIG_GLOBAL"] = git_config_global_path + configure_git_to_use_https_with_credentials(credentials, safe_directories, git_config_global_path) yield ensure ENV["GIT_CONFIG_GLOBAL"] = previous_config @@ -269,7 +272,7 @@ def self.with_git_configured(credentials:, &_block) rescue Errno::ENOSPC => e raise Dependabot::OutOfDisk, e.message ensure - FileUtils.rm_f(GIT_CONFIG_GLOBAL_PATH) + FileUtils.rm_f(T.must(git_config_global_path)) end # Handle SCP-style git URIs @@ -286,9 +289,12 @@ def self.credential_helper_path end # rubocop:disable Metrics/PerceivedComplexity - sig { params(credentials: T::Array[Dependabot::Credential], safe_directories: T::Array[String]).void } - def self.configure_git_to_use_https_with_credentials(credentials, safe_directories) - File.open(GIT_CONFIG_GLOBAL_PATH, "w") do |file| + sig do + params(credentials: T::Array[Dependabot::Credential], safe_directories: T::Array[String], + git_config_global_path: String).void + end + def self.configure_git_to_use_https_with_credentials(credentials, safe_directories, git_config_global_path) + File.open(git_config_global_path, "w") do |file| file << "# Generated by dependabot/dependabot-core" end diff --git a/common/spec/dependabot/shared_helpers_spec.rb b/common/spec/dependabot/shared_helpers_spec.rb index 0f2b03aedd2..5c578024ecc 100644 --- a/common/spec/dependabot/shared_helpers_spec.rb +++ b/common/spec/dependabot/shared_helpers_spec.rb @@ -409,7 +409,10 @@ def with_git_configured(&block) Dependabot::SharedHelpers.with_git_configured(credentials: credentials, &block) end - let(:git_config_path) { File.expand_path(".gitconfig", tmp) } + before do + allow(SecureRandom).to receive(:hex).and_return("XXXXXXXXXXXXXXXX") + end + let(:git_config_path) { File.expand_path("XXXXXXXXXXXXXXXX.gitconfig", tmp) } let(:configured_git_config) { with_git_configured { `cat #{git_config_path}` } } let(:configured_git_credentials) { with_git_configured { `cat #{Dir.pwd}/git.store` } } @@ -553,10 +556,10 @@ def with_git_configured(&block) context "when the host has run out of disk space" do before do allow(File).to receive(:open) - .with(described_class::GIT_CONFIG_GLOBAL_PATH, anything) + .with(git_config_path, anything) .and_raise(Errno::ENOSPC) allow(FileUtils).to receive(:rm_f) - .with(described_class::GIT_CONFIG_GLOBAL_PATH) + .with(git_config_path) end specify { expect { configured_git_config }.to raise_error(Dependabot::OutOfDisk) }