Issue #13997 has been updated by hone (Terence Lee).


hsbt (Hiroshi SHIBATA) wrote:
> Thanks, Terence.
> 
> ```/tmp/bundler/lib/ruby/gems/2.5.0/gems/bundler-1.15.4/exe/bundle``` is not default gem environment on Ruby 2.5.0preview1.
> 
> Can you show reproduce instructions for this issue?

```/tmp/bundler/``` is just the directory where I unpacked Ruby 2.5.0.

I investigated some more and it looks like Benoit is partially right. Thanks for pointing me in the right direction! On Heroku we use ```--enable-load-relative``` configure option for compiling ruby, which adds the shell portion to the ```bundle``` file.

Without ```--enable-load-relative```, the binstub looks like this:

```ruby
#!/tmp/rubytest2/bin/ruby
# frozen_string_literal: true

# Exit cleanly from an early interrupt
Signal.trap("INT") do
  Bundler.ui.debug("\n#{caller.join("\n")}") if defined?(Bundler)
  exit 1
end

require "bundler"
# Check if an older version of bundler is installed
$LOAD_PATH.each do |path|
  next unless path =~ %r{/bundler-0\.(\d+)} && $1.to_i < 9
  err = String.new
  err << "Looks like you have a version of bundler that's older than 0.9.\n"
  err << "Please remove your old versions.\n"
  err << "An easy way to do this is by running `gem cleanup bundler`."
  abort(err)
end

require "bundler/friendly_errors"
Bundler.with_friendly_errors do
  require "bundler/cli"

  # Allow any command to use --help flag to show help for that command
  help_flags = %w(--help -h)
  help_flag_used = ARGV.any? {|a| help_flags.include? a }
  args = help_flag_used ? Bundler::CLI.reformatted_help_args(ARGV) : ARGV

  Bundler::CLI.start(args, :debug => true)
end

```

With `--enable-load-relative` set:

```ruby
#!/bin/sh
# -*- ruby -*-
bindir="${0%/*}"
exec "$bindir/ruby" -x "$0" "$@"
#!/usr/bin/env ruby
# frozen_string_literal: true

# Exit cleanly from an early interrupt
Signal.trap("INT") do
  Bundler.ui.debug("\n#{caller.join("\n")}") if defined?(Bundler)
  exit 1
end

require "bundler"
# Check if an older version of bundler is installed
$LOAD_PATH.each do |path|
  next unless path =~ %r{/bundler-0\.(\d+)} && $1.to_i < 9
  err = String.new
  err << "Looks like you have a version of bundler that's older than 0.9.\n"
  err << "Please remove your old versions.\n"
  err << "An easy way to do this is by running `gem cleanup bundler`."
  abort(err)
end

require "bundler/friendly_errors"
Bundler.with_friendly_errors do
  require "bundler/cli"

  # Allow any command to use --help flag to show help for that command
  help_flags = %w(--help -h)
  help_flag_used = ARGV.any? {|a| help_flags.include? a }
  args = help_flag_used ? Bundler::CLI.reformatted_help_args(ARGV) : ARGV

  Bundler::CLI.start(args, :debug => true)
end
```

As for steps to reproduce:

Install Ruby 2.5.0-preview1

* ```./configure --enable-load-relative --prefix /tmp/rubytest```
* ```make```
* ```make install```

Setup ```$PATH```

Ensure rubygems binstubs is on the ```$PATH``` that precedes ruby's binstubs. We want rubygems binaries to win over ruby's.
For example, assuming the rubygems binstubs live at ```/home/hone/.gems/bin```, ```$PATH``` should be setup like this:

```
export PATH=/home/hone/.gems/bin:/tmp/rubytest/bin:$PATH
```

Run the `bundle` command

```
$ bundle -v
Traceback (most recent call last):
        1: from /home/hone/.gems/bin/bundle:22:in `<main>'
/home/hone/.gems/bin/bundle:22:in `load': /tmp/rubytest/lib/ruby/gems/2.5.0/gems/bundler-1.15.4/exe/bundle:4: syntax error, unexpected tSTRING_BEG, expecting keyword_do or '{' or '(' (SyntaxError)
exec "$bindir/ruby" -x "$0" "$@"
                       ^
/tmp/rubytest/lib/ruby/gems/2.5.0/gems/bundler-1.15.4/exe/bundle:9: syntax error, unexpected keyword_do_block, expecting end-of-input
Signal.trap("INT") do
```

----------------------------------------
Bug #13997: Bundler gem binstub broken
https://bugs.ruby-lang.org/issues/13997#change-67170

* Author: hone (Terence Lee)
* Status: Feedback
* Priority: Normal
* Assignee: hsbt (Hiroshi SHIBATA)
* Target version: 2.5
* ruby -v: ruby 2.5.0preview1 (2017-10-10 trunk 60153) [x86_64-linux]
* Backport: 
----------------------------------------
Hi,

In Ruby 2.5.0-preview1, I'm seeing the following error if the Rubygems binstub PATH precedes the binstubs from ruby and the Bundler version installed is <= 1.15.4 (what ruby vendors).

~~~
/home/hone/.rvm/gems/ruby-2.4.1@global/bin/bundle:22:in `load': /tmp/bundler/lib/ruby/gems/2.5.0/gems/bundler-1.15.4/exe/bundle:4: syntax error, unexpected tSTRING_BEG, expecting keyword_do or '{' or '(' (SyntaxError)
exec "$bindir/ruby" -x "$0" "$@"
                       ^
/tmp/bundler/lib/ruby/gems/2.5.0/gems/bundler-1.15.4/exe/bundle:9: syntax error, unexpected keyword_do_block, expecting end-of-input
Signal.trap("INT") do
~~~

The reason for this is because the generated bundler binstub by rubygems runs code like this:

~~~
load Gem.bin_path('bundler', 'bundle', '>= 0.a')
~~~

The problem is that the binstub from the vendored bundler in ruby is not pure ruby:

~~~
#!/bin/sh
# -*- ruby -*-
bindir="${0%/*}"
exec "$bindir/ruby" -x "$0" "$@"
~~~

The top of this file is shell and not ruby. Kernel#load chokes on this.

Thanks,
Terence



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>