トップ «前の日記(2015-09-02) 最新 次の日記(2015-09-16)» 編集

Route 477



2015-09-14

[ruby] gemを作るときに実行ファイルをbin/以下ではなくexe/以下に置くことについて

例えばあなたがコマンドラインからピザを注文するようなRubyGemsを書いているとすると、今まではbin/order_pizzaに実行用のファイルを置いていたと思うけど、それがexe/order_pizzaに変わるかもしれない、という話。

仕様変更なの?

実行ファイルをどこに置くかというのは完全に慣習の話で、.gemspecの仕様上は好きなところに置けるようになっている。なので既存のgemが動かなくなるという話ではない。 ただbundle gemコマンドでgemを新規生成したときに、以前のBundlerでは.gemspecが以下のようになっていたのに対し、

spec.bindir        = "bin"
spec.executables   = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }

Bundler 1.8からはこの箇所が以下のようになる。

spec.bindir        = "exe"
spec.executables   = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }

そのため今から新しくbundle gemしてgemを作るときは、実行ファイルはexe/以下に置く(か、.gemspecの当該箇所を編集する)必要がある。

なんで変わったの?

こっちには「うっかり開発用スクリプトをbin/に入れてしまうと、gem install時にインストールされてしまってうざい」みたいなことが書いてある。それはまあ分かるかも。 要するに「公開用スクリプトと開発用スクリプトを分けたい」っていう話っぽい。以前は両方binに入れてgemspecでフィルタしたりしてたけど、これからは開発用スクリプトはbin/に、公開用スクリプトはexe/に置くと。

そうなると、わざわざbin/の意味を変えずとも、「開発用スクリプトはdev/に入れる」みたいな規約を追加したらいいんじゃないの、という疑問が出てくる。しかし調べてみると、例のbundle binstubsコマンドがbin/を開発用に使うようなのだ。

bundle binstubsの使い方はこんな感じ。以下の例だと./bin/rakeというファイルができて、bundle exec rake -Tが./bin/rake -Tでよくなるので短くて嬉しいっていうことだと思う(多分)。

$ bundle gem new_gem
$ cd new_gem
$ bundle binstub rake
$ ./bin/rake -T

他にも当該コミットのコメントを見ると、rails, bundler, rubygemsあたりのプロジェクトがbin/を開発用に使っているという話がある。そういえばRails4でアプリを作ると./bin/railsとか./bin/springみたいな開発用スクリプトができますね。

まとめ

  • 既存のgemについては変更は不要。
  • 新しくbundle gemでgemを作るときは、exe/に公開用スクリプトを置く前提になっているので注意しよう。

参考にした記事