Skip to content

Instantly share code, notes, and snippets.

@japboy
Last active December 18, 2015 09:49
Show Gist options
  • Save japboy/5763697 to your computer and use it in GitHub Desktop.
Save japboy/5763697 to your computer and use it in GitHub Desktop.

rbenv に学ぶ PHP/Python/Ruby/Node.js のバージョン管理 (WIP)

ついに重い腰をあげて、軽量プログラミング言語のバージョン管理はじめました。Perl? そんなものは知りません。

バージョン管理?

バージョン管理の必要性

バージョン管理ってなんでしょうか。Subversion とか Git みたいな VCS のことでしょうか。似ていますが、ちがいます。

こんなことはありませんか。

  • クライアントが提供する環境が PHP 4 なので、普段の PHP 5 とは別に開発環境を用意しなければならなくなった。
  • 最新の Python 3 を導入したら、ほとんどの Python ライブラリが Python 2 系にしか対応していなくて、Python 2 もインストールする必要があった。
  • 最新の Ruby 2.0 にアップデートしたら、いつも使っている Ruby のツールが動作しなくなった。
  • Node.js がバージョンアップしたので更新したら、ほとんどのライブラリが動かなくなってバージョンをもどす必要がでた。

PHPPythonRubyNode.js のような軽量プログラミング言語を使っていると、このような問題によく直面します。

この問題の難しいところは、 「古いバージョンだと対応できなくなったから、最新バージョンに更新した」だけでは 、問題解決とならないところです。

時には、 「最新バージョンに更新したら、古いバージョンが必要になった」 みたいなことが生じます。

更に、 「この案件では古いバージョンが必要で、その案件では最新バージョンが必要で...」 といった具合に、案件ごとに必要とされる要件は変わるものです。

こういった状況に、いったいどうやって対処するのが良いでしょうか。案件ごとに専用のコンピュータを用意しますか。でも案件の開発者が複数人いたら、どうしますか。これは厄介な問題です。

今回学びたいのは、こういった問題の解決のための、「軽量プログラミング言語のバージョン管理」です。

パッケージ管理との違い

さて、これらの軽量プログラミング言語を使用したことがある人ならば、gem pip npm のようなコマンドも使用したことがあるでしょう。

これらは順に、Ruby、Python、Node.js のパッケージ管理システムです (PHP にも Pear や Pyrus といったパッケージ管理システムがあります)。

これらパッケージ管理と、バージョン管理とは、何がちがうのでしょう。前者も使用するライブラリのバージョンを管理する仕組みですし、バージョン管理といえるのではないでしょうか。

実際の違いは以下の通りです:

  • パッケージ管理とは、軽量プログラミング言語ごとのライブラリから 使用したいライブラリとそのバージョンを管理 する仕組み。
  • バージョン管理とは、軽量プログラミング言語 そのもののバージョンを管理 する仕組み。

この違いは理解しておきましょう。

rbenv?

さて、これらをふまえた上で、実際のバージョン管理を始めるにはどうしたら良いでしょう。もちろんそのためのツールを導入するのが賢明です。

しかし、このバージョン管理ツール、結構な種類があります:

この中で Ruby 界隈では近年 rbenv が普及しているようです。

rbenv の特徴としては;

  • グローバル環境のバージョン切替に対応
  • ローカル環境のバージョン切替に対応
  • プラグインによる機能拡張
  • バージョン管理に特化したシンプルな設計

などが挙げられます。

個人的見解で言わせてもらえば、これは Node.js の流行と共に訪れた UNIX 思想の再評価の結果だと思います。

rbenv はもう一つの rvm より "do one thing and do it well" の考えに近い実装となっており、シンプルな機能になっています。

シンプルな分、汎用性が高く、rbenv の実装を;

  • PHP で再現した phpenv
  • Python で再現した pyenv
  • Node.js で再現した nenv

が存在します。

従って rbenv の使い方を学ぶことで、PHP、Python、Ruby、Node.js のバージョン管理を同じ方法でできるようになります。

今回はそれをふまえ、rbenv の仕組みを学び、Ruby 以外にもその仕組みを適用したいと思います。

rbenv の概要

rbenv はシンプルなツールです。ですので実際にバージョン管理で使用するためには ruby-build という別のツールも組み合わせる必要があります。

rbenv はあくまでバージョン管理ツールです。バージョン管理される Ruby のソースコードをダウンロードしてきたり、コンパイルする機能はもちません。そういった機能は ruby-build として提供されているわけです。

ワークフローとしては以下のようになります:

  1. ruby-build でソースコードをダウンロードしてコンパイル
  2. コンパイルした Ruby を rbenv の管理下に設置
  3. rbenv でその Ruby に切り替えて使用

このようにして使用したい Ruby のバージョンを ruby-build で取得し、rbenv で実際に使えるように切り替える仕組みとなっています。

rbenv と Ruby のバージョン管理

rbenv と ruby-build

前述の通り rbenv を使うには、Ruby のコンパイルを担当する ruby-build と、Ruby のバージョン切り替えを担当する rbenv の 2 つのツールが必要です。

入手やインストール方法は以下のサイトで確認できます:

Mac OS X でのインストール方法

Mac OS X 環境では Homebrew と組み合わせたインストール方法が一般的でしょう。

まず Homebrew から ruby-build をインストールします:

brew install ruby-build

ruby-build のインストール先は Homebrew のコマンドで確認できます:

brew --prefix ruby-build

つづいて GitHub から rbenv をダウンロードし PATH を通してインストールします:

git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
exec $SHELL -l

これで ruby-buildrbenv コマンドが使えるようになります。

ruby-build の基本

ruby-build は Ruby のダウンロードとコンパイルを担当するツールです。なので、複数のバージョンを簡単に取得できる仕組みが提供されています。

一覧の取得

本来であれば;

  • どこからダウンロードして
  • どういったコンパイルオプションでコンパイルするのか

指定しなければなりません。

しかし ruby-build では予めこれらの設定が用意してあります。設定済のインストール可能はバージョン一覧は、次のコマンドで確認できます:

ruby-build --definitions

ダウンロードとコンパイル

例えば最新の Ruby 2.0.0-p195 をダウンロード、コンパイルして、/path/to/ruby に格納するコマンドは次の通りです:

ruby-build 2.0.0-p195 /path/to/ruby

このように単純にバージョンと格納先だけ指定してやれば、後は自動でダウンロードとコンパイルを実行してくれます。

バージョンファイル

以下は ruby-build のインストール先ディレクトリ構成です:

ruby-build/
├── bin/
└── share/
    └── ruby-build/
        └── {バージョン}

ruby-build/share/ruby-build 以下には Ruby のバージョンと対応した名前のファイルが格納されています。これが前述の ruby-build --definitions コマンドで出力される一覧と対応しています。

この {バージョン} ファイルはテキストファイルです。この中に、ダウンロード先やコンパイルオプションが記述されています。もしコンパイルエラーでインストールできない時は、このファイルのコンパイルオプションや設定を見直してみましょう。

もちろん、記述形式に沿って、自分で {バージョン} ファイルを書き、追加してやることも可能です。

コンパイルオプションの上書き

コンパイルオプションは環境変数から上書きすることも可能です。上書きするときは CONFIGURE_OPTS 環境変数に値を渡して ruby-build を実行します。

下記は Mac OS X で Homebrew でインストールされた opensslreadline を依存関係に指定する例です:

CONFIGURE_OPTS="--with-openssl-dir=$(brew --prefix openssl) \
                --with-readline-dir=$(brew --prefix readline)" \
ruby-build 2.0.0-p195 ~/path/to/ruby

こうすることで、バージョンファイルを書き換えなくても、コンパイルオプションを指定することができます。

これが ruby-build の基本になります。

rbenv の基本

rbenv は Ruby のバージョン切り替えを担当するツールです。前述の ruby-build でコンパイルした Ruby を rbenv の管理下に格納することで、それらの Ruby を簡単に切り替えられるようになります。

ディレクトリ構成

以下は rbenv のインストール先ディレクトリ構成です:

.rbenv/
├── bin/
├── completions/
├── libexec/
├── shims/
├── test/
└── versions
    └── {バージョン}/

rbenv では .rbenv/versions というディレクトリがあります。そしてその下にそれぞれの Ruby バージョンのディレクトリを作成します。この中に実際の Ruby が格納される仕組みです。

ここで話を ruby-build に戻します。

ruby-build で Ruby をコンパイルするときのコマンドを以下のようにしてみましょう:

ruby-build 2.0.0-p195 ~/.rbenv/versions/2.0.0-p195

rbenv が ~/.rbenv 下にインストールされていれば、上記コマンドで、前述の通り .rbenv/versions 下にコンパイルされた Ruby を格納できます。

つまり ruby-build のコンパイル先を rbenv の versions ディレクトリにしてやることで、rbenv に Ruby をインストールしてやることになるのです。

インストール

前述の通り Ruby のインストールは次のコマンドです:

ruby-build 2.0.0-p195 ~/.rbenv/versions/2.0.0-p195

しかし ruby-buildrbenv がインストールされた環境では、次のコマンドでも同じ結果が得られます:

rbenv install 2.0.0-p195

rbenv installruby-build コマンドのショートカットです。

そしてインストール可能な Ruby 一覧を確認するコマンドもあります:

rbenv install --list

これは前述の ruby-build --definitions コマンドのショートカットです。

これらも覚えておくと便利です。

バージョン確認

さて、ではインストールされている Ruby バージョン一覧も確認したいところです。そのためのコマンドは次の通りです:

rbenv versions

上記コマンドを実行すると以下のような出力が得られます:

  system
* 2.0.0-p195 (set by /Users/User/.rbenv/version)

system は文字通りシステムに標準でインストールされている Ruby を指します。行頭の * は現在有効な Ruby を指します。

上記の例では、Ruby の 2.0.0-p195 が現在有効になっているのがわかります。

バージョン切替

phpenv と PHP のバージョン管理

phpenv と php-build

php-build の基本

コンパイルオプションの指定

default_configure_options

pyenv と Python のバージョン管理

python-build の基本

コンパイルオプションの指定

CONFIGURE_OPTS

nenv と Node.js のバージョン管理

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment