24
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Ruby 2.6.1 に含まれる Bundler 1.17.2 に不具合があるという話

Posted at

不具合

先日知った以下の件。

この問題は gem update --system によって default gems としての Bundler を 1.17.3 にすれば回避可能でしょうか?

Ruby 2.6.1 は Ruby 2.5.3 と比較して、メモリ使用量が大きく(数百 MB 単位で)削減される(ケースがある)ことが確認できているため、簡単な Workaround で回避可能であれば個人的には積極的に利用したいところです。

比較

default gems としての Bundler のバージョンと、通常の gem としての Bundler のバージョンの組み合わせについて、実行に問題がなさそうなのかを確認。確認内容があっているのか、あまり自信がない。

Bundler 1.17.3 で作った Gemfile.lock

# default gems gem install ruby -rbundler/setup bundle exec ruby -rbundler/setup
A 1.17.2 None 指定バージョンを利用可能 default gems のものを利用してしまう
B 1.17.2 1.17.3 bundler の取り違い 指定バージョンを利用可能
C 1.17.3 None 指定バージョンを利用可能 指定バージョンを利用可能
D 1.17.3 2.0.1 指定バージョンを利用可能 指定バージョンを利用可能

Bundler 2.0.1 で作った Gemfile.lock

# default gems gem install ruby -rbundler/setup bundle exec ruby -rbundler/setup
E 1.17.2 None bundle install --deployment 不可 bundle install --deployment 不可
F 1.17.2 2.0.1 You must use Bundler 2 or greater with this lockfile. 指定バージョンを利用可能
G 1.17.3 2.0.1 指定バージョンを利用可能 指定バージョンを利用可能

補足(1): Bundler 1.17.3 で作った Gemfile.lock

$ bundle -v
Bundler version 1.17.3
$ bundle init
$ echo 'gem "csv", "3.0.3"' >> Gemfile
$ bundle install
$ cat Gemfile.lock
GEM
  remote: https://rubygems.org/
  specs:
    csv (3.0.3)

PLATFORMS
  ruby

DEPENDENCIES
  csv (= 3.0.3)

BUNDLED WITH
   1.17.3

A

$ docker run --rm -it -v(pwd):/mnt centos:7 bash
# yum install -y https://github.com/feedforce/ruby-rpm/releases/download/2.6.1/ruby-2.6.1-1.el7.centos.x86_64.rpm
# ruby -v
ruby 2.6.1p33 (2019-01-30 revision 66950) [x86_64-linux]
# gem -v
3.0.1
# bundle -v
Bundler version 1.17.2
# gem list bundler

*** LOCAL GEMS ***

bundler (default: 1.17.2)
# cp /mnt/Gemfile* .
# bundle install --deployment
# ruby -rbundler/setup -rcsv -e 'puts CSV::VERSION'
3.0.3
# bundle exec ruby -rbundler/setup -rcsv -e 'puts CSV::VERSION'
3.0.4

B

$ docker run --rm -it -v(pwd):/mnt centos:7 bash
# yum install -y https://github.com/feedforce/ruby-rpm/releases/download/2.6.1/ruby-2.6.1-1.el7.centos.x86_64.rpm
# gem install bundler -v 1.17.3 --no-document
# bundle -v
Bundler version 1.17.3
# gem list bundler

*** LOCAL GEMS ***

bundler (1.17.3, default: 1.17.2)
# cp /mnt/Gemfile* .
# bundle install --deployment
# ruby -rbundler/setup -rcsv -e 'puts CSV::VERSION'
Traceback (most recent call last):
        9: from /usr/lib64/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
        8: from /usr/lib64/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
        7: from /usr/lib64/ruby/2.6.0/bundler/setup.rb:10:in `<top (required)>'
        6: from /usr/lib64/ruby/gems/2.6.0/gems/bundler-1.17.3/lib/bundler.rb:107:in `setup'
        5: from /usr/lib64/ruby/gems/2.6.0/gems/bundler-1.17.3/lib/bundler/runtime.rb:26:in `setup'
        4: from /usr/lib64/ruby/gems/2.6.0/gems/bundler-1.17.3/lib/bundler/runtime.rb:26:in `map'
        3: from /usr/lib64/ruby/2.6.0/forwardable.rb:230:in `each'
        2: from /usr/lib64/ruby/2.6.0/forwardable.rb:230:in `each'
        1: from /usr/lib64/ruby/gems/2.6.0/gems/bundler-1.17.3/lib/bundler/runtime.rb:31:in `block in setup'
/usr/lib64/ruby/gems/2.6.0/gems/bundler-1.17.3/lib/bundler/runtime.rb:319:in `check_for_activated_spec!': You have already activated bundler 1.17.3, but your Gemfile requires bundler 1.17.2. Prepending `bundle exec` to your command may solve this. (Gem::LoadError)
# bundle exec ruby -rbundler/setup -e 'puts Bundler::VERSION'
1.17.3
# bundle exec ruby -rbundler/setup -rcsv -e 'puts CSV::VERSION'
3.0.3

C

$ docker run --rm -it -v(pwd):/mnt centos:7 bash
# yum install -y https://github.com/feedforce/ruby-rpm/releases/download/2.6.1/ruby-2.6.1-1.el7.centos.x86_64.rpm
# gem update --system
# bundle -v
Bundler version 1.17.3
# gem list bundler

*** LOCAL GEMS ***

bundler (default: 1.17.3)
# cp /mnt/Gemfile* .
# bundle install --deployment
# ruby -rbundler/setup -e 'puts Bundler::VERSION'
1.17.3
# ruby -rbundler/setup -rcsv -e 'puts CSV::VERSION'
3.0.3
# bundle exec ruby -rbundler/setup -e 'puts Bundler::VERSION'
1.17.3
# bundle exec ruby -rbundler/setup -rcsv -e 'puts CSV::VERSION'
3.0.3

D

$ docker run --rm -it -v(pwd):/mnt centos:7 bash
# yum install -y https://github.com/feedforce/ruby-rpm/releases/download/2.6.1/ruby-2.6.1-1.el7.centos.x86_64.rpm
# gem install bundler --no-document
# gem update --system
# gem -v
3.0.2
# bundle -v
Bundler version 2.0.1
# gem list bundler

*** LOCAL GEMS ***

bundler (2.0.1, default: 1.17.3)
# cp /mnt/Gemfile* .
# bundle install --deployment
# ruby -rbundler/setup -e 'puts Bundler::VERSION'
1.17.3
# ruby -rbundler/setup -rcsv -e 'puts CSV::VERSION'
3.0.3
# bundle exec ruby -rbundler/setup -e 'puts Bundler::VERSION'
1.17.3
# bundle exec ruby -rbundler/setup -rcsv -e 'puts CSV::VERSION'
3.0.3

補足: Bundler 2.0.1 で作った Gemfile.lock

$ bundle -v
Bundler version 2.0.1
$ bundle init
$ echo 'gem "csv", "3.0.3"' >> Gemfile
$ bundle install
$ cat Gemfile.lock
GEM
  remote: https://rubygems.org/
  specs:
    csv (3.0.3)

PLATFORMS
  ruby

DEPENDENCIES
  csv (= 3.0.3)

BUNDLED WITH
   2.0.1

E

$ docker run --rm -it -v(pwd):/mnt centos:7 bash
# yum install -y https://github.com/feedforce/ruby-rpm/releases/download/2.6.1/ruby-2.6.1-1.el7.centos.x86_64.rpm
# ruby -v
ruby 2.6.1p33 (2019-01-30 revision 66950) [x86_64-linux]
# gem -v
3.0.1
# bundle -v
Bundler version 1.17.2
# gem list bundler

*** LOCAL GEMS ***

bundler (default: 1.17.2)
# cp /mnt/Gemfile* .
# bundle install --deployment
Traceback (most recent call last):
        2: from /usr/bin/bundle:23:in `<main>'
        1: from /usr/lib64/ruby/2.6.0/rubygems.rb:302:in `activate_bin_path'
/usr/lib64/ruby/2.6.0/rubygems.rb:283:in `find_spec_for_exe': Could not find 'bundler' (2.0.1) required by your /Gemfile.lock. (Gem::GemNotFoundException)
To update to the latest version installed on your system, run `bundle update --bundler`.
To install the missing version, run `gem install bundler:2.0.1`

F

$ docker run --rm -it -v(pwd):/mnt centos:7 bash
# yum install -y https://github.com/feedforce/ruby-rpm/releases/download/2.6.1/ruby-2.6.1-1.el7.centos.x86_64.rpm
# gem install bundler -v 2.0.1 --no-document
# bundle -v
Bundler version 2.0.1
# gem list bundler

*** LOCAL GEMS ***

bundler (2.0.1, default: 1.17.2)
# cp /mnt/Gemfile* .
# bundle install --deployment
# ruby -rbundler/setup -e 'puts Bundler::VERSION'
You must use Bundler 2 or greater with this lockfile.
# ruby -rbundler/setup -rcsv -e 'puts CSV::VERSION'
You must use Bundler 2 or greater with this lockfile.
# bundle exec ruby -rbundler/setup -e 'puts Bundler::VERSION'
2.0.1
# bundle exec ruby -rbundler/setup -rcsv -e 'puts CSV::VERSION'
3.0.3

G

$ docker run --rm -it -v(pwd):/mnt centos:7 bash
# yum install -y https://github.com/feedforce/ruby-rpm/releases/download/2.6.1/ruby-2.6.1-1.el7.centos.x86_64.rpm
# gem install bundler --no-document
# gem update --system
# gem -v
3.0.2
# bundle -v
Bundler version 2.0.1
# gem list bundler

*** LOCAL GEMS ***

bundler (2.0.1, default: 1.17.3)
# cp /mnt/Gemfile* .
# bundle install --deployment
# ruby -rbundler/setup -e 'puts Bundler::VERSION'
2.0.1
# ruby -rbundler/setup -rcsv -e 'puts CSV::VERSION'
3.0.3
# bundle exec ruby -rbundler/setup -e 'puts Bundler::VERSION'
2.0.1
# bundle exec ruby -rbundler/setup -rcsv -e 'puts CSV::VERSION'
3.0.3

おまけ

gem install bundlergem update --system の実行順序によって、実行ファイル(ラッパー) bundle が conflict する様です。

bundler → rubygems

特に警告が出ることなく、また /usr/bin/bundle の内容が変わることはなかった。

# gem install bundler --no-document
...
# gem update --system
...

rubygems → bundler

gem update --system によって /usr/bin/bundle が更新され、 gem install bundler で上書きすると Ruby 同梱同等の内容に戻った。

# gem update --system
...
# gem install bundler --no-document
...
bundler's executable "bundle" conflicts with /usr/bin/bundle
Overwrite the executable? [yN]  y
...

RPM でインストールした /usr/bin/bundle

#!/usr/bin/ruby
#
# This file was generated by RubyGems.
#
# The application 'bundler' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'rubygems'

version = ">= 0.a"

str = ARGV.first
if str
  str = str.b[/\A_(.*)_\z/, 1]
  if str and Gem::Version.correct?(str)
    version = str
    ARGV.shift
  end
end

if Gem.respond_to?(:activate_bin_path)
load Gem.activate_bin_path('bundler', 'bundle', version)
else
gem "bundler", version
load Gem.bin_path("bundler", "bundle", version)
end

gem update --system で暗黙的に上書きされた /usr/bin/bundle

Bundler の exe/bundle とほぼ同等。違いは shebang のみ。

#!/usr/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

gem install bundler で上書きした /usr/bin/bundle

#!/usr/bin/ruby
#
# This file was generated by RubyGems.
#
# The application 'bundler' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'rubygems'

version = ">= 0.a"

str = ARGV.first
if str
  str = str.b[/\A_(.*)_\z/, 1]
  if str and Gem::Version.correct?(str)
    version = str
    ARGV.shift
  end
end

if Gem.respond_to?(:activate_bin_path)
load Gem.activate_bin_path('bundler', 'bundle', version)
else
gem "bundler", version
load Gem.bin_path("bundler", "bundle", version)
end

rbenv install 2.6.1 で作られた versions/2.6.1/bin/bundle

#!/home/koshigoe/.rbenv/versions/2.6.1/bin/ruby
#
# This file was generated by RubyGems.
#
# The application 'bundler' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'rubygems'

version = ">= 0.a"

str = ARGV.first
if str
  str = str.b[/\A_(.*)_\z/, 1]
  if str and Gem::Version.correct?(str)
    version = str
    ARGV.shift
  end
end

if Gem.respond_to?(:activate_bin_path)
load Gem.activate_bin_path('bundler', 'bundle', version)
else
gem "bundler", version
load Gem.bin_path("bundler", "bundle", version)
end
24
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?