背景
最近gemを作成していたが、その際にハマった点・やらかした点を整理して、備忘録として残しておく。
前提
gitを使ってgemを開発していること。
bundle gemでgemの雛形を作成していること。
build時の注意点
buildする前にgit addする
gem作成途中に動作確認をしようと思ってbuildしてinstallしたが、上手く動作しないことがあった。
unpackして中身を確認したところ、以下の状況。
- 既存のファイルの変更分は反映されている
- 新規作成したファイルが含まれていない
調べてみるとgit add していないことが原因だった。
なぜgit addしないとbuildされたgemに新規作成したファイルが含まれないのか?
bundle gemで作成したgemの雛形のgemspecにはspec.filesの指定がある。
Gem::Specification.new do |spec|
# ... 省略 ...
spec.files = `git ls-files`.split($/)
end
spec.filesはgemに含めるファイルを指定するもので、git ls-filesを使って指定している。
git ls-filesはgitのインデックスに登録されているファイル群を表示するコマンド。
gitのインデックスにはgit addすることで初めて登録される。
ようは、新規ファイルはaddしないとbuild対象にならないよ、ってことだった。
rake buildする前に同一バージョンのgemファイルがないか確認する
rake buildでpkg下にgemを作成した場合、既にファイルがある場合は上書きされない。
メッセージ上ではgemを新たに作ったように見えるので注意。
$ ls pkg/
mygem-0.0.1.gem
$ rake build
mygem 0.0.1 built to pkg/mygem-0.0.1.gem.
push時の注意点
buildしたgemを確認してからpushする
build時の注意に記載したように、開発中にgemを作ってpkg下に配置したままだった場合、
rake releaseすると、既存のgemは上書きされず、開発中のgemがpushされてしまう。
個人的には以下の手順でpush(rake release)している。
- pkg下の該当バージョンのgemがあれば削除
- rake release前にrake build -> gem unpackで中身を確認 -> OKならgem削除
- rake release
rubygems.orgに登録したgemは同一バージョンで差し替えできない
rubygems.orgの仕様。
同一バージョンのgemはpushできない (差し替えできない)
$ gem push pkg/mygem-0.0.1.gem
Pushing gem to https://rubygems.org...
Repushing of gem versions is not allowed.
Please use `gem yank` to remove bad gem releases.
$ rake release
mygem 0.0.1 built to pkg/mygem-0.0.9.gem.
Tag v0.0.1 has already been created.
rake aborted!
Pushing gem to https://rubygems.org...
Repushing of gem versions is not allowed.
Please use `gem yank` to remove bad gem releases.
...
前述のように開発中のgemを誤ってpushした場合等は、該当バージョンを公開停止して、次のバージョンをpushするしかなくなる。
gemの公開停止は後述。
gemを公開停止する
rubygems.orgに登録したとあるバージョンのgemを公開停止する
gemの公開停止にはgem yankコマンドを使う。
yankコマンドがない場合はgemcutterをインストールして使う。
間違ったバージョンを消さないように注意する。
## yankコマンドがない場合
$ gem yank mygem -v 0.0.1
ERROR: While executing gem ... (RuntimeError)
Unknown command yank
$ gem install gemcutter
$ gem yank mygem -v 0.0.1