summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Rodríguez <[email protected]>2023-06-30 13:45:39 +0200
committerHiroshi SHIBATA <[email protected]>2023-07-04 14:54:26 +0900
commit09382135de5e706d7b100900cc81ddf91f4d3314 (patch)
treea6f5dce3db76854deffdf1d01ce0ee67febf4793
parent0ae2709dd71eaefe4a316bdbc9e97eaef3c7ae69 (diff)
[rubygems/rubygems] Fix git source lockfile unstability
We have some flags that limit running git commit commands under certain situations, for example, when running under `--local`. However, those should only affect remote git operations, not local read-only operations like `git --version`, or `git rev-parse --abbrev-ref HEAD`. This commit refactors things to achieve that. By doing this, the `#to_s` representation of a source is more consistent, since we don't get any errors when reading the checked out branch, and we avoid some flip-flop lockfile issues. https://github.com/rubygems/rubygems/commit/4a529fce81
-rw-r--r--lib/bundler/source/git/git_proxy.rb44
-rw-r--r--spec/bundler/bundler/env_spec.rb2
-rw-r--r--spec/bundler/bundler/source/git/git_proxy_spec.rb20
3 files changed, 42 insertions, 24 deletions
diff --git a/lib/bundler/source/git/git_proxy.rb b/lib/bundler/source/git/git_proxy.rb
index 926c9b8ead..53a9a78ddf 100644
--- a/lib/bundler/source/git/git_proxy.rb
+++ b/lib/bundler/source/git/git_proxy.rb
@@ -67,8 +67,8 @@ module Bundler
end
def current_branch
- @current_branch ||= allowed_with_path do
- git("rev-parse", "--abbrev-ref", "HEAD", :dir => path).strip
+ @current_branch ||= with_path do
+ git_local("rev-parse", "--abbrev-ref", "HEAD", :dir => path).strip
end
end
@@ -84,7 +84,7 @@ module Bundler
end
def full_version
- @full_version ||= git("--version").sub(/git version\s*/, "").strip
+ @full_version ||= git_local("--version").sub(/git version\s*/, "").strip
end
def checkout
@@ -253,15 +253,15 @@ module Bundler
end
def git(*command, dir: nil)
- command_with_no_credentials = check_allowed(command)
-
- out, err, status = capture(command, dir)
-
- raise GitCommandError.new(command_with_no_credentials, dir || SharedHelpers.pwd, err) unless status.success?
-
- Bundler.ui.warn err unless err.empty?
+ run_command(*command, :dir => dir) do |unredacted_command|
+ check_allowed(unredacted_command)
+ end
+ end
- out
+ def git_local(*command, dir: nil)
+ run_command(*command, :dir => dir) do |unredacted_command|
+ redact_and_check_presence(unredacted_command)
+ end
end
def has_revision_cached?
@@ -330,12 +330,30 @@ module Bundler
end
def check_allowed(command)
- require "shellwords"
- command_with_no_credentials = URICredentialsFilter.credential_filtered_string("git #{command.shelljoin}", uri)
+ command_with_no_credentials = redact_and_check_presence(command)
raise GitNotAllowedError.new(command_with_no_credentials) unless allow?
command_with_no_credentials
end
+ def redact_and_check_presence(command)
+ raise GitNotInstalledError.new unless Bundler.git_present?
+
+ require "shellwords"
+ URICredentialsFilter.credential_filtered_string("git #{command.shelljoin}", uri)
+ end
+
+ def run_command(*command, dir: nil)
+ command_with_no_credentials = yield(command)
+
+ out, err, status = capture(command, dir)
+
+ raise GitCommandError.new(command_with_no_credentials, dir || SharedHelpers.pwd, err) unless status.success?
+
+ Bundler.ui.warn err unless err.empty?
+
+ out
+ end
+
def capture(cmd, dir, ignore_err: false)
SharedHelpers.with_clean_git_env do
require "open3"
diff --git a/spec/bundler/bundler/env_spec.rb b/spec/bundler/bundler/env_spec.rb
index 186b207b9f..a00489d0e5 100644
--- a/spec/bundler/bundler/env_spec.rb
+++ b/spec/bundler/bundler/env_spec.rb
@@ -217,7 +217,7 @@ RSpec.describe Bundler::Env do
context "when the git version is OS specific" do
it "includes OS specific information with the version number" do
- expect(git_proxy_stub).to receive(:git).with("--version").
+ expect(git_proxy_stub).to receive(:git_local).with("--version").
and_return("git version 1.2.3 (Apple Git-BS)")
expect(Bundler::Source::Git::GitProxy).to receive(:new).and_return(git_proxy_stub)
diff --git a/spec/bundler/bundler/source/git/git_proxy_spec.rb b/spec/bundler/bundler/source/git/git_proxy_spec.rb
index 98d54015e7..c79dd8ff71 100644
--- a/spec/bundler/bundler/source/git/git_proxy_spec.rb
+++ b/spec/bundler/bundler/source/git/git_proxy_spec.rb
@@ -13,7 +13,7 @@ RSpec.describe Bundler::Source::Git::GitProxy do
context "with configured credentials" do
it "adds username and password to URI" do
Bundler.settings.temporary(uri => "u:p") do
- allow(subject).to receive(:git).with("--version").and_return("git version 2.14.0")
+ allow(subject).to receive(:git_local).with("--version").and_return("git version 2.14.0")
expect(subject).to receive(:capture).with([*base_clone_args, "--", "https://u:[email protected]/rubygems/rubygems.git", path.to_s], nil).and_return(["", "", clone_result])
subject.checkout
end
@@ -21,7 +21,7 @@ RSpec.describe Bundler::Source::Git::GitProxy do
it "adds username and password to URI for host" do
Bundler.settings.temporary("github.com" => "u:p") do
- allow(subject).to receive(:git).with("--version").and_return("git version 2.14.0")
+ allow(subject).to receive(:git_local).with("--version").and_return("git version 2.14.0")
expect(subject).to receive(:capture).with([*base_clone_args, "--", "https://u:[email protected]/rubygems/rubygems.git", path.to_s], nil).and_return(["", "", clone_result])
subject.checkout
end
@@ -29,7 +29,7 @@ RSpec.describe Bundler::Source::Git::GitProxy do
it "does not add username and password to mismatched URI" do
Bundler.settings.temporary("https://u:[email protected]/rubygems/rubygems-mismatch.git" => "u:p") do
- allow(subject).to receive(:git).with("--version").and_return("git version 2.14.0")
+ allow(subject).to receive(:git_local).with("--version").and_return("git version 2.14.0")
expect(subject).to receive(:capture).with([*base_clone_args, "--", uri, path.to_s], nil).and_return(["", "", clone_result])
subject.checkout
end
@@ -39,7 +39,7 @@ RSpec.describe Bundler::Source::Git::GitProxy do
Bundler.settings.temporary("github.com" => "u:p") do
original = "https://orig:[email protected]/rubygems/rubygems.git"
subject = described_class.new(Pathname("path"), original, "HEAD")
- allow(subject).to receive(:git).with("--version").and_return("git version 2.14.0")
+ allow(subject).to receive(:git_local).with("--version").and_return("git version 2.14.0")
expect(subject).to receive(:capture).with([*base_clone_args, "--", original, path.to_s], nil).and_return(["", "", clone_result])
subject.checkout
end
@@ -49,7 +49,7 @@ RSpec.describe Bundler::Source::Git::GitProxy do
describe "#version" do
context "with a normal version number" do
before do
- expect(subject).to receive(:git).with("--version").
+ expect(subject).to receive(:git_local).with("--version").
and_return("git version 1.2.3")
end
@@ -64,7 +64,7 @@ RSpec.describe Bundler::Source::Git::GitProxy do
context "with a OSX version number" do
before do
- expect(subject).to receive(:git).with("--version").
+ expect(subject).to receive(:git_local).with("--version").
and_return("git version 1.2.3 (Apple Git-BS)")
end
@@ -79,7 +79,7 @@ RSpec.describe Bundler::Source::Git::GitProxy do
context "with a msysgit version number" do
before do
- expect(subject).to receive(:git).with("--version").
+ expect(subject).to receive(:git_local).with("--version").
and_return("git version 1.2.3.msysgit.0")
end
@@ -96,7 +96,7 @@ RSpec.describe Bundler::Source::Git::GitProxy do
describe "#full_version" do
context "with a normal version number" do
before do
- expect(subject).to receive(:git).with("--version").
+ expect(subject).to receive(:git_local).with("--version").
and_return("git version 1.2.3")
end
@@ -107,7 +107,7 @@ RSpec.describe Bundler::Source::Git::GitProxy do
context "with a OSX version number" do
before do
- expect(subject).to receive(:git).with("--version").
+ expect(subject).to receive(:git_local).with("--version").
and_return("git version 1.2.3 (Apple Git-BS)")
end
@@ -118,7 +118,7 @@ RSpec.describe Bundler::Source::Git::GitProxy do
context "with a msysgit version number" do
before do
- expect(subject).to receive(:git).with("--version").
+ expect(subject).to receive(:git_local).with("--version").
and_return("git version 1.2.3.msysgit.0")
end