[前][次][番号順一覧][スレッド一覧]

ruby-changes:70866

From: David <ko1@a...>
Date: Sat, 15 Jan 2022 00:00:23 +0900 (JST)
Subject: [ruby-changes:70866] 7d42b442bb (master): [rubygems/rubygems] Support binstubs with `--enable-load-relative` prolog

https://git.ruby-lang.org/ruby.git/commit/?id=7d42b442bb

From 7d42b442bb42d8958daf978a0fe14b948f49609f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?David=20Rodr=C3=ADguez?= <deivid.rodriguez@r...>
Date: Mon, 21 Oct 2019 19:26:51 +0200
Subject: [rubygems/rubygems] Support binstubs with `--enable-load-relative`
 prolog

https://github.com/rubygems/rubygems/commit/32a5e9057a
---
 lib/rubygems/installer.rb           |  48 ++++++--
 test/rubygems/test_gem_installer.rb | 226 +++++++++++++++++++++++++++---------
 2 files changed, 208 insertions(+), 66 deletions(-)

diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb
index 0224b918984..4cda09f200b 100644
--- a/lib/rubygems/installer.rb
+++ b/lib/rubygems/installer.rb
@@ -220,7 +220,17 @@ class Gem::Installer https://github.com/ruby/ruby/blob/trunk/lib/rubygems/installer.rb#L220
     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 https://github.com/ruby/ruby/blob/trunk/lib/rubygems/installer.rb#L595
   #
 
   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 https://github.com/ruby/ruby/blob/trunk/lib/rubygems/installer.rb#L623
       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 https://github.com/ruby/ruby/blob/trunk/lib/rubygems/installer.rb#L987
   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
diff --git a/test/rubygems/test_gem_installer.rb b/test/rubygems/test_gem_installer.rb
index a40b8741071..c90fdab283a 100644
--- a/test/rubygems/test_gem_installer.rb
+++ b/test/rubygems/test_gem_installer.rb
@@ -18,11 +18,12 @@ class TestGemInstaller < Gem::InstallerTestCase https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_installer.rb#L18
   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 https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_installer.rb#L53
 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 https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_installer.rb#L726
   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 https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_installer.rb#L1808
   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 https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_installer.rb#L1850
   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
+    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"
 
-    assert_equal "#!#{Gem.ruby} -ws", shebang
+      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
+    end
+  end
+
+  def test_shebang_env_arguments_with_load_relative
+    load_relative 'yes' do
+      installer = setup_base_installer
 
-    assert_equal "#!#{Gem.ruby} -ws", shebang
+      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 https://github.com/ruby/ruby/blob/trunk/test/rubygems/test_gem_installer.rb#L1941
   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 'execut (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]