平衡点


2012/12/10 [長年日記]

_ .gem から .deb へ 〜 gem2deb の紹介

はじめに

この記事は Debian/Ubuntu JP Advent Calendar 2012 : ATND の 12/10(月) の記事です(しかし, これを書いているのは 12/11 である, という...). 昨日はあかべさん(@vbkaisetsu)による nmudiff の使い方 でした.

今日のお題は Debian(>=Wheezy)/Ubunut(>=Precise) で「.gem をお手軽に .deb に」というお話です. 実際にお手軽にできるかは, その .gem の依存関係によりますが...

.gem って? .deb って?

Ruby 用のパッケージシステム RubyGems で使われるファイルの拡張子が .gem です. 実態は tar の archive で, これを展開すると data.tar.gz{,.sig}, metadata.gz{,.sig} が入っています. gem コマンドは metadata の内容に従って, .gem を処理しています.

Debian における配布パッケージの拡張子が .deb です. 中身は ar の archive で, debian-binary, control.tar.gz, data.tar.gz からなります. apt-get などでファイルを取得した後に, 下層で dpkg が動いて, .deb を処理します.

gem2deb って?

そのものズバリ, .gem.deb に変換するコマンドです.

RubyGems 自体がパッケージシステムですので, 別にわざわざ面倒な作業をしなくても良いじゃないか, という話もありますがパッケージシステムは一つの方が嬉しい (こともあります)よね, ということで.

ちなみに Perl の場合, CPAN で配布されているモジュールを .deb に変換する dh-make-perl なんてものが用意されています. gem2deb はこの Ruby 版だと思って下さい.

gem2deb ってどう使うの?

とりあえず

$ sudo apt-get install gem2deb

してから,

$ gem fetch hogehoge

.gem をダウンロードして下さい. その後, おもむろに

$ gem2deb hogehoge.gem

とします. うまく行けばこれで ruby-hogehoge という Debian パッケージ(.deb)ができます. その後おもむろに

$ sudo dpkg -i ruby-hogehoge*.deb

とすると, Debian パッケージとして導入されます.

.deb ができなかった Yo!!

残念ですね. なんででしょうか? 多くの場合は test に失敗したから だと思いますが, 如何でしょうか?

理由は幾つか考えられます.

test/spec に使う Ruby ライブラリが導入されていない

metadata や .gemspec を見て, 必要な環境を整えましょう. 一応, Gemfile, metadata, .gemspec を見て, test/spec の実行に必要そうなライブラリは debian/control ファイル内の Build-Depends フィールドに 列挙されています. これを確認してみましょう.

test/spec が特定のディレクトリ構造やRuby 以外の環境に依存していて =gem2deb= が提供している test-runner ではそもそもtest/spec が実行できない

必要に応じて patch 書きましょう. もしくは debian/rules 内の IGNORE から始まる行を有効にするのが良いと思います.

  • test/ 以下で実行されることを前提として, 相対パスで必要なライブラリを読み込んでいたりする gem とか?
  • .git を参照して spec を実行する gem もあったり(当然 .git は配布物の中には含まれておりません).
    • まあ, gem として配布する際には test 走らせることは無いのかな...
ruby1.8 では動かない, もしくは ruby (>= 1.9) では動かない

現状, Debian Ruby Extra チームでは 「複数の ruby 実装で動作すること」を目標にしています. /usr/bin/ruby は, alternatives で提供されていて, 使いたい ruby の実装を切り変えられるようになっています.

  • とはいえ, JRuby は Java チームの管轄なので, まだ上記範疇には入っていないですし, rubinius は(ITP されて進展していますが)まだ Debian パッケージには なっていません.

とりあえず debian/control 内の XS-Ruby-Version を適宜弄りましょう. デフォルトでは all になっているでしょうから, これを ruby1.8 とか ruby1.9.1 に変えると良いと思います.

そういや以前(関西闇Rubyかな?), 「Ruby 1.9.3 なのに実行バイナリの名前が ruby1.9.1 なのはなんで?」 とか聞かれましたが, soname 変わってないから, ですね.

$ ruby1.9.1 -v
ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux]

うーん...

まとめ

というわけで, あんまり gem2deb が知られていないようなので, 「こういうモノもあるよ?」というお話を書いてみました.

Teams/Ruby/Packaging には, 現在 Teams/Ruby が行なっている「 gem2deb によるパッケージ作成」の ノウハウがまとまっていますので, Debian パッケージ作成に興味があって, Ruby への愛に溢れている人は, 是非一度眺めてみて下さい (ついでに, 一緒に Debian パッケージを作成/管理しませんか?).

あと gem を配布している/作成している方は 一度 Teams/Ruby/RubyExtras/UpstreamDevelopers なんかを眺めてみて下さると幸いです. ディストリビューションのパッケージメンテナってこんな事気にしてんのかよ, とか, そういう.

最後に一言. gem の配布物って dependency hell 多過ぎじゃない?

明日も罰ゲームで私の予定です.