Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support --enable-load-relative inside binstubs #2929

Merged
merged 4 commits into from Jan 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
63 changes: 51 additions & 12 deletions lib/rubygems/installer.rb
Expand Up @@ -201,8 +201,8 @@ def initialize(package, options={})
#
# If +@force+ is set +filename+ is overwritten.
#
# If +filename+ exists and is a RubyGems wrapper for different gem the user
# is consulted.
# If +filename+ exists and it is a RubyGems wrapper for a different gem, then
# the user is consulted.
#
# If +filename+ exists and +@bin_dir+ is Gem.default_bindir (/usr/local) the
# user is consulted.
Expand All @@ -220,7 +220,17 @@ def check_executable_overwrite(filename) # :nodoc:
existing = nil

File.open generated_bin, 'rb' do |io|
next unless io.gets =~ /^#!/ # shebang
line = io.gets
shebang = /^#!.*ruby/

if load_relative_enabled?
until line.nil? || line =~ shebang do
line = io.gets
end
end

next unless line =~ shebang

io.gets # blankline

# TODO detect a specially formatted comment instead of trying
Expand Down Expand Up @@ -585,7 +595,6 @@ def generate_bin_symlink(filename, bindir)
#

def shebang(bin_file_name)
ruby_name = RbConfig::CONFIG['ruby_install_name'] if @env_shebang
path = File.join gem_dir, spec.bindir, bin_file_name
first_line = File.open(path, "rb") {|file| file.gets } || ""

Expand All @@ -598,7 +607,7 @@ def shebang(bin_file_name)

if which = Gem.configuration[:custom_shebang]
# replace bin_file_name with "ruby" to avoid endless loops
which = which.gsub(/ #{bin_file_name}$/," #{RbConfig::CONFIG['ruby_install_name']}")
which = which.gsub(/ #{bin_file_name}$/," #{ruby_install_name}")

which = which.gsub(/\$(\w+)/) do
case $1
Expand All @@ -614,14 +623,12 @@ def shebang(bin_file_name)
end

"#!#{which}"
elsif not ruby_name
"#!#{Gem.ruby}#{opts}"
elsif opts
"#!/bin/sh\n'exec' #{ruby_name.dump} '-x' \"$0\" \"$@\"\n#{shebang}"
else
elsif @env_shebang
# Create a plain shebang line.
@env_path ||= ENV_PATHS.find {|env_path| File.executable? env_path }
"#!#{@env_path} #{ruby_name}"
"#!#{@env_path} #{ruby_install_name}"
else
"#{bash_prolog_script}#!#{Gem.ruby}#{opts}"
end
end

Expand Down Expand Up @@ -805,7 +812,6 @@ def explicit_version_requirement(name)
# return the stub script text used to launch the true Ruby script

def windows_stub_script(bindir, bin_file_name)
rb_config = RbConfig::CONFIG
rb_topdir = RbConfig::TOPDIR || File.dirname(rb_config["bindir"])

# get ruby executable file name from RbConfig
Expand Down Expand Up @@ -973,4 +979,37 @@ def build_args
Gem::Command.build_args
end
end

def rb_config
RbConfig::CONFIG
end

def ruby_install_name
rb_config["ruby_install_name"]
end

def load_relative_enabled?
rb_config["LIBRUBY_RELATIVE"] == 'yes'
end

def bash_prolog_script
if load_relative_enabled?
script = +<<~EOS
bindir="${0%/*}"
EOS

script << %Q(exec "$bindir/#{ruby_install_name}" "-x" "$0" "$@"\n)

<<~EOS
#!/bin/sh
# -*- ruby -*-
_=_\\
=begin
#{script.chomp}
=end
EOS
else
""
end
end
end
2 changes: 2 additions & 0 deletions test/rubygems/test_gem.rb
Expand Up @@ -2022,6 +2022,8 @@ def test_default_source_date_epoch_doesnt_change
ENV['SOURCE_DATE_EPOCH'] = old_epoch
end

private

def ruby_install_name(name)
with_clean_path_to_ruby do
orig_RUBY_INSTALL_NAME = RbConfig::CONFIG['ruby_install_name']
Expand Down