すがブロ

sugamasaoのhatenablogだよ

ローカルにgemサーバをたてたい!

gemでインストールするのは楽だけれど、インターネットに繋がってないよ!

っていう環境って実際は多いと思うんですよね*1
で、そういう時のためにローカルの gem サーバを建てれば良いんじゃんっていう話と、でもでも、gemの依存関係さらうの大変すぎてやってらんないんだけど!っていう話について書くよ。
gem server を使って自分のローカルを云々って話もあるけれど、常時使う用途にはちょっとねー、というかやってる人ってどんだけいるんだ。

gem サーバを建てる

gem コマンドには、 gem サーバに必要なファイルを生成するコマンドがあるので、それを使う。

  1. 配信用 httpd のドキュメントルート内に gems ディレクトリを作り、 gem ファイルを置く
  2. gem generate_index で gem 配信用ファイルを生成する
  3. gem install 時に --source でローカルサーバを見るようにする

これだけ。簡単でしょう?

具体的には

/www/local がドキュメントルートだとして activerecord を配信する場合。

% cd /www/local
% mkdir gems  
% mv activerecord-3.0.5.gem gems  
% gem generate_index
Loading 1 gems from .
.
Loaded all gems
loaded: 0.034s
Generating Marshal quick index gemspecs for 1 gems
.
Complete
Generated Marshal quick index gemspecs: 0.001s
Generating YAML quick index gemspecs for 1 gems
.
Complete
Generated YAML quick index gemspecs: 0.008s
Generating quick index
Generated quick index: 0.000s
Generating latest index
Generated latest index: 0.000s
Generating Marshal master index
Generated Marshal master index: 0.000s
Generating YAML master index for 1 gems (this may take a while)
.
Complete
Generated YAML master index: 0.007s
Generating specs index
Generated specs index: 0.000s
Generating latest specs index
Generated latest specs index: 0.000s
Generating prerelease specs index
Generated prerelease specs index: 0.000s
Compressing indicies
Compressed indicies: 0.004s

これで配信用のサーバの設定はできた。
あとは指定してインストールするだけ

% gem install activerecord --source http://localhost # もっと下にディレクトリを切ってる場合はそこまで指定すればOK

配信する環境としてはこれで良いんだけど……。

でもでも、 gem の依存関係を集めるのめんどくさくて死にそうな件

上記で配信はできるんだけど、例えば ActiveRecord にだって依存関係はある。そしてそれを手軽に準備するための手段はあるのか?
自分の使ってる gem から掘り起こすのも面倒だし、もうちょっときちっと把握したい場合の手順を知りたいですよね。

そこで rvm ですよ

rvm の gemset を使って、必要な gem だけを集めて、それを配信用の gems ディレクトリに持っていけばウマーじゃねっていう。
rvm 自体は以下を参照してください。ざっくり説明すると Ruby のバージョンを複数管理するためのツールですが、 gemset という gem をインストールしている環境を複数使うための機構もあります。

あとはこのブログでも書いてあるエントリとかも参考になるかも。

で、rvm 由来の Ruby を使っているとして。
以下のコマンドで、現在の gem のディレクトリを確認できます。

% rvm gemdir 
/Users/sugamasao/.rvm/gems/ruby-1.9.2-head

新しい gemset を作って、そちらに切り替えます*2

% rvm gemset list

info: gemsets : for ruby-1.9.2-head (found in /Users/sugamasao/.rvm/gems/)
global
hoge

% rvm gemset create test

info: Gemset 'test' created.

% rvm gemset use test

info: Now using gemset 'test'

% rvm gemset list

info: gemsets : for ruby-1.9.2-head (found in /Users/sugamasao/.rvm/gems/)
global
hoge
test

そうすると、クリーンな状態の gem 環境が構築されます。

% rvm gemdir 
/Users/sugamasao/.rvm/gems/ruby-1.9.2-head@test

% gem list
*** LOCAL GEMS ***

rake (0.8.7)
rdoc (2.5.8)

ここでおもむろに(インターネット回線経由で)目的の gem をインストールする。

% gem install activerecord
Successfully installed activesupport-3.0.5
Successfully installed builder-2.1.2
Successfully installed i18n-0.5.0
Successfully installed activemodel-3.0.5
Successfully installed arel-2.0.9
Successfully installed tzinfo-0.3.26
Successfully installed activerecord-3.0.5
7 gems installed

そうしたら、 rvm gemdir のディレクトリ内にある cache ディレクトリを確認してみよう。

% ll /Users/sugamasao/.rvm/gems/ruby-1.9.2-head@test/cache
total 2192
-rw-r--r--  1 sugamasao  staff   37888  4  4 01:54 activemodel-3.0.5.gem
-rw-r--r--  1 sugamasao  staff  342528  4  4 01:54 activerecord-3.0.5.gem
-rw-r--r--  1 sugamasao  staff  303104  4  4 01:54 activesupport-3.0.5.gem
-rw-r--r--  1 sugamasao  staff   36864  4  4 01:54 arel-2.0.9.gem
-rw-r--r--  1 sugamasao  staff   22528  4  4 01:54 builder-2.1.2.gem
-rw-r--r--  1 sugamasao  staff   60416  4  4 01:54 i18n-0.5.0.gem
-rw-r--r--  1 sugamasao  staff  310272  4  4 01:54 tzinfo-0.3.26.gem

\ gem がアルゾー /
あとはここの gem ファイルたちを配信用の gems ディレクトリに移して、generate_index してあげればよい。
ね、簡単でしょう?

ちなみに

普段使ってる gemset に戻すときは、 use の後に何も指定しないで実行すると元に戻る。

% rvm gemset use
__rvm_parse_args:shift:66: shift count must be <= $#

info: Now using gemset 'default'

enjoy!

*1:本番サーバとか

*2:一応最初と最後に list で gemset の一覧を確認してる。