Gemを作って、自動テストを回して、公開してみる方法


rubyでstable_sortをできるようにするgemを作ったので、作った課程のメモ。
Gemを公開し、Rspecでテストを書いてTravis CIで回すところまでやっている。

## 実際に出来たもの

- https://github.com/awakia/ruby_stable_sort
- http://rubygems.org/gems/stable_sort


## gemのテンプレートを生成

`bundle gem`コマンドを使う。

```bash
% bundle gem stable_sort -t                   
      create  stable_sort/Gemfile
      create  stable_sort/Rakefile
      create  stable_sort/LICENSE.txt
      create  stable_sort/README.md
      create  stable_sort/.gitignore
      create  stable_sort/stable_sort.gemspec
      create  stable_sort/lib/stable_sort.rb
      create  stable_sort/lib/stable_sort/version.rb
      create  stable_sort/.rspec
      create  stable_sort/spec/spec_helper.rb
      create  stable_sort/spec/stable_sort_spec.rb
      create  stable_sort/.travis.yml
Initializating git repo in /Users/aikawa/work/stable_sort
```

`-t`オプションでRSpecのテストも生成してくれる。

## 中身を作る

StableSortの場合ArrayやEnemeratorにモンキーパッチするだけなのでモジュールの中身は空で良い。

https://github.com/awakia/ruby_stable_sort/blob/master/lib/stable_sort.rb

```ruby:lib/stable_sort.rb
require "stable_sort/version"
require "stable_sort/extension/enumerator"
require "stable_sort/extension/array"

module StableSort
end
```

例えばEnemeratorクラスの中身はこんな感じ。

```stable_sort/extension/enumerator.rb
class Enumerator
  def stable_sort_by
    sort_by.with_index{ |e, index| [yield(e), index] }
  end

  def stable_sort
    stable_sort_by { |x| x }
  end
end
```

## .gemファイルを作る

```bash
% gem build stable_sort.gemspec
  Successfully built RubyGem
  Name: stable_sort
  Version: 0.0.1
  File: stable_sort-0.0.1.gem
```

## stable_sort gemの公開

```bash
% gem push stable_sort-0.0.1.gem 
Pushing gem to https://rubygems.org...
Successfully registered gem: stable_sort (0.0.1)
```

`stable_sort`とか言う名前取れないかと思ったらまさかとれてしまったw

http://rubygems.org/gems/stable_sort

## テストを書く

デフォルトで1つFailするテストが作られているので、とりえあず`bundle exec rspec`で動かしてみる。

Failしてることを確認したら、それを消して後は適当にテストを書く。
https://github.com/awakia/ruby_stable_sort/commit/6c276352ef7ef9b1b6f55d85fb1d2d1223e7d374

## Travis CIで動かす

https://travis-ci.org/ にてGithubアカウントでログイン。

プロフィールページに行って (https://travis-ci.org/profile) 連携をON

![travis_on.png](https://qiita-image-store.s3.amazonaws.com/0/6664/cb738c6d-6e0f-f6bd-64be-0c9b6d021de8.png "travis_on.png")


## テスト結果をREADMEに表示

ドキュメント: http://about.travis-ci.org/docs/user/status-images/

マークダウンで言えば、以下のものを書けばいいみたい。

```README.md
[![Build Status](https://travis-ci.org/[YOUR_GITHUB_USERNAME]/[YOUR_PROJECT_NAME].png)](https://travis-ci.org/[YOUR_GITHUB_USERNAME]/[YOUR_PROJECT_NAME])
```

こんな感じ -> [![Build Status](https://travis-ci.org/awakia/ruby_stable_sort.png)](https://travis-ci.org/awakia/ruby_stable_sort)


## テストカバレッジも出してみる

[COVERALLS](https://coveralls.io)を使う。

gemspecのdevelopment dependencyにcoverallsを追加。

```ruby:stable_sort.gemspec
  spec.add_development_dependency "coveralls"
```

その上で、spec_helperの最初でrequireする。

```ruby:spec_helper.rb
require 'coveralls'
Coveralls.wear!

# ...
```

バッジもつける -> [![Coverage Status](https://coveralls.io/repos/awakia/ruby_stable_sort/badge.png?branch=master)](https://coveralls.io/r/awakia/ruby_stable_sort?branch=master)

```README.md
[![Coverage Status](https://coveralls.io/repos/awakia/ruby_stable_sort/badge.png?branch=master)](https://coveralls.io/r/awakia/ruby_stable_sort?branch=master)
```

## バージョンを上げてみる

`0.0.1`だと使えないGemみたいに見えるので、`1.0.0`に上げてみる。

```ruby:lib/stable_sort/version.rb
module StableSort
  VERSION = "1.0.0"
end
```

あとは

```bash
gem build stable_sort.gemspec
```

して

```bash
gem push stable_sort-1.0.0.gem
```

する。

## リリースにタグを付けておく

ちゃんとしたgemでは、gitでタグを付けておくことにより、Githubのreleasesにそれぞれバージョンがどのコミットまでの部分だったかがわかるようになっている。それに習って自分でもタグを付けておく

まずは古いバージョンのコミット位置で

```bash
git tag v0.0.1 
```

とし、
次に新しいバージョンのコミット位置で

```bash
git tag v1.0.0
```

とする。

```bash
git push origin --tags
```

とすることでリモートのGithubにもタグが反映される。

https://github.com/awakia/ruby_stable_sort/releases

## 参考にした資料

RubyGemsに登録するところの参考文献：

- http://www.ownway.info/Ruby/index.php?bundler%2Fgem

Gemを作って公開するところの参考文献：

- http://ja.asciicasts.com/episodes/245-new-gem-with-bundler


## ちなみに
これは毎週木曜Wantedlyでやっているもくもく会で作りました。
興味がある方は一度[こちら](https://www.wantedly.com/projects/5106)からどうぞ