Skip to content

Commit b909f7a

Browse files
martinemdedeivid-rodriguez
authored andcommitted
Merge pull request #6959 from pboling/fix-git-proxy-for-branch-and-ref
(cherry picked from commit c2c0966)
1 parent f8a0d17 commit b909f7a

File tree

13 files changed

+108
-41
lines changed

13 files changed

+108
-41
lines changed

bundler/lib/bundler/cli/info.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def spec_for_gem(gem_name)
3333
def default_gem_spec(gem_name)
3434
return unless Gem::Specification.respond_to?(:find_all_by_name)
3535
gem_spec = Gem::Specification.find_all_by_name(gem_name).last
36-
return gem_spec if gem_spec&.default_gem?
36+
gem_spec if gem_spec&.default_gem?
3737
end
3838

3939
def spec_not_found(gem_name)

bundler/lib/bundler/retry.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def fail_attempt(e)
5656
def keep_trying?
5757
return true if current_run.zero?
5858
return false if last_attempt?
59-
return true if @failed
59+
true if @failed
6060
end
6161

6262
def last_attempt?

bundler/lib/bundler/source/git/git_proxy.rb

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@ def initialize(command, destination_path, ref, repo)
4343
end
4444
end
4545

46+
class AmbiguousGitReference < GitError
47+
def initialize(options)
48+
msg = "Specification of branch or ref with tag is ambiguous. You specified #{options.inspect}"
49+
super msg
50+
end
51+
end
52+
4653
# The GitProxy is responsible to interact with git repositories.
4754
# All actions required by the Git source is encapsulated in this
4855
# object.
@@ -53,10 +60,15 @@ class GitProxy
5360
def initialize(path, uri, options = {}, revision = nil, git = nil)
5461
@path = path
5562
@uri = uri
56-
@branch = options["branch"]
5763
@tag = options["tag"]
64+
@branch = options["branch"]
5865
@ref = options["ref"]
59-
@explicit_ref = branch || tag || ref
66+
if @tag
67+
raise AmbiguousGitReference.new(options) if @branch || @ref
68+
@explicit_ref = @tag
69+
else
70+
@explicit_ref = @ref || @branch
71+
end
6072
@revision = revision
6173
@git = git
6274
@commit_ref = nil

bundler/spec/bundler/source/git/git_proxy_spec.rb

Lines changed: 77 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,127 +3,177 @@
33
RSpec.describe Bundler::Source::Git::GitProxy do
44
let(:path) { Pathname("path") }
55
let(:uri) { "https://github.com/rubygems/rubygems.git" }
6-
let(:ref) { "HEAD" }
6+
let(:ref) { nil }
7+
let(:branch) { nil }
8+
let(:tag) { nil }
9+
let(:options) { { "ref" => ref, "branch" => branch, "tag" => tag }.compact }
710
let(:revision) { nil }
811
let(:git_source) { nil }
912
let(:clone_result) { double(Process::Status, :success? => true) }
1013
let(:base_clone_args) { ["clone", "--bare", "--no-hardlinks", "--quiet", "--no-tags", "--depth", "1", "--single-branch"] }
11-
subject { described_class.new(path, uri, ref, revision, git_source) }
14+
subject(:git_proxy) { described_class.new(path, uri, options, revision, git_source) }
15+
16+
context "with explicit ref" do
17+
context "with branch only" do
18+
let(:branch) { "main" }
19+
it "sets explicit ref to branch" do
20+
expect(git_proxy.explicit_ref).to eq(branch)
21+
end
22+
end
23+
24+
context "with ref only" do
25+
let(:ref) { "HEAD" }
26+
it "sets explicit ref to ref" do
27+
expect(git_proxy.explicit_ref).to eq(ref)
28+
end
29+
end
30+
31+
context "with tag only" do
32+
let(:tag) { "v1.0" }
33+
it "sets explicit ref to ref" do
34+
expect(git_proxy.explicit_ref).to eq(tag)
35+
end
36+
end
37+
38+
context "with tag and branch" do
39+
let(:tag) { "v1.0" }
40+
let(:branch) { "main" }
41+
it "raises error" do
42+
expect { git_proxy }.to raise_error(Bundler::Source::Git::AmbiguousGitReference)
43+
end
44+
end
45+
46+
context "with tag and ref" do
47+
let(:tag) { "v1.0" }
48+
let(:ref) { "HEAD" }
49+
it "raises error" do
50+
expect { git_proxy }.to raise_error(Bundler::Source::Git::AmbiguousGitReference)
51+
end
52+
end
53+
54+
context "with branch and ref" do
55+
let(:branch) { "main" }
56+
let(:ref) { "HEAD" }
57+
it "honors ref over branch" do
58+
expect(git_proxy.explicit_ref).to eq(ref)
59+
end
60+
end
61+
end
1262

1363
context "with configured credentials" do
1464
it "adds username and password to URI" do
1565
Bundler.settings.temporary(uri => "u:p") do
16-
allow(subject).to receive(:git_local).with("--version").and_return("git version 2.14.0")
17-
expect(subject).to receive(:capture).with([*base_clone_args, "--", "https://u:[email protected]/rubygems/rubygems.git", path.to_s], nil).and_return(["", "", clone_result])
66+
allow(git_proxy).to receive(:git_local).with("--version").and_return("git version 2.14.0")
67+
expect(git_proxy).to receive(:capture).with([*base_clone_args, "--", "https://u:[email protected]/rubygems/rubygems.git", path.to_s], nil).and_return(["", "", clone_result])
1868
subject.checkout
1969
end
2070
end
2171

2272
it "adds username and password to URI for host" do
2373
Bundler.settings.temporary("github.com" => "u:p") do
24-
allow(subject).to receive(:git_local).with("--version").and_return("git version 2.14.0")
25-
expect(subject).to receive(:capture).with([*base_clone_args, "--", "https://u:[email protected]/rubygems/rubygems.git", path.to_s], nil).and_return(["", "", clone_result])
74+
allow(git_proxy).to receive(:git_local).with("--version").and_return("git version 2.14.0")
75+
expect(git_proxy).to receive(:capture).with([*base_clone_args, "--", "https://u:[email protected]/rubygems/rubygems.git", path.to_s], nil).and_return(["", "", clone_result])
2676
subject.checkout
2777
end
2878
end
2979

3080
it "does not add username and password to mismatched URI" do
3181
Bundler.settings.temporary("https://u:[email protected]/rubygems/rubygems-mismatch.git" => "u:p") do
32-
allow(subject).to receive(:git_local).with("--version").and_return("git version 2.14.0")
33-
expect(subject).to receive(:capture).with([*base_clone_args, "--", uri, path.to_s], nil).and_return(["", "", clone_result])
82+
allow(git_proxy).to receive(:git_local).with("--version").and_return("git version 2.14.0")
83+
expect(git_proxy).to receive(:capture).with([*base_clone_args, "--", uri, path.to_s], nil).and_return(["", "", clone_result])
3484
subject.checkout
3585
end
3686
end
3787

3888
it "keeps original userinfo" do
3989
Bundler.settings.temporary("github.com" => "u:p") do
4090
original = "https://orig:[email protected]/rubygems/rubygems.git"
41-
subject = described_class.new(Pathname("path"), original, "HEAD")
42-
allow(subject).to receive(:git_local).with("--version").and_return("git version 2.14.0")
43-
expect(subject).to receive(:capture).with([*base_clone_args, "--", original, path.to_s], nil).and_return(["", "", clone_result])
44-
subject.checkout
91+
git_proxy = described_class.new(Pathname("path"), original, options)
92+
allow(git_proxy).to receive(:git_local).with("--version").and_return("git version 2.14.0")
93+
expect(git_proxy).to receive(:capture).with([*base_clone_args, "--", original, path.to_s], nil).and_return(["", "", clone_result])
94+
git_proxy.checkout
4595
end
4696
end
4797
end
4898

4999
describe "#version" do
50100
context "with a normal version number" do
51101
before do
52-
expect(subject).to receive(:git_local).with("--version").
102+
expect(git_proxy).to receive(:git_local).with("--version").
53103
and_return("git version 1.2.3")
54104
end
55105

56106
it "returns the git version number" do
57-
expect(subject.version).to eq("1.2.3")
107+
expect(git_proxy.version).to eq("1.2.3")
58108
end
59109

60110
it "does not raise an error when passed into Gem::Version.create" do
61-
expect { Gem::Version.create subject.version }.not_to raise_error
111+
expect { Gem::Version.create git_proxy.version }.not_to raise_error
62112
end
63113
end
64114

65115
context "with a OSX version number" do
66116
before do
67-
expect(subject).to receive(:git_local).with("--version").
117+
expect(git_proxy).to receive(:git_local).with("--version").
68118
and_return("git version 1.2.3 (Apple Git-BS)")
69119
end
70120

71121
it "strips out OSX specific additions in the version string" do
72-
expect(subject.version).to eq("1.2.3")
122+
expect(git_proxy.version).to eq("1.2.3")
73123
end
74124

75125
it "does not raise an error when passed into Gem::Version.create" do
76-
expect { Gem::Version.create subject.version }.not_to raise_error
126+
expect { Gem::Version.create git_proxy.version }.not_to raise_error
77127
end
78128
end
79129

80130
context "with a msysgit version number" do
81131
before do
82-
expect(subject).to receive(:git_local).with("--version").
132+
expect(git_proxy).to receive(:git_local).with("--version").
83133
and_return("git version 1.2.3.msysgit.0")
84134
end
85135

86136
it "strips out msysgit specific additions in the version string" do
87-
expect(subject.version).to eq("1.2.3")
137+
expect(git_proxy.version).to eq("1.2.3")
88138
end
89139

90140
it "does not raise an error when passed into Gem::Version.create" do
91-
expect { Gem::Version.create subject.version }.not_to raise_error
141+
expect { Gem::Version.create git_proxy.version }.not_to raise_error
92142
end
93143
end
94144
end
95145

96146
describe "#full_version" do
97147
context "with a normal version number" do
98148
before do
99-
expect(subject).to receive(:git_local).with("--version").
149+
expect(git_proxy).to receive(:git_local).with("--version").
100150
and_return("git version 1.2.3")
101151
end
102152

103153
it "returns the git version number" do
104-
expect(subject.full_version).to eq("1.2.3")
154+
expect(git_proxy.full_version).to eq("1.2.3")
105155
end
106156
end
107157

108158
context "with a OSX version number" do
109159
before do
110-
expect(subject).to receive(:git_local).with("--version").
160+
expect(git_proxy).to receive(:git_local).with("--version").
111161
and_return("git version 1.2.3 (Apple Git-BS)")
112162
end
113163

114164
it "does not strip out OSX specific additions in the version string" do
115-
expect(subject.full_version).to eq("1.2.3 (Apple Git-BS)")
165+
expect(git_proxy.full_version).to eq("1.2.3 (Apple Git-BS)")
116166
end
117167
end
118168

119169
context "with a msysgit version number" do
120170
before do
121-
expect(subject).to receive(:git_local).with("--version").
171+
expect(git_proxy).to receive(:git_local).with("--version").
122172
and_return("git version 1.2.3.msysgit.0")
123173
end
124174

125175
it "does not strip out msysgit specific additions in the version string" do
126-
expect(subject.full_version).to eq("1.2.3.msysgit.0")
176+
expect(git_proxy.full_version).to eq("1.2.3.msysgit.0")
127177
end
128178
end
129179
end

bundler/spec/commands/add_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
it "adds multiple version constraints when specified" do
6464
requirements = ["< 3.0", "> 1.0"]
6565
bundle "add 'foo' --version='#{requirements.join(", ")}'"
66-
expect(bundled_app_gemfile.read).to match(/gem "foo", #{Gem::Requirement.new(requirements).as_list.map(&:dump).join(', ')}/)
66+
expect(bundled_app_gemfile.read).to match(/gem "foo", #{Gem::Requirement.new(requirements).as_list.map(&:dump).join(", ")}/)
6767
expect(the_bundle).to include_gems "foo 2.0"
6868
end
6969
end

bundler/spec/commands/open_spec.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@
104104
input.puts "2"
105105
end
106106

107-
expect(out).to match(%r{bundler_editor #{default_bundle_path('gems', 'activerecord-2.3.2')}/CHANGELOG\.md\z})
107+
expect(out).to match(%r{bundler_editor #{default_bundle_path("gems", "activerecord-2.3.2")}/CHANGELOG\.md\z})
108108
end
109109

110110
it "opens deep subpath of the selected matching gem", :readline do
@@ -113,7 +113,7 @@
113113
input.puts "2"
114114
end
115115

116-
expect(out).to match(%r{bundler_editor #{default_bundle_path('gems', 'activerecord-2.3.2')}/lib/activerecord/version\.rb\z})
116+
expect(out).to match(%r{bundler_editor #{default_bundle_path("gems", "activerecord-2.3.2")}/lib/activerecord/version\.rb\z})
117117
end
118118

119119
it "select the gem from many match gems", :readline do
@@ -122,7 +122,7 @@
122122
input.puts "2"
123123
end
124124

125-
expect(out).to match(/bundler_editor #{default_bundle_path('gems', 'activerecord-2.3.2')}\z/)
125+
expect(out).to match(/bundler_editor #{default_bundle_path("gems", "activerecord-2.3.2")}\z/)
126126
end
127127

128128
it "allows selecting exit from many match gems", :readline do

bundler/spec/install/gemfile/gemspec_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@
8585
source "#{file_uri_for(gem_repo2)}"
8686
gemspec :path => '#{tmp.join("foo")}'
8787
G
88-
expect(err).to match(/There are no gemspecs at #{tmp.join('foo')}/)
88+
expect(err).to match(/There are no gemspecs at #{tmp.join("foo")}/)
8989
end
9090

9191
it "should raise if there are too many gemspecs available" do
@@ -97,7 +97,7 @@
9797
source "#{file_uri_for(gem_repo2)}"
9898
gemspec :path => '#{tmp.join("foo")}'
9999
G
100-
expect(err).to match(/There are multiple gemspecs at #{tmp.join('foo')}/)
100+
expect(err).to match(/There are multiple gemspecs at #{tmp.join("foo")}/)
101101
end
102102

103103
it "should pick a specific gemspec" do

bundler/spec/install/gemfile/git_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@
572572

573573
bundle %(config set local.rack #{lib_path("local-rack")})
574574
bundle :install, :raise_on_error => false
575-
expect(err).to match(/Cannot use local override for rack-0.8 because #{Regexp.escape(lib_path('local-rack').to_s)} does not exist/)
575+
expect(err).to match(/Cannot use local override for rack-0.8 because #{Regexp.escape(lib_path("local-rack").to_s)} does not exist/)
576576

577577
solution = "config unset local.rack"
578578
expect(err).to match(/Run `bundle #{solution}` to remove the local override/)
@@ -594,7 +594,7 @@
594594

595595
bundle %(config set local.rack #{lib_path("local-rack")})
596596
bundle :install, :raise_on_error => false
597-
expect(err).to match(/Cannot use local override for rack-0.8 at #{Regexp.escape(lib_path('local-rack').to_s)} because :branch is not specified in Gemfile/)
597+
expect(err).to match(/Cannot use local override for rack-0.8 at #{Regexp.escape(lib_path("local-rack").to_s)} because :branch is not specified in Gemfile/)
598598

599599
solution = "config unset local.rack"
600600
expect(err).to match(/Specify a branch or run `bundle #{solution}` to remove the local override/)

bundler/spec/runtime/setup_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ def clean_load_path(lp)
410410

411411
it "provides a useful exception when the git repo is not checked out yet" do
412412
run "1", :raise_on_error => false
413-
expect(err).to match(/the git source #{lib_path('rack-1.0.0')} is not yet checked out. Please run `bundle install`/i)
413+
expect(err).to match(/the git source #{lib_path("rack-1.0.0")} is not yet checked out. Please run `bundle install`/i)
414414
end
415415

416416
it "does not hit the git binary if the lockfile is available and up to date" do
@@ -497,7 +497,7 @@ def clean_load_path(lp)
497497

498498
FileUtils.rm_rf(lib_path("local-rack"))
499499
run "require 'rack'", :raise_on_error => false
500-
expect(err).to match(/Cannot use local override for rack-0.8 because #{Regexp.escape(lib_path('local-rack').to_s)} does not exist/)
500+
expect(err).to match(/Cannot use local override for rack-0.8 because #{Regexp.escape(lib_path("local-rack").to_s)} does not exist/)
501501
end
502502

503503
it "explodes if branch is not given on runtime" do

tool/bundler/dev_gems.rb.lock

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ PLATFORMS
3939
x64-mingw-ucrt
4040
x64-mingw32
4141
x86_64-darwin-20
42+
x86_64-darwin-21
43+
x86_64-darwin-22
4244
x86_64-linux
4345

4446
DEPENDENCIES

0 commit comments

Comments
 (0)