echinoideaははじめてのgem開発となりました。こちらの記事がとても参考になったのですが、割とつまずいた点が多かったのでまとめておきます。
JewelerよりBundler
最初はJewelerを使ってgemを作ろうとしたところ、RubyのバージョンやらGithubのAPI廃止などの影響があり、難航しました。どうやら、最近はJewelerを使うよりBundlerを使って開発する方がよさげです。
参考となる資料
【gemの作り方】 Rubyのオブジェクトをグンマー県が制圧するgem書いた
がわかりやすいので、これを読むのが一番だと思います。加えて、オープンソースで公開されているHeroku Toolbeltのコードも参考になります。
gemspecとgit
そのgemで使うソースコードなどをgemspecファイルにて指定するのですが、ここに注意が必要です。
Gem::Specification.new do |gem| gem.authors = ["Foo"] gem.email = ["foo@example.com"] gem.description = %q{TODO: Write a gem description} gem.summary = %q{TODO: Write a gem summary} gem.homepage = "" gem.files = `git ls-files`.split($\) gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) } gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) gem.name = "foo" gem.require_paths = ["lib"] gem.version = Foo::VERSION end
ここにgem内で使うファイルなどを記述していくわけですが、gem.filesの中身に注目。git ls-filesとなっており、gitレポジトリに登録されているファイルが対象になっています。新しいソースコードを追加した場合はレポジトリに登録しない限りここには追加されないので注意が必要です。
開発の流れとして、テストなどで動作確認後、パッケージを作成して動作確認、確認できたらレポジトリにコミット、というような流れだとレポジトリへの追加の前に動作確認時にここで躓くことがあるので注意。
実行可能なファイル
gemをインストールしたらコマンドを叩けるようにしたい場合は、gemspecのexecutablesの中に対象となる実行ファイルを登録します。通常はbinディレクトリを作成し、その中にスクリプトを用意し、拡張子無しのパーミッション755にします。
gemspecのデフォルトの設定では「binディレクトリ以下にあるレポジトリに登録されているファイルすべて」となっていますが、分かりにくいのでデフォルトでbinディレクトリ以下のファイルはすべて対象にするか、あるいは意図しないコマンドが登録されないように明示的に指定しなければ使えないようになっていたほうがいい気がしますが。
gem.executables = "heroku"
ちなみにherokuではherokuコマンドだけが明示的に指定されていました。
実行可能ファイルの動作確認
実行可能ファイルについては、テストケースだけで開発・動作確認していくのが難しい場合があります。特に特定のディレクトリでなければ動作確認ができないような場合は、ビルドはgemプロジェクトのディレクトリで行い、動作確認は確認用のディレクトリで…とディレクトリを行ったり来たりするのが面倒です。良いノウハウではありませんが下記のようなコマンドを用意しておくと手間が省けて便利です。(ただし途中でプログラムが失敗した場合は手動で戻る必要があります)
gem build foo.gemspec && rake install && cd 動作確認用のディレクトリ && 確認用コマンド && cd -
(cd – は直前のディレクトリに戻るためのコマンド)