わすれっぽいきみえ

みらいのじぶんにやさしくしてやる

gemのインストール先にrbenvが指すものとGem.user_dirがあることを知らなくてハマった話

rbenvでrubyのバージョンを上げた後bundlerをインストールしたら

$ bundle -v
zsh: command not found: bundle

が返ってきた。 rbenv rehash は実行したのに /Users/kimikimi714/.rbenv/shims/ 下にbundlerが見つからない。

そもそもインストールした時点で

$ sudo gem install bundler
Password:
WARNING:  You don't have /Users/kimikimi714/.gem/ruby/2.1.0/bin in your PATH,
      gem executables will not run.
Successfully installed bundler-1.10.6
Parsing documentation for bundler-1.10.6
Done installing documentation for bundler after 4 seconds
1 gem installed

と返ってきており、確かに良く見たら /Users/kimikimi714/.rbenv/shims/ 下ではなく、 /Users/kimikimi714/.gem/ruby/2.1.0/bin 下にbundlerがインストールされていた。以前rbenvでruby上げた後にbundlerを入れたときにはこの警告が出なかった気がしたので何が変わったんだろうかと思った。

なので、いきなり安易に /Users/kimikimi714/.gem/ruby/2.1.0/binPATH に追加する方法は取らずに、なぜ /Users/kimikimi714/.gem/ruby/2.1.0/bin 下にbundlerがインストールされたのかを調べた。

gem environment

gem environment はgemに関するもろもろの設定を表示してくれる便利コマンドだ。コマンドの使い方はここを見てもらうこととして、単純に実行すると以下のようになった。

$ gem environment
RubyGems Environment:
  - RUBYGEMS VERSION: 2.2.3
  - RUBY VERSION: 2.1.6 (2015-04-13 patchlevel 336) [x86_64-darwin14.0]
  - INSTALLATION DIRECTORY: /Users/kimikimi714/.rbenv/versions/2.1.6/lib/ruby/gems/2.1.0
  - RUBY EXECUTABLE: /Users/kimikimi714/.rbenv/versions/2.1.6/bin/ruby
  - EXECUTABLE DIRECTORY: /Users/kimikimi714/.rbenv/versions/2.1.6/bin
  - SPEC CACHE DIRECTORY: /Users/kimikimi714/.gem/specs
  - RUBYGEMS PLATFORMS:
    - ruby
    - x86_64-darwin-14
  - GEM PATHS:
     - /Users/kimikimi714/.rbenv/versions/2.1.6/lib/ruby/gems/2.1.0
     - /Users/kimikimi714/.gem/ruby/2.1.0
  - GEM CONFIGURATION:
     - :update_sources => true
     - :verbose => true
     - :backtrace => false
     - :bulk_threshold => 1000
     - :sources => ["https://rubygems.org/"]
     - "install" => "--user"
     - "update" => "--user"
(以下略)

注目したいのは GEM_PATHS で、ここにはrbenvで作成されたgemのインストール用ディレクトリとホームディレクトリ下のディレクトリの二つが指定されている。ややこしいんだが GEM_PATHS とはgemのインストール先にどのディレクトリを用いるのかをリスト表示しているもので、gemの実行パスを指しているわけではない。 gem list を実行すると GEM_PATHS の中を見てgemを探して見つかったら表示されてしまうので勘違いする人多いのでは?と思う。私はここを見て「パス通ってるやんか。なんでcommand not foundやねん」とすごく悩んだ。

次に注目したいのは GEM CONFIGURATION で、これは文字通りgemの設定を表しているんだが、 ~/.gemrc でここの設定をいじることができる。で、今回のbundlerの件で言えば ~/.gemrc の設定によって /Users/kimikimi714/.gem/ruby/2.1.0/bin にbundlerがインストールされてしまっていた。

.gemrc

.gemrcとはgemの設定ファイルだ。書き方の説明も gem environment と同じページを見ると良い。

最初に私が書いていた .gemrc の設定は以下。*1

$ cat ~/.gemrc
---
:backtrace: false
:bulk_threshold: 1000
:sources:
- https://rubygems.org/
:update_sources: true
:verbose: true
install: "--user"
update: "--user"

ここにある install: "--user" が「 /Users/kimikimi714/.gem/ruby/2.1.0/bin にgemをインストールしろ」という設定にあたる。 --user をつけると優先的にホームディレクトリ下にgemをインストールしてしまう。

Frequently Asked Questions - RubyGems Guides

に記載があるが*2、この下にインストールされたgemはパスが通ってないので

if which ruby >/dev/null && which gem >/dev/null; then
    PATH="$(ruby -rubygems -e 'puts Gem.user_dir')/bin:$PATH"
fi

.bashrc なり .zshrc なりに追記してやる必要がある。その設定をやってなかったことが一番最初に書いたWARNINGの理由であり、bundlerが見つからなかった理由だった。

/Users/kimikimi714/.gem/ruby/2.1.0/bin は人によってパス名が違ってくる。これを解決してくれるのが Gem.user_dir で、ユーザごとのホームディレクトリ名とrubyのバージョンをいい感じにしてgemのインストール先がどこになるのか教えてくれる。

今回の私の場合はrbenvをユーザごとでインストールしていて、あまり user_dir を使う必要性を感じなかったので、 ~/.gemrc の方から --user の設定を削除することで対処した。なので結局 PATHGem.user_dir を追加しなかった。

問題解決にあたって見て回ったリンク

*1:.gemrc、自分で書いた記憶が全くなくて何かの拍子に自動生成されたようだ。たぶんrubyのバージョンアップのときになんかいい感じにやってくれようとして大きなお世話になったやつだと思う。

*2:FAQに書かれる程度にはみんなハマるっぽい。