1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

[rubygems/rubygems] Support binstubs with --enable-load-relative prolog

32a5e9057a
This commit is contained in:
David Rodríguez 2019-10-21 19:26:51 +02:00 committed by git
parent 044b0ae8e0
commit 7d42b442bb
2 changed files with 208 additions and 66 deletions

View file

@ -220,7 +220,17 @@ class Gem::Installer
existing = nil existing = nil
File.open generated_bin, 'rb' do |io| 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 io.gets # blankline
# TODO detect a specially formatted comment instead of trying # TODO detect a specially formatted comment instead of trying
@ -585,7 +595,6 @@ class Gem::Installer
# #
def shebang(bin_file_name) def shebang(bin_file_name)
ruby_name = ruby_install_name if @env_shebang
path = File.join gem_dir, spec.bindir, bin_file_name path = File.join gem_dir, spec.bindir, bin_file_name
first_line = File.open(path, "rb") {|file| file.gets } || "" first_line = File.open(path, "rb") {|file| file.gets } || ""
@ -614,14 +623,12 @@ class Gem::Installer
end end
"#!#{which}" "#!#{which}"
elsif not ruby_name elsif @env_shebang
"#!#{Gem.ruby}#{opts}"
elsif opts
"#!/bin/sh\n'exec' #{ruby_name.dump} '-x' \"$0\" \"$@\"\n#{shebang}"
else
# Create a plain shebang line. # Create a plain shebang line.
@env_path ||= ENV_PATHS.find {|env_path| File.executable? env_path } @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
end end
@ -980,4 +987,29 @@ TEXT
def ruby_install_name def ruby_install_name
rb_config["ruby_install_name"] rb_config["ruby_install_name"]
end 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 end

View file

@ -18,11 +18,12 @@ class TestGemInstaller < Gem::InstallerTestCase
end end
def test_app_script_text def test_app_script_text
installer = setup_base_installer load_relative "no" do
installer = setup_base_installer
util_make_exec @spec, '' util_make_exec @spec, ''
expected = <<-EOF expected = <<-EOF
#!#{Gem.ruby} #!#{Gem.ruby}
# #
# This file was generated by RubyGems. # This file was generated by RubyGems.
@ -52,10 +53,11 @@ else
gem "a", version gem "a", version
load Gem.bin_path("a", "executable", version) load Gem.bin_path("a", "executable", version)
end end
EOF EOF
wrapper = installer.app_script_text 'executable' wrapper = installer.app_script_text 'executable'
assert_equal expected, wrapper assert_equal expected, wrapper
end
end end
def test_check_executable_overwrite def test_check_executable_overwrite
@ -724,17 +726,19 @@ gem 'other', version
def test_generate_bin_uses_default_shebang def test_generate_bin_uses_default_shebang
pend "Symlinks not supported or not enabled" unless symlink_supported? pend "Symlinks not supported or not enabled" unless symlink_supported?
installer = setup_base_installer load_relative 'no' do
installer = setup_base_installer
installer.wrappers = true installer.wrappers = true
util_make_exec util_make_exec
installer.generate_bin installer.generate_bin
default_shebang = Gem.ruby default_shebang = Gem.ruby
shebang_line = File.open("#{@gemhome}/bin/executable") {|f| f.readlines.first } shebang_line = File.open("#{@gemhome}/bin/executable") {|f| f.readlines.first }
assert_match(/\A#!/, shebang_line) assert_match(/\A#!/, shebang_line)
assert_match(/#{default_shebang}/, shebang_line) assert_match(/#{default_shebang}/, shebang_line)
end
end end
def test_generate_bin_with_dangling_symlink def test_generate_bin_with_dangling_symlink
@ -1804,13 +1808,15 @@ gem 'other', version
end end
def test_shebang def test_shebang
installer = setup_base_installer load_relative "no" do
installer = setup_base_installer
util_make_exec @spec, "#!/usr/bin/ruby" util_make_exec @spec, "#!/usr/bin/ruby"
shebang = installer.shebang 'executable' shebang = installer.shebang 'executable'
assert_equal "#!#{Gem.ruby}", shebang assert_equal "#!#{Gem.ruby}", shebang
end
end end
def test_process_options def test_process_options
@ -1844,42 +1850,80 @@ gem 'other', version
end end
def test_shebang_arguments def test_shebang_arguments
installer = setup_base_installer load_relative 'no' do
installer = setup_base_installer
util_make_exec @spec, "#!/usr/bin/ruby -ws" util_make_exec @spec, "#!/usr/bin/ruby -ws"
shebang = installer.shebang 'executable' shebang = installer.shebang 'executable'
assert_equal "#!#{Gem.ruby} -ws", shebang assert_equal "#!#{Gem.ruby} -ws", shebang
end
end
def test_shebang_arguments_with_load_relative
load_relative 'yes' do
installer = setup_base_installer
util_make_exec @spec, "#!/usr/bin/ruby -ws"
shebang = installer.shebang 'executable'
shebang_lines = shebang.split "\n"
assert_equal "#!/bin/sh", shebang_lines.shift
assert_includes shebang_lines, "#!#{Gem.ruby} -ws"
end
end end
def test_shebang_empty def test_shebang_empty
installer = setup_base_installer load_relative 'no' do
installer = setup_base_installer
util_make_exec @spec, '' util_make_exec @spec, ''
shebang = installer.shebang 'executable' shebang = installer.shebang 'executable'
assert_equal "#!#{Gem.ruby}", shebang assert_equal "#!#{Gem.ruby}", shebang
end
end end
def test_shebang_env def test_shebang_env
installer = setup_base_installer load_relative 'no' do
installer = setup_base_installer
util_make_exec @spec, "#!/usr/bin/env ruby" util_make_exec @spec, "#!/usr/bin/env ruby"
shebang = installer.shebang 'executable' shebang = installer.shebang 'executable'
assert_equal "#!#{Gem.ruby}", shebang assert_equal "#!#{Gem.ruby}", shebang
end
end end
def test_shebang_env_arguments def test_shebang_env_arguments
installer = setup_base_installer load_relative 'no' do
installer = setup_base_installer
util_make_exec @spec, "#!/usr/bin/env ruby -ws" util_make_exec @spec, "#!/usr/bin/env ruby -ws"
shebang = installer.shebang 'executable' shebang = installer.shebang 'executable'
assert_equal "#!#{Gem.ruby} -ws", shebang assert_equal "#!#{Gem.ruby} -ws", shebang
end
end
def test_shebang_env_arguments_with_load_relative
load_relative 'yes' do
installer = setup_base_installer
util_make_exec @spec, "#!/usr/bin/env ruby -ws"
shebang = installer.shebang 'executable'
shebang_lines = shebang.split "\n"
assert_equal "#!/bin/sh", shebang_lines.shift
assert_includes shebang_lines, "#!#{Gem.ruby} -ws"
end
end end
def test_shebang_env_shebang def test_shebang_env_shebang
@ -1897,63 +1941,120 @@ gem 'other', version
end end
def test_shebang_nested def test_shebang_nested
installer = setup_base_installer load_relative 'no' do
installer = setup_base_installer
util_make_exec @spec, "#!/opt/local/ruby/bin/ruby" util_make_exec @spec, "#!/opt/local/ruby/bin/ruby"
shebang = installer.shebang 'executable' shebang = installer.shebang 'executable'
assert_equal "#!#{Gem.ruby}", shebang assert_equal "#!#{Gem.ruby}", shebang
end
end end
def test_shebang_nested_arguments def test_shebang_nested_arguments
installer = setup_base_installer load_relative 'no' do
installer = setup_base_installer
util_make_exec @spec, "#!/opt/local/ruby/bin/ruby -ws" util_make_exec @spec, "#!/opt/local/ruby/bin/ruby -ws"
shebang = installer.shebang 'executable' shebang = installer.shebang 'executable'
assert_equal "#!#{Gem.ruby} -ws", shebang assert_equal "#!#{Gem.ruby} -ws", shebang
end
end
def test_shebang_nested_arguments_with_load_relative
load_relative 'yes' do
installer = setup_base_installer
util_make_exec @spec, "#!/opt/local/ruby/bin/ruby -ws"
shebang = installer.shebang 'executable'
shebang_lines = shebang.split "\n"
assert_equal "#!/bin/sh", shebang_lines.shift
assert_includes shebang_lines, "#!#{Gem.ruby} -ws"
end
end end
def test_shebang_version def test_shebang_version
installer = setup_base_installer load_relative 'no' do
installer = setup_base_installer
util_make_exec @spec, "#!/usr/bin/ruby18" util_make_exec @spec, "#!/usr/bin/ruby18"
shebang = installer.shebang 'executable' shebang = installer.shebang 'executable'
assert_equal "#!#{Gem.ruby}", shebang assert_equal "#!#{Gem.ruby}", shebang
end
end end
def test_shebang_version_arguments def test_shebang_version_arguments
installer = setup_base_installer load_relative 'no' do
installer = setup_base_installer
util_make_exec @spec, "#!/usr/bin/ruby18 -ws" util_make_exec @spec, "#!/usr/bin/ruby18 -ws"
shebang = installer.shebang 'executable' shebang = installer.shebang 'executable'
assert_equal "#!#{Gem.ruby} -ws", shebang assert_equal "#!#{Gem.ruby} -ws", shebang
end
end
def test_shebang_version_arguments_with_load_relative
load_relative 'yes' do
installer = setup_base_installer
util_make_exec @spec, "#!/usr/bin/ruby18 -ws"
shebang = installer.shebang 'executable'
shebang_lines = shebang.split "\n"
assert_equal "#!/bin/sh", shebang_lines.shift
assert_includes shebang_lines, "#!#{Gem.ruby} -ws"
end
end end
def test_shebang_version_env def test_shebang_version_env
installer = setup_base_installer load_relative 'no' do
installer = setup_base_installer
util_make_exec @spec, "#!/usr/bin/env ruby18" util_make_exec @spec, "#!/usr/bin/env ruby18"
shebang = installer.shebang 'executable' shebang = installer.shebang 'executable'
assert_equal "#!#{Gem.ruby}", shebang assert_equal "#!#{Gem.ruby}", shebang
end
end end
def test_shebang_version_env_arguments def test_shebang_version_env_arguments
installer = setup_base_installer load_relative 'no' do
installer = setup_base_installer
util_make_exec @spec, "#!/usr/bin/env ruby18 -ws" util_make_exec @spec, "#!/usr/bin/env ruby18 -ws"
shebang = installer.shebang 'executable' shebang = installer.shebang 'executable'
assert_equal "#!#{Gem.ruby} -ws", shebang assert_equal "#!#{Gem.ruby} -ws", shebang
end
end
def test_shebang_version_env_arguments_with_load_relative
load_relative 'yes' do
installer = setup_base_installer
util_make_exec @spec, "#!/usr/bin/env ruby18 -ws"
shebang = installer.shebang 'executable'
shebang_lines = shebang.split "\n"
assert_equal "#!/bin/sh", shebang_lines.shift
assert_includes shebang_lines, "#!#{Gem.ruby} -ws"
end
end end
def test_shebang_custom def test_shebang_custom
@ -2283,4 +2384,13 @@ gem 'other', version
def mask def mask
0100755 0100755
end end
def load_relative(value)
orig_LIBRUBY_RELATIVE = RbConfig::CONFIG['LIBRUBY_RELATIVE']
RbConfig::CONFIG['LIBRUBY_RELATIVE'] = value
yield
ensure
RbConfig::CONFIG['LIBRUBY_RELATIVE'] = orig_LIBRUBY_RELATIVE
end
end end