Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion lib/bundler/shared_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,12 @@ def set_path

def set_rubyopt
rubyopt = [ENV["RUBYOPT"]].compact
setup_require = "-r#{File.expand_path("setup", __dir__)}"
setup_path = File.expand_path("setup", __dir__)
# RUBYOPT is split on whitespace with no quoting mechanism, so an
# absolute path containing spaces would be torn apart. Fall back to
# requiring by feature name; set_rubylib puts our lib directory first
# on the child's load path.
setup_require = /\s/.match?(setup_path) ? "-rbundler/setup" : "-r#{setup_path}"
return if !rubyopt.empty? && rubyopt.first.include?(setup_require)
rubyopt.unshift setup_require
Bundler::SharedHelpers.set_env "RUBYOPT", rubyopt.join(" ")
Expand Down
28 changes: 28 additions & 0 deletions spec/bundler/shared_helpers_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,34 @@
it_behaves_like "ENV['RUBYOPT'] gets set correctly"
end

context "when bundler install path contains whitespace" do
let(:install_path) { "/opt/ruby with space/lib" }

before do
allow(File).to receive(:expand_path).and_return("#{install_path}/bundler/setup")
allow(Gem).to receive(:bin_path).and_return("#{install_path}/bundler/setup")
end

# RUBYOPT is split on whitespace with no quoting mechanism, so an
# absolute -r path containing spaces would make every child ruby fail
# to boot with "invalid switch in RUBYOPT".
it "requires bundler/setup by feature name instead of absolute path" do
subject.set_bundle_environment
expect(ENV["RUBYOPT"].split(" ")).to start_with("-rbundler/setup")
end

it "does not inject the space-containing path into RUBYOPT" do
subject.set_bundle_environment
expect(ENV["RUBYOPT"]).not_to include(install_path)
end

it "is idempotent" do
subject.set_bundle_environment
subject.set_bundle_environment
expect(ENV["RUBYOPT"].split(" ").grep(%r{\A-r.*bundler/setup\z}).length).to eq(1)
end
end

context "ENV['RUBYLIB'] does not exist" do
before { ENV.delete("RUBYLIB") }

Expand Down