gemビルドしようとして `The validation error was 'yourgem-x.y.z contains itself (yourgem-x.y.z.gem), check your files list` と出たとき

  • 4
    Like
  • 0
    Comment

これは pepabo Advent Calendar 2016 - Qiita 8日目の記事です。

docker環境で動かしているredashをマイグレーションする話を書こうと思っていたら、一緒にやった人に先に書かれてしまうというアクシデントがおこり、どうしようと思いながらこんな時間になってしまいました。

今回の記事の内容は、gem開発の流儀ややり方を知ってる人はほとんどハマることはない問題です。それ故にあまり情報がないので、アドベントカレンダーのネタにすることにしました。

社内向けのgemをインストールしようとして失敗した

ペパボでは、社内向けのcliツールをgemとして開発し、GitHub Enterprizeからcloneしてrake installするような運用をしているものが幾つかあります。

数日前に、たまたまその1つを使おうと思ってcloneして、bin/setup(またはbundle install)をするとタイトルのようなエラーメッセージが出てきました。(ディレクトリやgem名はマスクしています)

$ bin/setup

bundle install
+ bundle install
You have one or more invalid gemspecs that need to be fixed.
The gemspec at /your/gem/src/location is not valid. Please fix this gemspec.
The validation error was 'your_gem-x.y.z contains itself (your_gem-x.y.z.gem), check your files list'

下から2行目のエラーメッセージは、gemを作ったことのある人ならよく見ることになる(?)、gemspecファイルにエラーがあるときに出るメッセージですね。
そして、一番下のメッセージは自分自身のgemパッケージがファイルリストに含まれてるよ〜と言っています。

gemspecファイルを見てみる

gemspecには、gemをパッケージングするときにどのファイルを含めるか、定義する部分があります。bundle gemコマンドで雛形を作った場合は、以下のようになっています。

  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }

つまり、含めるファイルはgit ls-filesコマンドを使って調べるわけですね。

bundlerのgemの雛形を使う限りは、.gemファイルはpkgディレクトリの中に生成されて、それは.gitignoreで除外されていまるので、今回問題となったようなエラーは起きないようになっています。

エラーの原因: pkg以外に.gemがコミットされていた

これでエラーが起きる原因がわかってきました。cloneしてきたディレクトリをみてみると確かに.gemが入っていることがわかったので、これを消せばいいとわかります。

最後に1点。前述の通り、gemspecの中では、git ls-filesコマンドを使ってファイルをリストアップします。そのため、rmコマンドなどでファイルを消すだけでなく、git rm等でgitの管理下からも外してあげないといけません。

まとめ

知ってる人が慣れた手順でやる分には、このような問題が起きることがないような仕組みになっています。(rubygems & bundler ありがとうございます!)

一方で、何かの手違いだったり、gemを作る練習の過程でこのような問題が起きることがあるかもしれないので、見慣れないエラーメッセージを見たときに、この記事のことを思い出していただければと思います。