Skip to content

Commit

Permalink
[rubygems/rubygems] Avoid duplicates -rbundler/setup in RUBYOPT with …
Browse files Browse the repository at this point in the history
…Ruby preview

When using a Ruby preview the require path of `bundler/setup` is
similar to `-r/opt/ruby3.3.0-preview2/lib/ruby/3.3.0+0/bundler/setup`.
The special character `+` in the string makes the Regexp fail,
leading to multiple addition of the same require statement each time
`set_rubyopt` is called (e.g. server reloading).
Escaping the characters in the string esure a correct match with all
the different Ruby versions.

rubygems/rubygems@dd43dfa709
  • Loading branch information
intrip authored and matzbot committed Oct 9, 2023
1 parent 0fdee13 commit f44cee9
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 11 deletions.
2 changes: 1 addition & 1 deletion lib/bundler/shared_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ def set_path
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
Expand Down
41 changes: 31 additions & 10 deletions spec/bundler/bundler/shared_helpers_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@
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

Expand Down Expand Up @@ -367,20 +367,41 @@
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"
end
context "ENV['RUBYOPT'] does not exist" do
before { ENV.delete("RUBYOPT") }

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

it_behaves_like "ENV['RUBYOPT'] gets set correctly"
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 and contains -rbundler/setup" do
before { ENV["RUBYOPT"] = "-rbundler/setup" }
context "when bundler install path contains special characters" do
let(:install_path) { "/opt/ruby3.3.0-preview2/lib/ruby/3.3.0+0" }

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

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
Expand Down

0 comments on commit f44cee9

Please sign in to comment.