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

https://github.com/rubygems/rubygems/commit/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
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
@ -585,7 +595,6 @@ class Gem::Installer
#
def shebang(bin_file_name)
ruby_name = 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 } || ""
@ -614,14 +623,12 @@ class Gem::Installer
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
@ -980,4 +987,29 @@ TEXT
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

View file

@ -18,11 +18,12 @@ class TestGemInstaller < Gem::InstallerTestCase
end
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}
#
# This file was generated by RubyGems.
@ -52,10 +53,11 @@ else
gem "a", version
load Gem.bin_path("a", "executable", version)
end
EOF
EOF
wrapper = installer.app_script_text 'executable'
assert_equal expected, wrapper
wrapper = installer.app_script_text 'executable'
assert_equal expected, wrapper
end
end
def test_check_executable_overwrite
@ -724,17 +726,19 @@ gem 'other', version
def test_generate_bin_uses_default_shebang
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
util_make_exec
installer.wrappers = true
util_make_exec
installer.generate_bin
installer.generate_bin
default_shebang = Gem.ruby
shebang_line = File.open("#{@gemhome}/bin/executable") {|f| f.readlines.first }
assert_match(/\A#!/, shebang_line)
assert_match(/#{default_shebang}/, shebang_line)
default_shebang = Gem.ruby
shebang_line = File.open("#{@gemhome}/bin/executable") {|f| f.readlines.first }
assert_match(/\A#!/, shebang_line)
assert_match(/#{default_shebang}/, shebang_line)
end
end
def test_generate_bin_with_dangling_symlink
@ -1804,13 +1808,15 @@ gem 'other', version
end
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
def test_process_options
@ -1844,42 +1850,80 @@ gem 'other', version
end
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
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'
assert_equal "#!#{Gem.ruby}", shebang
shebang = installer.shebang 'executable'
assert_equal "#!#{Gem.ruby}", shebang
end
end
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
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
def test_shebang_env_shebang
@ -1897,63 +1941,120 @@ gem 'other', version
end
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
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
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
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
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
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
def test_shebang_custom
@ -2283,4 +2384,13 @@ gem 'other', version
def mask
0100755
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