github に gem を公開する

最近一部で話題沸騰の github。github は Rails で作られたアプリケーションでは、自分が知りうる限り一番の完成度と使いやすさを誇るんじゃないか、と思っています。
ソースコードツリーの見やすさ、(g)zipでくれ機能、各種 git の情報へのアクセスしやすさ、最初に git レポジトリを作ったとき表示されるチュートリアルと云った基本的なことはもちろんですが、オープンソースプロジェクト・コミュニティを加速させるであろう、分散レポジトリを利用した様々な機能がすばらしいですね。
誰かが公開してるレポジトリを fork ボタン一つで自分のレポジトリにクローンし、いろいろ変更を加え、大本に取り込んで欲しいなぁ、と思ったら pull request。大本のコミッタは気に入れば pull で取り込めばよいし、もし気に入らなかったとしても、変更者がそのフォークしたレポジトリを削除しない限り、完全なソースが存在し続けます。それを気に入った第三者はそちらを使うのもよし、参考にするもよし。
また git のフック機能を利用した数々の機能。たとえば edit 画面からコミット時、指定した URL に JSON のデータを送るPost-Receive Hooks機能(Web Hooksと呼ばれてるらしいです。先ほど知りました)。
そして Rubyist にはうれしい、gem を自動でサーバサイドで作成してリリースしてくれる機能があったりします。

この機能は最近の rubygems に実装された、大本のソースURLを追加できる機能を利用しています。

$ sudo gem install rubygems-update
$ sudo gem update --system
$ gem sources -a http://gems.github.com

することにより、github をソース元に追加できます。rubyforge では結構アップロードが面倒でしたが、github では .gemspec ファイルを用意して、master に push するだけで gem が自動で作られ、公開されるのです。
というわけで、これは相当面白いので実際に rascut を gems.github.com に公開してみました。その手順メモを。

github でプロジェクトを作る

ふつうに作ります。rascut という名前で作ったので、ユーザ名/rascut名前空間が割り当てられます。

rubyforgesvn から取り込む

git-svn を使えば svn からのコンバートもばっちりです。

git-svn clone svn+ssh://secondlife@rubyforge.org/var/svn/hotchpotch/rascut/trunk rascut_svn

push する

チュートリアルに沿って、適当なファイルを作り最初のコミット、push を行います。

# 思い出して書いてるのでひょっとしたらうまくいかないかも…
mkdir rascut
cd rascut
git init
touch .gitignore
git add .gitignore
git commit -m 'first commit'
git remote add origin git@github.com:hotchpotch/rascut.git
git push origin master

その後 pull して svn な git を取り込み、push します。

git pull ../rascut_svn
git push

これで github に公開されました。

edit で RubyGem のチェックボックスにチェックを入れる

Web インターフェイスから行います。

gemspec ファイルを作る

hoe や cutagem の 0.0.8 >= ( いまは http://github.com/hotchpotch/cutagem/ にしかありませんが、そのうち id:cho45 が取り込んでくれるはず…) を使うと、 rake debug_gem で .gemspec ファイルを作ることができます。Gem::Specification#to_ruby というメソッドがあるので、自分で gem を作っている人は、puts spec.to_ruby での出力を取り込むだけで OK です。

$ rake --silent debug_gem > rascut.gemspec
$ git add rascut.gemspec   
$ gem build rascut.gemspec # build できるかチェック
$ git push

完了!

これでちょっと待つと、gems.github.com からインストールされるようになるはずです。

require 'open-uri'
require 'rubygems'

gem_list = Marshal.load(open('http://gems.github.com/Marshal.4.8').read)
gem_list.extend Enumerable
p gem_list.map{|l| l.first}.grep(/rascut/)

で、表示されれば完了です。後は

$ sudo gem install hotchpotch-rascut

と ユーザ名-プロジェクト名 でうまくインストールされるはずです。

github + rubygems が熱い

というわけで、自動で master だけ簡単に gem 化することができますね。いろんな俺俺 fork gem が乱立しそうな気もしなくはないですが、分散レポジトリ+OSSならではということで。

ちなみに本題とは関係ありませんが、現在はてなのレポジトリの大半は git に移行しました。svn から git に移行することで結構メリット・デメリットが見えた気がします。まだ一部試行錯誤してたりするので、まとまったらどこかで公開したいですね。