diff --git a/lib/bundler.rb b/lib/bundler.rb index 2958e64cee5..7e7fba22c79 100644 --- a/lib/bundler.rb +++ b/lib/bundler.rb @@ -304,11 +304,11 @@ def which(executable) if File.file?(executable) && File.executable?(executable) executable elsif path = ENV["PATH"] - executable_path = path.split(File::PATH_SEPARATOR).find do |p| - abs_path = File.join(p, executable) - File.file?(abs_path) && File.executable?(abs_path) + path.split(File::PATH_SEPARATOR).find do |path| + path = path[1..-2] if path[0] == '"' && path[-1] == '"' + executable_path = File.expand_path(executable, path) + return executable_path if File.file?(executable_path) && File.executable?(executable_path) end - executable_path && File.expand_path(executable, executable_path) end end diff --git a/spec/bundler/bundler_spec.rb b/spec/bundler/bundler_spec.rb index 84d2922f37d..2ad3704db08 100644 --- a/spec/bundler/bundler_spec.rb +++ b/spec/bundler/bundler_spec.rb @@ -103,4 +103,41 @@ end end end + + describe "#which" do + let(:executable) { "executable" } + let(:path) { %w(/a /b c ../d "/e") } + let(:expected) { "executable" } + + before do + ENV["PATH"] = path.join(File::PATH_SEPARATOR) + + allow(File).to receive(:file?).and_return(false) + allow(File).to receive(:executable?).and_return(false) + if expected + expect(File).to receive(:file?).with(expected).and_return(true) + expect(File).to receive(:executable?).with(expected).and_return(true) + end + end + + subject { described_class.which(executable) } + + shared_examples_for "it returns the correct executable" do + it "returns the expected file" do + expect(subject).to eq(expected) + end + end + + it_behaves_like "it returns the correct executable" + + context "when the executable in inside a quoted path" do + let(:expected) { "/e/executable" } + it_behaves_like "it returns the correct executable" + end + + context "when the executable is not found" do + let(:expected) { nil } + it_behaves_like "it returns the correct executable" + end + end end