direnvは単なるシェルの拡張であり、今いるフォルダによって環境変数を管理します。 この記事では、ruby-installと組み合わせて使うことで、プロジェクトで使いたいrubyのバージョンを管理したり選択したりする方法を見ていきます。
まずdirenvをインストールしてください。 以下はOSXとBashを使っている場合の簡単な手順です。
brew install direnv
echo 'eval $(direnv hook bash)' >> .bashrc
exec $0
それからruby-installを使って、いくつかrubyのバージョンをインストールしてください。 また、便宜上エイリアスを作ります。
brew install ruby-install
ruby-install ruby 1.9
ruby-install ruby 2.0
cd ~/.rubies
ln -s 1.9.3-p448 1.9.3
ln -s 1.9.3-p448 1.9
ln -s 2.0.0-p247 2.0.0
ln -s 2.0.0-p247 2.0
最終目標は、各プロジェクトに、use ruby 1.9.3
のような分かりやすい構文を含む.envrc
ファイルがあり、プロジェクトの正しいrubyのバージョンを選択できるようにすることです。
このため、direnvの標準ライブラリで使えるコマンドを使います。
また、~/.config/direnv/direnvrc
ファイルで少し拡張します。
以下を~/.config/direnv/direnvrc
ファイルに追加してください(ファイルが存在しないときは作らなければなりません)。
# 使い方:use ruby <バージョン>
#
# 指定されたrubyのバージョンを環境に読み込みます
#
use_ruby() {
local ruby_dir=$HOME/.rubies/$1
load_prefix $ruby_dir
layout ruby
}
以上です。
これで、プロジェクトでdirenv edit .
を走らせたり、ファイルにuse ruby 1.9.3
やuse ruby 2.0
を追加したりして、direnvにより、プロジェクトのフォルダに入ったときに正しいrubyのバージョンが選択されるようにできます。
最後の部分は多分もう少し説明が必要です。 標準ライブラリの一部のコマンドを活用しており、これらはenvrcの実行の文脈で使えます。
use
はコマンドの発出器で、use ナントカ カントカ
の領域特化言語を構築するためだけにあります。
これにより、use ruby <バージョン>
はuse_ruby <バージョン>
に読み替えます。
load_prefix
により、環境にいくつかのものが追加されます。
特に、<prefix>/bin
がPATHに追加されます。
こうすることで、特定のrubyが使えるようになります。
また最後に、layout ruby
はuse
に似ており、layout_ruby
関数呼び出しに読み替えます。
これは、一般的なプロジェクトの配置を記述するために使います。
標準ライブラリでは、rubyの配置で(GEM_HOME
環境変数により)rubygemsを構成し、プロジェクトルート配下の
.direnv/ruby/RUBY_VERSION フォルダに全てのgemがインストールされます。
rvmのgemsetと少し似ていますが、そちらはプロジェクトのフォルダ内にある点が異なります。
また、bundlerを構成して、.direnv/bin フォルダにラッパーのシンボリックリンクをインストールします。
これにより、毎回bundle exec
でrubyプログラムを前置する代わりに、直接コマンドを呼び出せます。
ここまで見てきたように、この手法はrubyに限定されません。
~/.pythons
配下に様々なバージョンのpythonをインストールし、~/.direnvrc
でuse_python
を定義することができるでしょう。
perl、phpなども同様です。
これはdirenvの良い点であり、単一の言語に制限されないのです。
実際のところ、プロジェクトフォルダに入ったとき、全てのプロジェクトの依存関係があると素晴らしくないですか? rubyのバージョンだけでなく、使いたいredisやmysqlやその他諸々の厳密なバージョンを、VMを開始させることなく使えるといいですよね。 筆者はこれが確実に可能であると考えており、それにはNixパッケージ管理のようなものを使います。 そちらについては将来別の記事で見ていく必要があると考えています。