RubyGemsのインストールにBundlerを使う

JekyllはRubyで書かれているためRubyGemsというRuby に特化した apt-get と同じようなパッケージングシステムが使われています。 RubyでもNode.jsでも、今の流れとして、これらのライブラリーはプロジェクトごとにインストールするようになっていると感じます。 たくさんのライブラリーを使うとプロジェクト間のバージョンの違いによる問題が出てくることがあるからなんですね。 今回はBundlerでRubyGemsをインストールしてみました。

環境

  • OS X El Capitan バージョン 10.11.3
  • Ruby バージョン 2.0.0p645
  • RubyGems バージョン 2.5.1
  • Bundler バージョン 1.11.2

Bundler?

Bundler provides a consistent environment for Ruby projects by tracking and installing the exact gems and versions that are needed.

Bundler is an exit from dependency hell, and ensures that the gems you need are present in development, staging, and production. Starting work on a project is as simple as bundle install.

Bundler: The best way to manage a Ruby application's gems

環境変数

gem コマンドの設定

  • GEM_HOME Gem のホームディレクトリ
  • GEM_PATH Gem のサーチパス
  • $HOME/.gemrc

環境変数 GEM_HOME, GEM_PATH を設定する事によって Gem コマンドの動作を変更することができます。 また、ホームディレクトリに .gemrc という YAML フォーマットで書かれたファイルを置くことでも 動作を変更することができます。

例:

---
:backtrace: false
:benchmark: false
:bulk_threshold: 1000
:sources:
- http://gems.rubyforge.org
:update_sources: true
:verbose: true
gemhome: /home/hoge/.gems
gempath:
- /usr/local/lib/ruby/gems/1.9
gem: --no-rdoc --no-ri

library rubygems (Ruby 2.1.0)

Gemのインストールの時にsudoしなくてもいいようにGEM_HOMEは設定しておきます。 自分のMacにインストールしたRubyは、$HOME/.gemディレクトリーがすでにありましたので、これをGEM_HOMEにしてみます。 (自分はRubyでバリバリ書いていこうと思っていませんので、最新のバージョンじゃなくてもいいのでこれを使っています) それから$HOME/.gem/binPATHに追加しておきます。

# ~/.bashrc
export GEM_HOME=$HOME/.gem
export PATH=$GEM_HOME/bin:$PATH

環境変数を設定する前と設定した後を確認してみます。

設定する前

$ gem environment
RubyGems Environment:
  - RUBYGEMS VERSION: 2.5.1
  - RUBY VERSION: 2.0.0 (2015-04-13 patchlevel 645) [universal.x86_64-darwin15]
  - INSTALLATION DIRECTORY: /Library/Ruby/Gems/2.0.0
  - USER INSTALLATION DIRECTORY: /Users/user/.gem/ruby/2.0.0
  - RUBY EXECUTABLE: /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby
  - EXECUTABLE DIRECTORY: /usr/bin
  - SPEC CACHE DIRECTORY: /Users/user/.gem/specs
  - SYSTEM CONFIGURATION DIRECTORY: /Library/Ruby/Site
  - RUBYGEMS PLATFORMS:
   - ruby
   - universal-darwin-15
  - GEM PATHS:
    - /Library/Ruby/Gems/2.0.0
    - /Users/user/.gem/ruby/2.0.0
    - /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/gems/2.0.0
  - GEM CONFIGURATION:
    - :update_sources => true
    - :verbose => true
    - :backtrace => false
    - :bulk_threshold => 1000
  - REMOTE SOURCES:
    - https://rubygems.org/
  - SHELL PATH:
    - /Users/user/.nodebrew/current/bin
    - /usr/local/bin
    - /usr/bin
    - /bin
    - /usr/sbin
    - /sbin
    - ./node_modules/.bin

設定した後

INSTALLATION DIRECTORYUSER INSTALLATION DIRECTORYが一致しないことが気になる・・ Rubyのバージョンが考慮されて、ruby/2.0.0までがGEM_HOMEになるのか・・ GEM PATHS/Users/user/.gem/Users/user/.gem/ruby/2.0.0があるのが気になる・・ そうすると、PATH/Users/user/.gem/ruby/2.0.0/binになるんだろう。

$ gem environment
RubyGems Environment:
  - RUBYGEMS VERSION: 2.5.1
  - RUBY VERSION: 2.0.0 (2015-04-13 patchlevel 645) [universal.x86_64-darwin15]
  - INSTALLATION DIRECTORY: /Users/user/.gem
  - USER INSTALLATION DIRECTORY: /Users/user/.gem/ruby/2.0.0
  - RUBY EXECUTABLE: /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby
  - EXECUTABLE DIRECTORY: /Users/user/.gem/bin
  - SPEC CACHE DIRECTORY: /Users/user/.gem/specs
  - SYSTEM CONFIGURATION DIRECTORY: /Library/Ruby/Site
  - RUBYGEMS PLATFORMS:
    - ruby
    - universal-darwin-15
  - GEM PATHS:
     - /Users/user/.gem
     - /Users/user/.gem/ruby/2.0.0
     - /Library/Ruby/Gems/2.0.0
     - /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/gems/2.0.0
  - GEM CONFIGURATION:
     - :update_sources => true
     - :verbose => true
     - :backtrace => false
     - :bulk_threshold => 1000
  - REMOTE SOURCES:
     - https://rubygems.org/
  - SHELL PATH:
     - /Users/user/.gem/bin
     - /Users/user/.nodebrew/current/bin
     - /usr/local/bin
     - /usr/bin
     - /bin
     - /usr/sbin
     - /sbin
     - ./node_modules/.bin

改めて設定

# ~/.bashrc
export GEM_HOME=$HOME/.gem/ruby/2.0.0
export PATH=$GEM_HOME/bin:$PATH

INSTALLATION DIRECTORYUSER INSTALLATION DIRECTORYが一致しました。 EXECUTABLE DIRECTORYもそれらしくユーザーの場所になりました。 GEM PATHSもユーザーのものとシステムのものがあって良さそうです。

$ gem environment
RubyGems Environment:
  - RUBYGEMS VERSION: 2.5.1
  - RUBY VERSION: 2.0.0 (2015-04-13 patchlevel 645) [universal.x86_64-darwin15]
  - INSTALLATION DIRECTORY: /Users/user/.gem/ruby/2.0.0
  - USER INSTALLATION DIRECTORY: /Users/user/.gem/ruby/2.0.0
  - RUBY EXECUTABLE: /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby
  - EXECUTABLE DIRECTORY: /Users/user/.gem/ruby/2.0.0/bin
  - SPEC CACHE DIRECTORY: /Users/user/.gem/specs
  - SYSTEM CONFIGURATION DIRECTORY: /Library/Ruby/Site
  - RUBYGEMS PLATFORMS:
    - ruby
    - universal-darwin-15
  - GEM PATHS:
     - /Users/user/.gem/ruby/2.0.0
     - /Library/Ruby/Gems/2.0.0
     - /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/gems/2.0.0
  - GEM CONFIGURATION:
     - :update_sources => true
     - :verbose => true
     - :backtrace => false
     - :bulk_threshold => 1000
  - REMOTE SOURCES:
     - https://rubygems.org/
  - SHELL PATH:
     - /Users/user/.gem/ruby/2.0.0/bin
     - /Users/user/.nodebrew/current/bin
     - /usr/local/bin
     - /usr/bin
     - /bin
     - /usr/sbin
     - /sbin
     - ./node_modules/.bin

インストール

$ gem install bundler
Successfully installed bundler-1.11.2
Parsing documentation for bundler-1.11.2
Installing ri documentation for bundler-1.11.2
1 gem installed

確認

$ bundle -v
Bundler version 1.11.2

BundlerでGemをインストールする

プロジェクトのディレクトリーを作成して、Bundlerの設定ファイルであるGemfileというファイルを作成します。

$ mkdir [directory]
$ cd [directory]
$ bundle init
Writing new Gemfile to /Users/user/[directory]/Gemfile

確認のために、以前自分がよく使っていたsinatraというGemをインストールする設定にしてみます。

$ echo "gem 'sinatra'" >> Gemfile
$ cat Gemfile
# A sample Gemfile
source "https://rubygems.org"

# gem "rails"
gem 'sinatra'

Install your dependencies, even gems that are already installed to your system gems, to a location other than your system's gem repository. In this case, install them to vendor/bundle.

$ bundle install --path vendor/bundle

Further bundle commands or calls to Bundler.setup or Bundler.require will remember this location.

Bundler: The best way to manage a Ruby application's gems

RubyアプリケーションのGemを管理する最良の方法ということで、すでに同じGemがシステムのGemリポジトリーにインストールされている場合は、vendor/bundleにインストールするように記載されています。 これと同じようにvendor/bundleにインストールしようと思いますが、システムのGemに同じものがなくてもプロジェクトごとにGemをインストールするのが今の流れのように感じています。

$ bundle install --path vendor/bundle
Fetching gem metadata from https://rubygems.org/...........
Fetching version metadata from https://rubygems.org/..
Resolving dependencies...
Installing rack 1.6.4
Installing tilt 2.0.2
Using bundler 1.11.2
Installing rack-protection 1.5.3
Installing sinatra 1.4.7
Bundle complete! 1 Gemfile dependency, 5 gems now installed.
Bundled gems are installed into ./vendor/bundle.

.bundle/configGemfile.lockファイルとvendor/bundleディレクトリーが作成されました。 .bundle/configbundleを実行した時の設定が保存されますので、次にbundle installとかした時に--path vendor/bundleをつけなくてもvendor/bundleディレクトリーにGemがインストールされることになります。 Gemfile.lockbundle installした時の各Gemのバージョンを覚えておくためのファイルです。 vendor/bundleディレクトリーより下は省略していますが、この下にGemがインストールされています。

$ tree -a -L 2
.
├── .bundle
│   └── config
├── Gemfile
├── Gemfile.lock
└── vendor
    └── bundle

3 directories, 3 files

アップデート

全てのGemをまとめてアップデートしてみます。

$ bundle update
Fetching gem metadata from https://rubygems.org/...........
Fetching version metadata from https://rubygems.org/..
Resolving dependencies...
Using rack 1.6.4
Using tilt 2.0.2
Using bundler 1.11.2
Using rack-protection 1.5.3
Using sinatra 1.4.7
Bundle updated!

アンインストール

アンインストールは個別にするようです。

$ bundle exec gem uninstall sinatra

Gemfileからgem 'sinatra'の行を削除します。 ここではコメントアウトにしました。

$ cat Gemfile
# A sample Gemfile
source "https://rubygems.org"

# gem "rails"
#gem 'sinatra'

bundle updateGemfile.lockファイルの内容を更新します。

$ bundle update
The Gemfile specifies no dependencies
Resolving dependencies...
Bundle updated!

Gemfile.lockファイルの内容が更新されました。

$ cat Gemfile.lock
GEM
  remote: https://rubygems.org/
  specs:

PLATFORMS
  ruby

DEPENDENCIES

BUNDLED WITH
   1.11.2

クリーン

アップデートやアンインストールで不要になったGemを綺麗にします。 これをするとファイルシステムからファイルが削除されることになります。

$ bundle clean
Removing rack (1.6.4)
Removing rack-protection (1.5.3)
Removing sinatra (1.4.7)
Removing tilt (2.0.2)

終わり

gemにインストールした記憶のないものがいくつかあるのが気になる・・

$ gem list

*** LOCAL GEMS ***

bigdecimal (1.2.0)
bundler (1.11.2)
CFPropertyList (2.2.8) # ← これ
io-console (0.4.2)
json (1.7.7)
libxml-ruby (2.6.0) # ← これ
minitest (4.3.2)
nokogiri (1.5.6) # ← これ
psych (2.0.0)
rake (0.9.6)
rdoc (4.0.0)
rubygems-update (2.5.1)
sqlite3 (1.3.7) # ← これ
test-unit (2.0.0.0)

/System/Library/Frameworks/Ruby.framework/の下にあるようなんですど・・

$ ls -l /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/gems/2.0.0/gems/
total 0
drwxr-xr-x   4 root  wheel  136  8 23 09:24 CFPropertyList-2.2.8
drwxr-xr-x  11 root  wheel  374  8 23 09:25 libxml-ruby-2.6.0
drwxr-xr-x  19 root  wheel  646  8 23 09:25 nokogiri-1.5.6
drwxr-xr-x  14 root  wheel  476  8 23 09:25 sqlite3-1.3.7

ご存知の方がいらっしゃったら教えて欲しいです。

参考