summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThe Bundler Bot <bot@bundler.io>2018-03-15 22:11:04 +0000
committerColby Swandale <me@colby.fyi>2018-04-20 10:27:32 +1000
commitc47fc5d568eabf92c6e25e86c9fe964003dd1c5b (patch)
treedd85e210bab8eaa0e910cf3acc653b3bcee9a1fe
parent5d69c54e088dbcd15b45148135673cbadbb23e16 (diff)
downloadbundler-c47fc5d568eabf92c6e25e86c9fe964003dd1c5b.tar.gz
Auto merge of #6337 - bundler:segiddins/fail-gracefully-when-resetting-to-rev-fails, r=colby-swandale
[GitProxy] Fail gracefully when resetting to the given revision fails ### What was the end-user problem that led to this PR? See https://github.com/bundler/bundler/issues/6324 for context. The problem was when a git gem referenced a branch, and you tried to install on a machine without the revision in the lockfile cached, Bundler would print the following error: ``` Git error: command `git reset --hard cb70aded58b9215a495f0509e49daef930eec478` in directory /home/deivid/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/bundler/gems/decidim-cb70aded58b9 has failed. If this error persists you could try removing the cache directory '/home/deivid/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/cache/bundler/git/decidim-9495d3039168996748af12c0fdb04debdea10392' ``` The problem was that removing the cache directory doesn't help. ### What was your diagnosis of the problem? My diagnosis was we needed to print a `RevisionNotFound` error when that `git reset --hard` failed. ### What is your fix for the problem, implemented in this PR? My fix rescues git command failures resulting from that `git reset --hard` and re-raises a more appropriate error message: ``` Revision cb70aded58b9215a495f0509e49daef930eec478 does not exist in the repository https://github.com/decidim/decidim. Maybe you misspelled it? ``` ### Why did you choose this fix out of the possible options? I chose this fix because it didn't involve bubbling information up from the git proxy to the definition. Ideally we'd re-rescue this error somewhere and suggest a `bundle update --source`, but that can be done in a separate PR. (cherry picked from commit 21c262a36da1d1b4bfb71acf4de31edc94d796e8)
-rw-r--r--lib/bundler/source/git/git_proxy.rb7
-rw-r--r--spec/bundler/source/git/git_proxy_spec.rb26
2 files changed, 31 insertions, 2 deletions
diff --git a/lib/bundler/source/git/git_proxy.rb b/lib/bundler/source/git/git_proxy.rb
index c56dda66ea..cd964f7e56 100644
--- a/lib/bundler/source/git/git_proxy.rb
+++ b/lib/bundler/source/git/git_proxy.rb
@@ -131,7 +131,12 @@ module Bundler
# method 2
SharedHelpers.chdir(destination) do
git_retry %(fetch --force --quiet --tags "#{path}")
- git "reset --hard #{@revision}"
+
+ begin
+ git "reset --hard #{@revision}"
+ rescue GitCommandError
+ raise MissingGitRevisionError.new(@revision, URICredentialsFilter.credential_filtered_uri(uri))
+ end
if submodules
git_retry "submodule update --init --recursive"
diff --git a/spec/bundler/source/git/git_proxy_spec.rb b/spec/bundler/source/git/git_proxy_spec.rb
index d282a449a5..3a29c97461 100644
--- a/spec/bundler/source/git/git_proxy_spec.rb
+++ b/spec/bundler/source/git/git_proxy_spec.rb
@@ -1,8 +1,12 @@
# frozen_string_literal: true
RSpec.describe Bundler::Source::Git::GitProxy do
+ let(:path) { Pathname("path") }
let(:uri) { "https://github.com/bundler/bundler.git" }
- subject { described_class.new(Pathname("path"), uri, "HEAD") }
+ let(:ref) { "HEAD" }
+ let(:revision) { nil }
+ let(:git_source) { nil }
+ subject { described_class.new(path, uri, ref, revision, git_source) }
context "with configured credentials" do
it "adds username and password to URI" do
@@ -113,4 +117,24 @@ RSpec.describe Bundler::Source::Git::GitProxy do
end
end
end
+
+ describe "#copy_to" do
+ let(:destination) { tmpdir("copy_to_path") }
+ let(:submodules) { false }
+
+ context "when given a SHA as a revision" do
+ let(:revision) { "abcd" * 10 }
+
+ it "fails gracefully when resetting to the revision fails" do
+ expect(subject).to receive(:git_retry).with(start_with("clone ")) { destination.mkpath }
+ expect(subject).to receive(:git_retry).with(start_with("fetch "))
+ expect(subject).to receive(:git).with("reset --hard #{revision}").and_raise(Bundler::Source::Git::GitCommandError, "command")
+ expect(subject).not_to receive(:git)
+
+ expect { subject.copy_to(destination, submodules) }.
+ to raise_error(Bundler::Source::Git::MissingGitRevisionError,
+ "Revision #{revision} does not exist in the repository #{uri}. Maybe you misspelled it?")
+ end
+ end
+ end
end