これは pepabo Advent Calendar 2016 - Qiita 8日目の記事です。
docker環境で動かしているredashをマイグレーションする話を書こうと思っていたら、一緒にやった人に先に書かれてしまうというアクシデントがおこり、どうしようと思いながらこんな時間になってしまいました。
今回の記事の内容は、gem開発の流儀ややり方を知ってる人はほとんどハマることはない問題です。それ故にあまり情報がないので、アドベントカレンダーのネタにすることにしました。
社内向けのgemをインストールしようとして失敗した
ペパボでは、社内向けのcliツールをgemとして開発し、GitHub Enterpriseから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を作る練習の過程でこのような問題が起きることがあるかもしれないので、見慣れないエラーメッセージを見たときに、この記事のことを思い出していただければと思います。