Skip to content

Commit

Permalink
Generate alternatives for every git source (#3417)
Browse files Browse the repository at this point in the history
Generate alternatives for every git source (not just GitHub) (@jerbob92)
  • Loading branch information
jerbob92 authored Mar 31, 2021
1 parent 58d3135 commit 8c63c95
Show file tree
Hide file tree
Showing 2 changed files with 170 additions and 32 deletions.
68 changes: 36 additions & 32 deletions common/lib/dependabot/shared_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -161,47 +161,21 @@ def self.with_git_configured(credentials:)
reset_global_git_config(backup_git_config_path)
end

def self.credential_helper_path
File.join(__dir__, "../../bin/git-credential-store-immutable")
end

# rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/PerceivedComplexity
def self.configure_git_to_use_https_with_credentials(credentials)
File.open(GIT_CONFIG_GLOBAL_PATH, "w") do |file|
file << "# Generated by dependabot/dependabot-core"
end
configure_git_to_use_https
configure_git_credentials(credentials)
end

def self.configure_git_to_use_https
# NOTE: we use --global here (rather than --system) so that Dependabot
# can be run without privileged access
run_shell_command(
"git config --global --replace-all url.https://github.com/."\
"insteadOf ssh://[email protected]/"
)
run_shell_command(
"git config --global --add url.https://github.com/."\
"insteadOf ssh://[email protected]:"
)
run_shell_command(
"git config --global --add url.https://github.com/."\
"insteadOf [email protected]:"
)
run_shell_command(
"git config --global --add url.https://github.com/."\
"insteadOf [email protected]/"
)
run_shell_command(
"git config --global --add url.https://github.com/."\
"insteadOf git://github.com/"
)
end

# rubocop:disable Metrics/PerceivedComplexity
def self.configure_git_credentials(credentials)
# Then add a file-based credential store that loads a file in this repo.
# Under the hood this uses git credential-store, but it's invoked through
# a wrapper binary that only allows non-mutating commands. Without this,
# whenever the credentials are deemed to be invalid, they're erased.
credential_helper_path =
File.join(__dir__, "../../bin/git-credential-store-immutable")
run_shell_command(
"git config --global credential.helper "\
"'!#{credential_helper_path} --file #{Dir.pwd}/git.store'",
Expand All @@ -219,6 +193,9 @@ def self.configure_git_credentials(credentials)
github_credentials.find { |c| !c["password"]&.start_with?("v1.") } ||
github_credentials.first

# Make sure we always have https alternatives for github.com.
configure_git_to_use_https("github.com") if github_credential.nil?

deduped_credentials = credentials -
github_credentials +
[github_credential].compact
Expand All @@ -234,13 +211,40 @@ def self.configure_git_credentials(credentials)
"@#{cred.fetch('host')}"

git_store_content += authenticated_url + "\n"
configure_git_to_use_https(cred.fetch("host"))
end

# Save the file
File.write("git.store", git_store_content)
end
# rubocop:enable Metrics/AbcSize
# rubocop:enable Metrics/PerceivedComplexity

def self.configure_git_to_use_https(host)
# NOTE: we use --global here (rather than --system) so that Dependabot
# can be run without privileged access
run_shell_command(
"git config --global --replace-all url.https://#{host}/."\
"insteadOf ssh://git@#{host}/"
)
run_shell_command(
"git config --global --add url.https://#{host}/."\
"insteadOf ssh://git@#{host}:"
)
run_shell_command(
"git config --global --add url.https://#{host}/."\
"insteadOf git@#{host}:"
)
run_shell_command(
"git config --global --add url.https://#{host}/."\
"insteadOf git@#{host}/"
)
run_shell_command(
"git config --global --add url.https://#{host}/."\
"insteadOf git://#{host}/"
)
end

def self.reset_git_repo(path)
Dir.chdir(path) do
run_shell_command("git reset HEAD --hard")
Expand Down
134 changes: 134 additions & 0 deletions common/spec/dependabot/shared_helpers_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -314,4 +314,138 @@
)
end
end

describe ".with_git_configured" do
config_header = "Generated by dependabot/dependabot-core"

credentials_helper = <<~CONFIG.chomp
[credential]
helper = !#{Dependabot::SharedHelpers.credential_helper_path} --file #{Dir.pwd}/git.store
CONFIG

def alternatives(host)
<<~CONFIG.chomp
[url "https://#{host}/"]
insteadOf = ssh://git@#{host}/
insteadOf = ssh://git@#{host}:
insteadOf = git@#{host}:
insteadOf = git@#{host}/
insteadOf = git://#{host}/
CONFIG
end

let(:credentials) { [] }

def with_git_configured(&block)
Dependabot::SharedHelpers.with_git_configured(credentials: credentials) { block.call }
end

let(:configured_git_config) { with_git_configured { `cat ~/.gitconfig` } }
let(:configured_git_credentials) { with_git_configured { `cat #{Dir.pwd}/git.store` } }

context "when providing no extra credentials" do
let(:credentials) { [] }

it "creates a .gitconfig that contains the Dependabot header" do
expect(configured_git_config).to include(config_header)
end

it "creates a .gitconfig that contains the credentials helper" do
expect(configured_git_config).to include(credentials_helper)
end

it "creates a .gitconfig that contains the github.com alternatives" do
expect(configured_git_config).to include(alternatives("github.com"))
end

it "creates a git credentials store that is empty" do
expect(configured_git_credentials).to eq("")
end
end

context "when providing github.com credentials" do
let(:credentials) do
[
{
"type" => "git_source",
"host" => "github.com",
"username" => "x-access-token",
"password" => "fake-token"
}
]
end

it "creates a .gitconfig that contains the Dependabot header" do
expect(configured_git_config).to include(config_header)
end

it "creates a .gitconfig that contains the credentials helper" do
expect(configured_git_config).to include(credentials_helper)
end

it "creates a .gitconfig that contains the github.com alternatives" do
expect(configured_git_config).to include(alternatives("github.com"))
end

it "creates a git credentials store that contains github.com credentials" do
expect(configured_git_credentials).to eq("https://x-access-token:[email protected]\n")
end
end

context "when providing multiple github.com credentials" do
let(:credentials) do
[
{
"type" => "git_source",
"host" => "github.com",
"username" => "x-access-token",
"password" => "v1.fake-token"
},
{
"type" => "git_source",
"host" => "github.com",
"username" => "x-access-token",
"password" => "fake-token"
}
]
end

it "creates a git credentials store that contains non-app-token github.com credentials" do
expect(configured_git_credentials).to eq("https://x-access-token:[email protected]\n")
end
end

context "when providing private git_source credentials" do
let(:credentials) do
[
{
"type" => "git_source",
"host" => "private.com",
"username" => "x-access-token",
"password" => "fake-token"
}
]
end

it "creates a .gitconfig that contains the Dependabot header" do
expect(configured_git_config).to include(config_header)
end

it "creates a .gitconfig that contains the credentials helper" do
expect(configured_git_config).to include(credentials_helper)
end

it "creates a .gitconfig that contains the github.com alternatives" do
expect(configured_git_config).to include(alternatives("github.com"))
end

it "creates a .gitconfig that contains the private.com alternatives" do
expect(configured_git_config).to include(alternatives("private.com"))
end

it "creates a git credentials store that contains private git credentials" do
expect(configured_git_credentials).to eq("https://x-access-token:[email protected]\n")
end
end
end
end

0 comments on commit 8c63c95

Please sign in to comment.