diff --git a/lib/bundler/shared_helpers.rb b/lib/bundler/shared_helpers.rb index 165982ad0a..5196243949 100644 --- a/lib/bundler/shared_helpers.rb +++ b/lib/bundler/shared_helpers.rb @@ -312,7 +312,7 @@ module Bundler def set_rubyopt rubyopt = [ENV["RUBYOPT"]].compact setup_require = "-r#{File.expand_path("setup", __dir__)}" - return if !rubyopt.empty? && rubyopt.first =~ /#{setup_require}/ + return if !rubyopt.empty? && rubyopt.first =~ /#{Regexp.escape(setup_require)}/ rubyopt.unshift setup_require Bundler::SharedHelpers.set_env "RUBYOPT", rubyopt.join(" ") end diff --git a/spec/bundler/bundler/shared_helpers_spec.rb b/spec/bundler/bundler/shared_helpers_spec.rb index 3c6536c4eb..917f22c10d 100644 --- a/spec/bundler/bundler/shared_helpers_spec.rb +++ b/spec/bundler/bundler/shared_helpers_spec.rb @@ -242,7 +242,7 @@ RSpec.describe Bundler::SharedHelpers do shared_examples_for "ENV['RUBYOPT'] gets set correctly" do it "ensures -rbundler/setup is at the beginning of ENV['RUBYOPT']" do subject.set_bundle_environment - expect(ENV["RUBYOPT"].split(" ")).to start_with("-r#{source_lib_dir}/bundler/setup") + expect(ENV["RUBYOPT"].split(" ")).to start_with("-r#{install_path}/bundler/setup") end end @@ -367,20 +367,41 @@ RSpec.describe Bundler::SharedHelpers do end end - context "ENV['RUBYOPT'] does not exist" do - before { ENV.delete("RUBYOPT") } + context "when bundler install path is standard" do + let(:install_path) { source_lib_dir } - it_behaves_like "ENV['RUBYOPT'] gets set correctly" + context "ENV['RUBYOPT'] does not exist" do + before { ENV.delete("RUBYOPT") } + + it_behaves_like "ENV['RUBYOPT'] gets set correctly" + end + + context "ENV['RUBYOPT'] exists without -rbundler/setup" do + before { ENV["RUBYOPT"] = "-I/some_app_path/lib" } + + it_behaves_like "ENV['RUBYOPT'] gets set correctly" + end + + context "ENV['RUBYOPT'] exists and contains -rbundler/setup" do + before { ENV["RUBYOPT"] = "-rbundler/setup" } + + it_behaves_like "ENV['RUBYOPT'] gets set correctly" + end end - context "ENV['RUBYOPT'] exists without -rbundler/setup" do - before { ENV["RUBYOPT"] = "-I/some_app_path/lib" } + context "when bundler install path contains special characters" do + let(:install_path) { "/opt/ruby3.3.0-preview2/lib/ruby/3.3.0+0" } - it_behaves_like "ENV['RUBYOPT'] gets set correctly" - end + before do + ENV["RUBYOPT"] = "-r#{install_path}/bundler/setup" + 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 - context "ENV['RUBYOPT'] exists and contains -rbundler/setup" do - before { ENV["RUBYOPT"] = "-rbundler/setup" } + it "ensures -rbundler/setup is not duplicated" do + subject.set_bundle_environment + expect(ENV["RUBYOPT"].split(" ").grep(%r{-r.*/bundler/setup}).length).to eq(1) + end it_behaves_like "ENV['RUBYOPT'] gets set correctly" end