たごもりすメモ

コードとかその他の話とか。

gemspecにおける依存gem記述上の注意

要約

gemspecにおいて add_development_dependency と add_runtime_dependency (or add_dependency) の両方に同じgemがセットされたものをリリースすると、そのgemを bundler 経由でインストールしたとき正常に依存gemがインストールされなくなる。

これはおそらく rubygems.org の問題である。なぜなら該当 gemspec を用いて rake build したgemを手元で直接インストールしたときは依存ライブラリは正常にインストールされる。このgemをリリース後に rubygems.org のAPI経由で確認すると依存gemリストが正常に返ってこないことが確認できている。

なお該当の条件を満たす gemspec を含むgemがすべて影響を受けるわけではなく、おそらく最近数ヶ月のうちにリリースされたもののみが対象である。充分過去にリリースされたgemであれば問題のない状況である場合もある。

しかし今後のリリース時にうっかり修正を忘れる可能性が否定できないので、条件を満たす gem については今のうちに修正して再リリースしておいた方がよい。おそらく。

経緯・詳細

最近自分で書いていたgemのうちいくつかについて bundle install で依存gemがインストールされないという状況になっているのに気付いた。gemspec はちゃんと書いてあるように見えるし実際にコードを走らせてみても問題ないように見える、rubygems.org/gems/gemname で見てみても正常に依存gemがリストアップされている。

あれー? と思ってあれこれ調べたり調べてもらったりした結果、rubygems.org の一部のAPIが依存ライブラリについての情報を正しく返さない状態になっていることに気付いた。具体的には gemspec で同じライブラリを add_development_dependency, add_runtime_dependency 両方やっていると、rubygems.org の一部のAPIについて、返す依存ライブラリに正常にリストアップされなくなる。

特定のgemの最新の状況について調べたい場合は以下の1-linerを実行すればよい。dependencies が空リストになっているものは影響を受けている。正常なものは add_runtime_dependency にリストアップしたものが並んでいるはず。*1

$ ruby -rrubygems -ropen-uri -rpp -e 'pp Marshal.load(open("https://rubygems.org/api/v1/dependencies?gems=#{ARGV[0]}")).sort{|a,b|Gem::Version.new(b[:number])<=>Gem::Version.new(a[:number])}.first' gemname

過去の全バージョンについて調べたい場合は最後の .first を削ればよい。影響を受けているgemについて過去のリリースを見ると、充分前にリリースされたものがあれば、おそらくそちらは dependencies は意図したものが含まれているのが確認できると思う*2

なお以下のエントリで過去に自分が "fluentd" を add_development_dependency および add_runtime_dependency の両方に記述しており、それを見てgemを書きはじめたという人は影響を受けている可能性が高い。特にfluent-plugin作者の方々はご注意いただきたい*3。原文は修正してある。

fluentdのためのプラグインをイチから書く手順(bundler版) - tagomorisのメモ置き場

状況については以下URLにて報告してある。意図的なものだとは思えないので修正されると思いたいが、そもそも何が原因なのか自分でも追ってないのでなんとも。たぶん以下リポジトリに含まれるコードの何らかの変更が原因なんじゃないかなあ……。たぶん。

https://github.com/rubygems/rubygems.org

なんというか、あれですね。すいませんすいません。……しかし自分の書き方もたぶんどこかから真似たんだと思うので、世の中に他にも同じ状況に陥っているgemがありそうだけどなあ。どこからパクった書きかただったかなー。

あと実際問題として、両方に列挙するのは間違いなんでしょうか。識者のご指摘をいただけますと嬉しいです。

*1:開発時依存のライブラリは表示されない

*2:このため gem アップロード時に行われる何らかの解析処理およびその情報の保存ロジックに何か問題があるのではないか、と思われる。したがって充分前にrelease済で影響を受けていないgemが今後突然おかしくなるということは無い、と思う。たぶん。

*3:ただし fluentd plugin については bundler 経由でインストールするという使いかたはおそらく少数派に属すると思われるため、実際にこれで fluentd plugin が誤動作するというケースは比較的少ないのではないかと思う。実際そのためこれまで気付かなかった。