diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ad68792f..284ff1da 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -44,6 +44,9 @@ jobs: run: ruby-install --prefix ~/build_prefix/${{ matrix.ruby }} --no-install-deps -j4 ${{ matrix.ruby }} -- --enable-shared --enable-rpath --enable-load-relative --disable-install-doc env: CPPFLAGS: "-DENABLE_PATH_CHECK=0" # https://github.com/actions/virtual-environments/issues/267 + - name: Fix the RubyGems line when using load-relative + run: ~/build_prefix/${{ matrix.ruby }}/bin/ruby --disable-gems fix-rubygems-line.rb + if: startsWith(matrix.ruby, 'ruby-') - name: Create archive run: tar czf ${{ matrix.ruby }}-${{ matrix.os }}.tar.gz -C ~/build_prefix ${{ matrix.ruby }} - name: Install Bundler if needed diff --git a/fix-rubygems-line.rb b/fix-rubygems-line.rb new file mode 100644 index 00000000..f4d69c42 --- /dev/null +++ b/fix-rubygems-line.rb @@ -0,0 +1,39 @@ +require 'rbconfig' + +bindir = RbConfig::CONFIG["bindir"] + +FIRST_LINE = "#!/bin/sh\n" +RUBY_SHEBANG = %r{^#!/usr/bin/env ruby$} +RUBYGEMS_LINE = /This file was generated by RubyGems/ + +Dir.glob("#{bindir}/*") do |file| + exe = "bin/#{File.basename(file)}" + + if File.binread(file, FIRST_LINE.bytesize) == FIRST_LINE + puts "\nFound load-relative prolog in #{exe}" + contents = File.binread(file) + rubygems_line = contents.lines.index { |line| RUBYGEMS_LINE =~ line } + + if !rubygems_line + puts "No RubyGems line in #{exe}, skipping it" + elsif rubygems_line == 2 + # RubyGems expects RUBYGEMS_LINE to match the 3rd line + # https://github.com/rubygems/rubygems/blob/6d7fe84753/lib/rubygems/installer.rb#L220 + # Otherwise, it will consider the executable to be conflicting and ask whether to override, + # and that results in an error when STDIN is not interactive + else + puts "The RubyGems line in #{exe} is not the 3rd line (but line #{rubygems_line+1}), fixing it" + + index = contents =~ RUBY_SHEBANG + raise "Could not find ruby shebang in:\n#{contents}" unless index + contents = contents[index..-1] + + rubygems_line = contents.lines.index { |line| RUBYGEMS_LINE =~ line } + unless rubygems_line == 2 + raise "The RubyGems line is still not 3rd in #{exe}:\n#{contents}" + end + + File.binwrite(file, contents) + end + end +end